LILO会执行装入内核映像的工作,它会将内核映像装载到0x00010000处(对于低装载)或者0x00100000处(对于高装载),所以在跳转到header.S的_start的时候,内存里面的代码布局为:
0x90000: header.S前512字节内容,兼容软盘,已经废弃
0x90200: header.S的_start及其后,LILO的setup函数会加载这个扇区
低装载:0x10000:带解压的vmlinux
高装载:0x100000:带解压的vmlinux。
UBOOT也起到相同的效果。对于X86来说,bootloader和kernel的交互参数是hdr和cmdline,因为x86的兼容性较好,架构变化不大。但是对于arm和ppc,嵌入式场景很多,所以后续采用更好的设备树架构,扩展性更好一些。
UBOOT和kernel的交接点如下:
load_zimage //Zimage.c (uboot\lib_i386) 7320 2012/1/17
=>setup_base = (void*)DEFAULT_SETUP_BASE; /* base address for real-mode segment */ //#define DEFAULT_SETUP_BASE 0x90000
=>/* determine size of setup */
if (0 == *(u8*)(image + SETUP_SECTS_OFF)) { //#define SETUP_SECTS_OFF 0x1F1 /* The size of the setup in sectors */ //SETUP_SECTS_OFF 等在“Zimage.h (uboot\include\asm-i386) 3075 2012/1/17
”里面定义,属于bootloader和内核交互的参数,详细在 linux-2.6.23\Documentation\i386\boot.txt 里面有描述,在内核的定义是setup_header hdr
setup_size = 5 * 512;
} else {
setup_size = (*(u8*)(image + SETUP_SECTS_OFF) + 1) * 512;
}
=>load_address = (void*)(big_image ? BZIMAGE_LOAD_ADDR:ZIMAGE_LOAD_ADDR);//前面说的,低装载或者高装载内核
=>build_command_line(setup_base + COMMAND_LINE_OFFSET, auto_boot); /* build command line at COMMAND_LINE_OFFSET */ //构建cmdline
加载内核使用如下函数
boot_zimage(void *setup_base)//setup_base 0x90000
=>enter_realmode(((u32)setup_base+SETUP_START_OFFSET)>>4, 0, ®s, ®s);//SETUP_START_OFFSET 是0x200,表示是第二个扇区,也就是第二个512字节
X86内核启动流程:如下一系列的内核启动
内核启动初步
http://blog.csdn.net/yu616568/article/details/7578573
e820是关键,关于e820可用参考如下文章:
从硬件获得内存布局–e820, 这个人的博客不错,可用好好学习一下
http://blog.csdn.net/richardysteven/article/details/69350893
e820与kernel物理内存映射
http://deltamaster.is-programmer.com/posts/37297.html
疯狂内核系列
http://blog.csdn.net/yunsongice/article/category/759408/2
[置顶] linux内核启动1-启动参数(启动参数的获取和处理,分析setup_arch)
http://www.cnblogs.com/james1207/p/3343528.html