Understanding skull module in Linux Device Driver Book

Submitted by dinesha7
on October 2, 2004 - 3:33am

I [being a chemical enginner and new to Kernel world ] am having problem in understanding a sample code [skull] available with Book Linux device driver By Alessandro Rubini. Could anyone guide me about this ?

mb(); [ What mb do ?. Is documentation present for these functions? mb seems to move byte ]

I got the programming aspect for this but did not get the logic of it. Please give me a concept of below line.

if ((oldval^newval) == 0xff) { /* we re-read our change: it's ram */
printk(KERN_INFO "%lx: RAM\n", add);
continue;
}

if ((oldval^newval) != 0) { /* random bits changed: it's empty */
printk(KERN_INFO "%lx: empty\n", add);
continue;
}

Please explain the below lines and what is the significance of Expansion ROM.

if ( (oldval == 0x55) && (readb (base + add + 1) == 0xaa)) {
int size = 512 * readb (base + add + 2);
printk(KERN_INFO "%lx: Expansion ROM, %i bytes\n",
add, size);
add += (size & ~2048) - 2048; /* skip it */
continue;
}

printk(KERN_INFO "%lx: ", add);
for (i=0; i<5; i++) {
unsigned long radd = add + 57*(i+1); /* a "random" value */
unsigned char val = readb (base + radd);
if (val && val != 0xFF && val != ((unsigned long) radd&0xFF))
break;
}
printk("%s\n", i==5 ? "empty" : "ROM");

Thanks & Regards
Dinesh

mb() - memory barrier

Anonymous
on
October 2, 2004 - 7:29am

mb() stands for memory barrier. IIRC the mb() macro is just an instruction to the compiler to limit reordering of memory accesses.

Compilers might reorder memory accesses to improve performance but it's guaranteed that all memory accesses before the mb() in your code will really occur before all memory accesses after the mb(), regardless of this reordering.

There are also macros {smp_}rmb() and {smp_}wmb() which protect against reordering of memory reads and writes by the hardware itself.

It can help to wrap a wet towel around your head before thinking about memory barriers - prevents overheating your brain ;-)

tips

strcmp
on
October 2, 2004 - 9:40am

As a general rule: if you don't know a function a program calls, and which might be defined by the program, grep the sources, or at least the include files. In most cases it is documented somewhere. This is especially true for completely self-contained programs like operating system kernels.

In this case, find Documentation include | xargs grep 'mb()' gives you plenty of documentation and implementations.

The difference between RAM and ROM and the ^ operator of C are really simple, just think about it some more seconds; read the excellent comments, if that doesn't help. The expansion ROM stuff is only interesting for you, if you want to write new operation systems, which have to boot on old pre-PCI PCs. Read an old 80ies 'PC Inside' book for this.

And why do you even want to understand what you call "the logic of it", i.e. the specific hardware? You want to learn how to write drivers, and not recite this specific driver by heart. It could as well be nonsense-code, the authors maybe only chose this example, because the expect some of their readers to be seasoned DOS hackers or so, who will find this code familiar.

More people will answer your questions, if they are less imperative.

Please explain !

dinesha7
on
October 2, 2004 - 10:54am

Thanks to all for replying. I am not interested in mugging up the code and that's why I am interested in knowing the following things

1. Why the writer has mentioned that if (oldval^newval) == 0xff), then it is RAM.

2. And why (oldval^newval) != 0) corresponds to random bits changed,it's empty

I am familiar with the Bitwise operations in C. I hope that I can skip ROM part at this point.

Regards
Dinesh

I think the trick was to stor

Ano Nymous
on
October 2, 2004 - 2:21pm

I think the trick was to store the current value, edit the memory, and then compare it with the stored value. If it's RAM then it's writable, if it's ROM then it isn't, and the now current value will be the same as the stored one.

It's like

/* test if b is on ROM: */
a = b;
b = c;
if (b == a)
b didn't change -> ROM
else { /* b == c */
b changed -> RAM
/* restore b */
b = a;
}

oldval^newval != 0 seems to be exactly the same as oldval != newval, no idea why they use the bit operator.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.