回到start_kernel当中,562行,调用setup_arch函数,传给他的参数是那个未被初始化的内部变量command_line。这个setup_arch()函数是start_kernel阶段最重要的一个函数,每个体系都有自己的setup_arch()函数,是体系结构相关的,具体编译哪个体系的setup_arch()函数,由顶层Makefile中的ARCH变量决定:
724void __init setup_arch(char **cmdline_p) 725{ 726 int acpi = 0; 727 int k8 = 0; 728 …… 730 memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); 731 visws_early_detect(); …… 736 /* VMI may relocate the fixmap; do this before touching ioremap area */ 737 vmi_init(); 738 739 early_cpu_init(); 740 early_ioremap_init(); 741 742 ROOT_DEV = old_decode_dev(boot_params.hdr.root_dev); 743 screen_info = boot_params.screen_info; 744 edid_info = boot_params.edid_info; …… 746 apm_info.bios = boot_params.apm_bios_info; 747 ist_info = boot_params.ist_info; 748 if (boot_params.sys_desc_table.length != 0) { 749 set_mca_bus(boot_params.sys_desc_table.table[3] & 0x2); 750 machine_id = boot_params.sys_desc_table.table[0]; 751 machine_submodel_id = boot_params.sys_desc_table.table[1]; 752 BIOS_revision = boot_params.sys_desc_table.table[2]; 753 } …… 755 saved_video_mode = boot_params.hdr.vid_mode; 756 bootloader_type = boot_params.hdr.type_of_loader; 757 if ((bootloader_type >> 4) == 0xe) { 758 bootloader_type &= 0xf; 759 bootloader_type |= (boot_params.hdr.ext_loader_type+0x10) << 4; 760 } 761 bootloader_version = bootloader_type & 0xf; 762 bootloader_version |= boot_params.hdr.ext_loader_ver << 4; …… 782 x86_init.oem.arch_setup(); 783 784 setup_memory_map(); 785 parse_setup_data(); 786 /* update the e820_saved too */ 787 e820_reserve_setup_data(); 788 789 copy_edd(); 790 791 if (!boot_params.hdr.root_flags) 792 root_mountflags &= ~MS_RDONLY; 793 init_mm.start_code = (unsigned long) _text; 794 init_mm.end_code = (unsigned long) _etext; 795 init_mm.end_data = (unsigned long) _edata; 796 init_mm.brk = _brk_end; 797 798 code_resource.start = virt_to_phys(_text); 799 code_resource.end = virt_to_phys(_etext)-1; 800 data_resource.start = virt_to_phys(_etext); 801 data_resource.end = virt_to_phys(_edata)-1; 802 bss_resource.start = virt_to_phys(&__bss_start); 803 bss_resource.end = virt_to_phys(&__bss_stop)-1; …… 817 818 strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); 819 *cmdline_p = command_line; …… 828 x86_configure_nx(); 829 830 parse_early_param(); 831 832 x86_report_nx(); 833 834 /* Must be before kernel pagetables are setup */ 835 vmi_activate(); 836 837 /* after early param, so could get panic from serial */ 838 reserve_early_setup_data(); 839 840 if (acpi_mps_check()) { 841#ifdef CONFIG_X86_LOCAL_APIC 842 disable_apic = 1; 843#endif 844 setup_clear_cpu_cap(X86_FEATURE_APIC); 845 } 846 847#ifdef CONFIG_PCI 848 if (pci_early_dump_regs) 849 early_dump_pci_devices(); 850#endif 851 852 finish_e820_parsing(); 853 854 if (efi_enabled) 855 efi_init(); 856 857 dmi_scan_machine(); 858 859 dmi_check_system(bad_bios_dmi_table); 860 …… 865 init_hypervisor_platform(); 866 867 x86_init.resources.probe_roms(); 868 869 /* after parse_early_param, so could debug it */ 870 insert_resource(&iomem_resource, &code_resource); 871 insert_resource(&iomem_resource, &data_resource); 872 insert_resource(&iomem_resource, &bss_resource); 873 874 trim_bios_range(); …… 891 max_pfn = e820_end_of_ram_pfn(); 892 893 /* preallocate 4k for mptable mpc */ 894 early_reserve_e820_mpc_new(); 895 /* update e820 for memory not covered by WB MTRRs */ 896 mtrr_bp_init(); 897 if (mtrr_trim_uncached_memory(max_pfn)) 898 max_pfn = e820_end_of_ram_pfn(); 899 …… 901 /* max_low_pfn get updated here */ 902 find_low_pfn_range(); …… 923 printk(KERN_DEBUG "initial memory mapped : 0 - %08lx/n", 924 max_pfn_mapped<<PAGE_SHIFT); 925 926 reserve_brk(); 927 928 /* 929 * Find and reserve possible boot-time SMP configuration: 930 */ 931 find_smp_config(); 932 933 reserve_ibft_region(); 934 935 reserve_trampoline_memory(); …… 944 init_gbpages(); 945 946 /* max_pfn_mapped is updated here */ 947 max_low_pfn_mapped = init_memory_mapping(0, max_low_pfn<<PAGE_SHIFT); 948 max_pfn_mapped = max_low_pfn_mapped; 949 …… 968 reserve_initrd(); 969 970 reserve_crashkernel(); 971 972 vsmp_init(); 973 974 io_delay_init(); 975 976 /* 977 * Parse the ACPI tables for possible boot-time SMP configuration. 978 */ 979 acpi_boot_table_init(); 980 981 early_acpi_boot_init(); 982 983#ifdef CONFIG_ACPI_NUMA 984 /* 985 * Parse SRAT to discover nodes. 986 */ 987 acpi = acpi_numa_init(); 988#endif 989 990#ifdef CONFIG_K8_NUMA 991 if (!acpi) 992 k8 = !k8_numa_init(0, max_pfn); 993#endif 994 995 initmem_init(0, max_pfn, acpi, k8); 996#ifndef CONFIG_NO_BOOTMEM 997 early_res_to_bootmem(0, max_low_pfn<<PAGE_SHIFT); 998#endif 999 1000 dma32_reserve_bootmem(); …… 1005 1006 x86_init.paging.pagetable_setup_start(swapper_pg_dir); 1007 paging_init(); 1008 x86_init.paging.pagetable_setup_done(swapper_pg_dir); 1009 1010 tboot_probe(); 1011 …… 1016 generic_apic_probe(); 1017 1018 early_quirks(); 1019 1020 /* 1021 * Read APIC and some other early information from ACPI tables. 1022 */ 1023 acpi_boot_init(); 1024 1025 sfi_init(); 1026 1027 /* 1028 * get boot-time SMP configuration: 1029 */ 1030 if (smp_found_config) 1031 get_smp_config(); 1032 1033 prefill_possible_map(); 1034 …… 1038 1039 init_apic_mappings(); 1040 ioapic_init_mappings(); 1041 1042 /* need to wait for io_apic is mapped */ 1043 probe_nr_irqs_gsi(); 1044 1045 kvm_guest_init(); 1046 1047 e820_reserve_resources(); 1048 e820_mark_nosave_regions(max_low_pfn); 1049 1050 x86_init.resources.reserve_resources(); 1051 1052 e820_setup_gap(); 1053 1054#ifdef CONFIG_VT 1055#if defined(CONFIG_VGA_CONSOLE) 1056 if (!efi_enabled || (efi_mem_type(0xa0000) != EFI_CONVENTIONAL_MEMORY)) 1057 conswitchp = &vga_con; 1058#elif defined(CONFIG_DUMMY_CONSOLE) 1059 conswitchp = &dummy_con; 1060#endif 1061#endif 1062 x86_init.oem.banner(); 1063 1064 mcheck_init(); 1065} |
浩浩荡荡300多行代码,我们去掉了其中64位x86体系的相关代码,以及一些未配置的编译选项,如CONFIG_EFI、CONFIG_CMDLINE_BOOL、CONFIG_ACPI_SLEEP等的相关代码,剩余对我们有用的代码如上所示,也有将近200行。我们这里只挑几个重要的来讲解一下,主要涉及初始化阶段的内存分配器的安装。