Linux源码与编译出的目标文件汇编代码的一致性问题
start_kernel是内核启动时比较重要的一个函数,然而我发现一个问题,我编译出来的目标文件中的汇编代码与C源码并不完全对应,这是怎么一回事呢?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | asmlinkage void __init start_kernel( void ) { char * command_line; extern const struct kernel_param __start___param[], __stop___param[]; /* * Need to run as early as possible, to initialize the * lockdep hash: */ lockdep_init(); smp_setup_processor_id(); debug_objects_early_init(); /* * Set up the the initial canary ASAP: */ boot_init_stack_canary(); cgroup_init_early(); local_irq_disable(); early_boot_irqs_disabled = true ;<br> /*<br> * Interrupts are still disabled. Do necessary setups, then<br> * enable them<br> */ <br> boot_cpu_init();<br> page_address_init();<br> pr_notice( "%s" , linux_banner);<br> setup_arch(&command_line);<br> mm_init_owner(&init_mm, &init_task);<br> mm_init_cpumask(&init_mm);<br> setup_command_line(command_line);<br> setup_nr_cpu_ids();<br> setup_per_cpu_areas();<br> smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */ |
1 | objdump -d main.o |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 00000337 <start_kernel>: 337: 55 push %ebp 338: 89 e5 mov %esp,%ebp 33a: 53 push %ebx 33b: 83 ec 14 sub $0x14,%esp 33e: e8 fc ff ff ff call 33f <start_kernel+0x8> 343: e8 fc ff ff ff call 344 <start_kernel+0xd> 348: ff 15 08 00 00 00 call *0x8 34e: 64 8b 1d 00 00 00 00 mov %fs:0x0,%ebx 355: ba 01 00 00 00 mov $0x1,%edx 35a: 89 d8 mov %ebx,%eax 35c: c6 05 00 00 00 00 01 movb $0x1,0x0 363: e8 fc ff ff ff call 364 <start_kernel+0x2d> 368: 89 d8 mov %ebx,%eax 36a: ba 01 00 00 00 mov $0x1,%edx 36f: e8 fc ff ff ff call 370 <start_kernel+0x39> 374: 89 d8 mov %ebx,%eax 376: ba 01 00 00 00 mov $0x1,%edx 37b: e8 fc ff ff ff call 37c <start_kernel+0x45> 380: ba 01 00 00 00 mov $0x1,%edx 385: 89 d8 mov %ebx,%eax 387: e8 fc ff ff ff call 388 <start_kernel+0x51> 38c: e8 fc ff ff ff call 38d <start_kernel+0x56> 391: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) |
1 | objdump -r main.o |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 00000309 R_386_32 boot_command_line 0000030e R_386_32 .init.data 00000313 R_386_PC32 strlcpy 00000318 R_386_32 .init.data 0000031d R_386_PC32 parse_early_options 00000324 R_386_32 .init.data 0000033f R_386_PC32 smp_setup_processor_id 00000344 R_386_PC32 cgroup_init_early 0000034a R_386_32 pv_irq_ops 00000351 R_386_32 cpu_number 0000035e R_386_32 early_boot_irqs_disabled 00000364 R_386_PC32 set_cpu_online 00000370 R_386_PC32 set_cpu_active 0000037c R_386_PC32 set_cpu_present 00000388 R_386_PC32 set_cpu_possible 0000038d R_386_PC32 page_address_init 00000395 R_386_32 linux_banner 0000039c R_386_32 .rodata.str1.1 000003a1 R_386_PC32 printk 000003a9 R_386_PC32 setup_arch 000003ae R_386_32 init_task 000003b3 R_386_32 init_mm 000003b8 R_386_PC32 mm_init_owner 000003bd R_386_32 boot_command_line |
那么,lockdep_init函数哪里去了呢,start_kernel究竟有没有调用到它呢。
首先可以肯定的是,lockdep_init没有被内核导出,因为在System.map中找不到它。
然后,在重定位信息中也找不到lockdep_init。
lockdep_init是在哪个文件中定义的?
1 | kernel/locking/lockdep.c |
但是在kernel/locking目录下并没有生成lockdep.o,这又是为什么?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | void lockdep_init( void ) { int i; /* * Some architectures have their own start_kernel() * code which calls lockdep_init(), while we also * call lockdep_init() from the start_kernel() itself, * and we want to initialize the hashes only once: */ if (lockdep_initialized) return ; for (i = 0; i < CLASSHASH_SIZE; i++) INIT_LIST_HEAD(classhash_table + i); for (i = 0; i < CHAINHASH_SIZE; i++) INIT_LIST_HEAD(chainhash_table + i); lockdep_initialized = 1; } |
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步