There are a few other differences between 2.0 and 2.1.43. They don’t deserve special treatment in my opinion, so I’ll summarize them quickly.
The proc_register_dynamic function disappeared in
2.1.29. Recent kernels use the proc_register interface for every
/proc
file; if the low_ino
field in struct proc_dir_entry
is 0, then a dynamic inode number is assigned. The
header sysdep-2.1.h
defines proc_register_dynamic as
proc_register when compiling for 2.1.29 or newer; this works
as long as the proc_dir_entry
structure being registered
features 0 as the inode number.
In the field of network interface drivers, the rebuild_header
device method has a new prototype from 2.1.15 onwards. You won’t be
concerned with this difference as long as you develop Ethernet
drivers, as Ethernet drivers don’t implement their own method; they fall
back on the general-purpose Ethernet implementation. The
sysdep-2.1
header defines the macro
__USE_OLD_REBUILD_HEADER__
when the old implementation is
needed. The sample module snull shows how to use the macro, but
it’s not worth showing here.
Another change in network code affects struct enet_statistics
, which doesn’t exist any more since 2.1.25.
There is a new
structure, struct net_device_stats
, in its place, which is
declared in <linux/netdevice.h>
instead of
<linux/if_ether.h>
. The new structure is just like the old one,
with the addition of two fields to store byte counters: unsigned long rx_bytes, tx_bytes;
. A full-featured network interface
driver should increment these counters along with rx_packets
and tx_packets
, athough a quick project might disregard the
counters. The kernel headers define enet_statistics
(the name
of the old structure) to net_device_stats
(the name of the new
structure) to ease portability of existing drivers.
As a final note, I’d like to point out that the current
pointer is no longer a global variable; the x86, Alpha, and Sparc
kernel ports use smart tricks to store current
in the
processor itself. The kernel developers thus managed to squeeze out a few
CPU cycles more. This trick avoids a lot of memory references, and
sometimes frees a general-purpose register; the compiler often
allocates processor registers to cache a few frequently used memory
locations, and current
is frequently used. Different tricks
are used in the different ports to optimize access. The Alpha and Sparc
versions use a processor register (one not used by the compiler’s
optimization) to store current
. The Intel processor, on the
other hand, has a limited number of registers, and the compiler uses
all of them; the trick in this case consists in storing struct task_struct
and the kernel stack page in consecutive virtual-memory
pages. This allows the current
pointer to be ``encoded'' in the
stack pointer. For every platform supported by Linux the header,
<asm/current.h>
shows the actual implementation chosen.
Like any vital piece of software, Linux continues to change. If you want to write drivers for the latest and greatest kernel, you’ll need to keep up to date with kernel development. Although dealing with incompatibilities might look like hard work, two observations are due. First, the major programming techniques are in place and are unlikely to change (at least not often). Second, each change makes things better, and usually leaves you less work to do on future development.
18.189.22.136