On Fri, Aug 27, 2010 at 10:53 PM, James Bond <jamesbond.2k.g@xxxxxxxxx> wrote: > > > > Hi, > I am new to kernel development. > So after being able to have some basic understand of some things I just went > through source code. > I was going through a file known as > linux-2.6.34/kernel/timer.c and found following code. > I want to understand what is it doing. > What should I be reading to be able to understand it? > > static inline void > timer_set_base(struct timer_list *timer, struct tvec_base *new_base) > { > timer->base = (struct tvec_base *)((unsigned long)(new_base) | > tbase_get_deferrable(timer->base)); > } > What static does is to create a label for a certain global memory chunk and give that a value at compile time, plus not making it available to the linker. Look at these examples static int mystatic = 6; int main(void) { return 0; } Generated ASM is as follows: Code: .file "static2.c" .data .align 4 .type mystatic, @object .size mystatic, 4 mystatic: .long 6 .text .globl main .type main, @function main: pushl %ebp movl %esp, %ebp movl $0, %eax popl %ebp ret .size main, .-main .ident "GCC: (Debian 4.4.4-8) 4.4.5 20100728 (prerelease)" .section .note.GNU-stack,"",@progbits Compare that with declaring the global variable as non-static: Code: int mynonstatic = 6; int main(void) { return 0; } Code: .file "nonstatic2.c" .globl mynonstatic .data .align 4 .type mynonstatic, @object .size mynonstatic, 4 mynonstatic: .long 6 .text .globl main .type main, @function main: pushl %ebp movl %esp, %ebp movl $0, %eax popl %ebp ret .size main, .-main .ident "GCC: (Debian 4.4.4-8) 4.4.5 20100728 (prerelease)" .section .note.GNU-stack,"",@progbits The only difference is that in the non-static case, there's the .globl mynonstatic that makes that symbol available to the linker. Now, careful observation will make you notice that both global variables are declared as labels, exactly the same way as main is. ASM doesn't really distinguish between functions and variables (the @function and @object thing is just an optimization gcc does): all there is memory addresses that you conveniently can refer to with a label. So, when you declare a function static, what will happen is exactly the same: the function is given a value (its code) and make it unavailable to the linker... exactly what was done to the variable. Here you have the C and ASM for a static function: Code: .file "stat_func.c" .text .type something, @function something: pushl %ebp movl %esp, %ebp movl $0, %eax popl %ebp ret .size something, .-something .ident "GCC: (Debian 4.4.4-8) 4.4.5 20100728 (prerelease)" .section .note.GNU-stack,"",@progbits Again, the value for something is its code, it's a global value but not available to the linker because there's no .globl something. What about local static variables? Actually, the idea of local variables is lost when compiling C to ASM. What you have is a global stack that each function is in charge to clean up when returning... therefore making its local values no longer available outside the function... but place a jmp and the value will be available. What happens with static variables is that the static again sets up a value at compile time and makes the symbol unavailable for the linker... as you'll see here: Code: int main(void) { static int mystatic = 6; return 0; } Code: .file "static.c" .text .globl main .type main, @function main: pushl %ebp movl %esp, %ebp movl $0, %eax popl %ebp ret .size main, .-main .data .align 4 .type mystatic.1248, @object .size mystatic.1248, 4 mystatic.1248: .long 6 .ident "GCC: (Debian 4.4.4-8) 4.4.5 20100728 (prerelease)" .section .note.GNU-stack,"",@progbits The only difference here is that the .data section has been placed *after* the main "rets" (a kind of return you have in ASM...)... ASM indentation is awful here, but actually main ends at the ret, not at the mystatic.1248 label. Ok, I'm not sure why the name is "mangled" but it's clear that the variable is declared as global even when we declared it as local in C. What will happen is that the C compiler will restrict the usage of that symbol to the main function, but you clearly see that it's just a way to create the illusion of locality... It's actually a global and that's why its value is persistent across the program's execution. So, in summary, it seems that the real effective meaning (I don't care what the standard says) of static is "Make a global memory address not be available to the linker"... therefore we can explain why is it used both for functions and variables. Of course, tutorials are doing fine to explain this the way they do... As you see, you have to step down to ASM in order to make some sense of this. Also, this is another great reason of why C is such a pain to use: in the end you still have to understand the basics of ASM... while to use bash, Perl, Python you don't need to know C (or the language the implementation is written in). -- To unsubscribe from this list: send an email with "unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx Please read the FAQ at http://kernelnewbies.org/FAQ