列表 上一篇 下一篇

linux+v2.6.24/arch/x86/boot/main.c

<ol class="linenums"><li class="L0"><span class="kwd">void</span><span class="pln"> main</span><span class="pun">(</span><span class="kwd">void</span><span class="pun">)</span></li><li class="L1"><span class="pun">{</span></li><li class="L2"><span class="pln"> </span><span class="com">/* First, copy the boot header into the "zeropage" */</span></li><li class="L3"><span class="pln"> copy_boot_params</span><span class="pun">();</span></li><li class="L4"><span class="pln">&nbsp;</span></li><li class="L5"><span class="pln"> </span><span class="com">/* End of heap check */</span></li><li class="L6"><span class="pln"> </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">boot_params</span><span class="pun">.</span><span class="pln">hdr</span><span class="pun">.</span><span class="pln">loadflags </span><span class="pun">&amp;</span><span class="pln"> CAN_USE_HEAP</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span></li><li class="L7"><span class="pln"> heap_end </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">char</span><span class="pln"> </span><span class="pun">*)(</span><span class="pln">boot_params</span><span class="pun">.</span><span class="pln">hdr</span><span class="pun">.</span><span class="pln">heap_end_ptr</span></li><li class="L8"><span class="pln"> </span><span class="pun">+</span><span class="lit">0x200</span><span class="pun">-</span><span class="pln">STACK_SIZE</span><span class="pun">);</span></li><li class="L9"><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">else</span><span class="pln"> </span><span class="pun">{</span></li><li class="L0"><span class="pln"> </span><span class="com">/* Boot protocol 2.00 only, no heap available */</span></li><li class="L1"><span class="pln"> puts</span><span class="pun">(</span><span class="str">"WARNING: Ancient bootloader, some functionality "</span></li><li class="L2"><span class="pln"> </span><span class="str">"may be limited!\n"</span><span class="pun">);</span></li><li class="L3"><span class="pln"> </span><span class="pun">}</span></li><li class="L4"><span class="pln">&nbsp;</span></li><li class="L5"><span class="pln"> </span><span class="com">/* Make sure we have all the proper CPU support */</span></li><li class="L6"><span class="pln"> </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">validate_cpu</span><span class="pun">())</span><span class="pln"> </span><span class="pun">{</span></li><li class="L7"><span class="pln"> puts</span><span class="pun">(</span><span class="str">"Unable to boot - please use a kernel appropriate "</span></li><li class="L8"><span class="pln"> </span><span class="str">"for your CPU.\n"</span><span class="pun">);</span></li><li class="L9"><span class="pln"> </span><span class="kwd">die</span><span class="pun">();</span></li><li class="L0"><span class="pln"> </span><span class="pun">}</span></li><li class="L1"><span class="pln">&nbsp;</span></li><li class="L2"><span class="pln"> </span><span class="com">/* Tell the BIOS what CPU mode we intend to run in. */</span></li><li class="L3"><span class="pln"> set_bios_mode</span><span class="pun">();</span></li><li class="L4"><span class="pln">&nbsp;</span></li><li class="L5"><span class="pln"> </span><span class="com">/* Detect memory layout */</span></li><li class="L6"><span class="pln"> detect_memory</span><span class="pun">();</span></li><li class="L7"><span class="pln">&nbsp;</span></li><li class="L8"><span class="pln"> </span><span class="com">/* Set keyboard repeat rate (why?) */</span></li><li class="L9"><span class="pln"> keyboard_set_repeat</span><span class="pun">();</span></li><li class="L0"><span class="pln">&nbsp;</span></li><li class="L1"><span class="pln"> </span><span class="com">/* Set the video mode */</span></li><li class="L2"><span class="pln"> set_video</span><span class="pun">();</span></li><li class="L3"><span class="pln">&nbsp;</span></li><li class="L4"><span class="pln"> </span><span class="com">/* Query MCA information */</span></li><li class="L5"><span class="pln"> query_mca</span><span class="pun">();</span></li><li class="L6"><span class="pln">&nbsp;</span></li><li class="L7"><span class="pln"> </span><span class="com">/* Voyager */</span></li><li class="L8"><span class="com">#ifdef</span><span class="pln"> CONFIG_X86_VOYAGER</span></li><li class="L9"><span class="pln"> query_voyager</span><span class="pun">();</span></li><li class="L0"><span class="com">#endif</span></li><li class="L1"><span class="pln">&nbsp;</span></li><li class="L2"><span class="pln"> </span><span class="com">/* Query Intel SpeedStep (IST) information */</span></li><li class="L3"><span class="pln"> query_ist</span><span class="pun">();</span></li><li class="L4"><span class="pln">&nbsp;</span></li><li class="L5"><span class="pln"> </span><span class="com">/* Query APM information */</span></li><li class="L6"><span class="com">#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)</span></li><li class="L7"><span class="pln"> query_apm_bios</span><span class="pun">();</span></li><li class="L8"><span class="com">#endif</span></li><li class="L9"><span class="pln">&nbsp;</span></li><li class="L0"><span class="pln"> </span><span class="com">/* Query EDD information */</span></li><li class="L1"><span class="com">#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)</span></li><li class="L2"><span class="pln"> query_edd</span><span class="pun">();</span></li><li class="L3"><span class="com">#endif</span></li><li class="L4"><span class="pln"> </span><span class="com">/* Do the last things and invoke protected mode */</span></li><li class="L5"><span class="pln"> go_to_protected_mode</span><span class="pun">();</span></li><li class="L6"><span class="pun">}</span></li></ol> main函数的主要作用对硬件进行设置、通过memcpy或者硬件探测为内核启动准备参数放入boot_params结构体(main.c中定义的全局变量),然后跳转到保护模式。 boot_params结构体需要注意的部分有hdr、e820_map[E820MAX]、hdr.cmd_line_ptr,hdr是main函数调用copy_boot_params从kernel setup处拷贝过来,e820_map是main函数调用detect_memory得到,hdr.cmd_line_ptr是bootloader传递给内核的参数,所以bootloader会设置kernel setup处的hdr,bootloader把参数放在适当的位置,然后把参数的指针存放到hdr.cmd_line_ptr,需要注意的这个指针是32位保护模式下的线性地址。