3.3 实模式代码main函数
前面header.S中最后跳到main函数,在boot/main.c,void main()。再次强调一下,这一段C代码还是系统处于实模式下所执行的代码:
128void main(void) 129{ 130 /* First, copy the boot header into the "zeropage" */ 131 copy_boot_params(); 132 133 /* End of heap check */ 134 init_heap(); 135 136 /* Make sure we have all the proper CPU support */ 137 if (validate_cpu()) { 138 puts("Unable to boot - please use a kernel appropriate " 139 "for your CPU./n"); 140 die(); 141 } 142 143 /* Tell the BIOS what CPU mode we intend to run in. */ 144 set_bios_mode(); 145 146 /* Detect memory layout */ 147 detect_memory(); 148 149 /* Set keyboard repeat rate (why?) */ 150 keyboard_set_repeat(); 151 152 /* Query MCA information */ 153 query_mca(); 154 155 /* Query Intel SpeedStep (IST) information */ 156 query_ist(); 157 158 /* Query APM information */ 159#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE) 160 query_apm_bios(); 161#endif 162 163 /* Query EDD information */ 164#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) 165 query_edd(); 166#endif 167 168 /* Set the video mode */ 169 set_video(); 170 171 /* Parse command line for 'quiet' and pass it to decompressor. */ 172 if (cmdline_find_option_bool("quiet")) 173 boot_params.hdr.loadflags |= QUIET_FLAG; 174 175 /* Do the last things and invoke protected mode */ 176 go_to_protected_mode(); 177} |
这个main函数里面的代码大部分对应ULK3中附录A讲setup函数的那一小节,主要是在实模式下做些前期工作。涉及初始化计算机中的硬件设备,并为内核程序的执行建立环境。虽然前面看到BIOS已经初始化了大部分硬件设备,但是Linux并不依赖于BIOS,而是以自己的方式重新初始化设备以增强可移植性和健壮性。
这里只强调一个事情,接下来大部分工作都是在为进入保护模式而做准备。虽然现在仅仅工作在实模式中,A20 Gate暂时关闭(后面会详谈),程序无法访问内存地址0x100000以后的内容,但并不意味着,0x100000以后就没有东西。所以,grub程序的stage2有个打开和关闭保护模式的过程,即将内核映像从磁拷贝到内存时,必须使用保护模式。拷贝完成后,关闭A20 Gate并且回到实模式下,但并不意味着高于0x100000的内存单元就没有内容了,而是保护起来了,不然怎么叫“保护模式”呢?