这是内核初始化至此,终于跑出arch/x86目录了,它在linux/init/main.c,以后的代码除了少数特例,其余的都在linux/init/目录中。
528asmlinkage void __init start_kernel(void) 529{ 530 char * command_line; 531 extern struct kernel_param __start___param[], __stop___param[]; 532 533 smp_setup_processor_id(); 534 535 /* 536 * Need to run as early as possible, to initialize the 537 * lockdep hash: 538 */ 539 lockdep_init(); 540 debug_objects_early_init(); 541 542 /* 543 * Set up the the initial canary ASAP: 544 */ 545 boot_init_stack_canary(); 546 547 cgroup_init_early(); 548 549 local_irq_disable(); 550 early_boot_irqs_off(); 551 early_init_irq_lock_class(); 552 553/* 554 * Interrupts are still disabled. Do necessary setups, then 555 * enable them 556 */ 557 lock_kernel(); 558 tick_init(); 559 boot_cpu_init(); 560 page_address_init(); 561 printk(KERN_NOTICE "%s", linux_banner); 562 setup_arch(&command_line); 563 mm_init_owner(&init_mm, &init_task); 564 setup_command_line(command_line); 565 setup_nr_cpu_ids(); 566 setup_per_cpu_areas(); 567 smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */ 568 569 build_all_zonelists(); 570 page_alloc_init(); 571 572 printk(KERN_NOTICE "Kernel command line: %s/n", boot_command_line); 573 parse_early_param(); 574 parse_args("Booting kernel", static_command_line, __start___param, 575 __stop___param - __start___param, 576 &unknown_bootoption); 577 /* 578 * These use large bootmem allocations and must precede 579 * kmem_cache_init() 580 */ 581 pidhash_init(); 582 vfs_caches_init_early(); 583 sort_main_extable(); 584 trap_init(); 585 mm_init(); 586 /* 587 * Set up the scheduler prior starting any interrupts (such as the 588 * timer interrupt). Full topology setup happens at smp_init() 589 * time - but meanwhile we still have a functioning scheduler. 590 */ 591 sched_init(); 592 /* 593 * Disable preemption - early bootup scheduling is extremely 594 * fragile until we cpu_idle() for the first time. 595 */ 596 preempt_disable(); 597 if (!irqs_disabled()) { 598 printk(KERN_WARNING "start_kernel(): bug: interrupts were " 599 "enabled *very* early, fixing it/n"); 600 local_irq_disable(); 601 } 602 rcu_init(); 603 radix_tree_init(); 604 /* init some links before init_ISA_irqs() */ 605 early_irq_init(); 606 init_IRQ(); 607 prio_tree_init(); 608 init_timers(); 609 hrtimers_init(); 610 softirq_init(); 611 timekeeping_init(); 612 time_init(); 613 profile_init(); 614 if (!irqs_disabled()) 615 printk(KERN_CRIT "start_kernel(): bug: interrupts were " 616 "enabled early/n"); 617 early_boot_irqs_on(); 618 local_irq_enable(); 619 620 /* Interrupts are enabled now so all GFP allocations are safe. */ 621 gfp_allowed_mask = __GFP_BITS_MASK; 622 623 kmem_cache_init_late(); 624 625 /* 626 * HACK ALERT! This is early. We're enabling the console before 627 * we've done PCI setups etc, and console_init() must be aware of 628 * this. But we do want output early, in case something goes wrong. 629 */ 630 console_init(); 631 if (panic_later) 632 panic(panic_later, panic_param); 633 634 lockdep_info(); 635 636 /* 637 * Need to run this when irqs are enabled, because it wants 638 * to self-test [hard/soft]-irqs on/off lock inversion bugs 639 * too: 640 */ 641 locking_selftest(); 642 643#ifdef CONFIG_BLK_DEV_INITRD 644 if (initrd_start && !initrd_below_start_ok && 645 page_to_pfn(virt_to_page((void *)initrd_start)) < min_low_pfn) { 646 printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - " 647 "disabling it./n", 648 page_to_pfn(virt_to_page((void *)initrd_start)), 649 min_low_pfn); 650 initrd_start = 0; 651 } 652#endif 653 page_cgroup_init(); 654 enable_debug_pagealloc(); 655 kmemtrace_init(); 656 kmemleak_init(); 657 debug_objects_mem_init(); 658 idr_init_cache(); 659 setup_per_cpu_pageset(); 660 numa_policy_init(); 661 if (late_time_init) 662 late_time_init(); 663 sched_clock_init(); 664 calibrate_delay(); 665 pidmap_init(); 666 anon_vma_init(); 667#ifdef CONFIG_X86 668 if (efi_enabled) 669 efi_enter_virtual_mode(); 670#endif 671 thread_info_cache_init(); 672 cred_init(); 673 fork_init(totalram_pages); 674 proc_caches_init(); 675 buffer_init(); 676 key_init(); 677 security_init(); 678 vfs_caches_init(totalram_pages); 679 signals_init(); 680 /* rootfs populating might need page-writeback */ 681 page_writeback_init(); 682#ifdef CONFIG_PROC_FS 683 proc_root_init(); 684#endif 685 cgroup_init(); 686 cpuset_init(); 687 taskstats_init_early(); 688 delayacct_init(); 689 690 check_bugs(); 691 692 acpi_early_init(); /* before LAPIC and SMP init */ 693 sfi_init_late(); 694 695 ftrace_init(); 696 697 /* Do the rest non-__init'ed, we're now alive */ 698 rest_init(); 699} |
首先,533行,执行smp_setup_processor_id()函数。对于我们x86体系,这个函数是个空函数。继续走,539行,调用lockdep_init()函数,这个函数来自kernel/Lockdep.c: