分享

Linux内核x86架构引导协议 1(翻译)

 just_person 2012-04-16

注:

1、本文档翻译的是Linux内核的源代码中的Documentation\x86\ boot.txt。内核版本为2.6.36.2。

2、该文档的版权依照原文档的版权要求,需要遵循GNU GENERAL PUBLIC LICENSE Version 2。

3、本文所有内容,不保证其正确性。读者请自己辨识。

 

x86平台上,Linux内核具有一个颇为复杂的引导协议。在现代计算机系统中,为了运行早已不是主流操作系统的DOS(运行于实模式)而设计了一套复杂的内存管理模式。正式这个历史原因加剧了Linux引导的复杂性。

目前,在X86平台上,Linux的引导协议存在以下的几个版本:

古老内核版本:仅仅支持zImage/Image内核打包类型。另外,早期版本的内核不支持内核命令行参数。

2.00版:(1.3.73版内核制定)添加对bzImage内核打包类型和initrd的支持,开始规定引导加载程序与内核之间的联系。setup.S可以重定位,但是依然假设原来的setup区域是可写的。

2.01版:(1.3.76版内核制定)新增堆越界警告。

2.02版:(2.4.0-test3-pre3版内核制定)新的内核命令行协议。允许在常规内存的任意位置(即1MB以下的任意位置。)不再更改原来的setup区域。这样就可以很安全地从那些使用EBDA32BIOS的系统中引导内核(TODO:为什么?)。从该版本开始,不再推荐使用zImage内核打包格式,但是依然支持。

2.03版:(2.4.18- pre1版内核制定)明确加载程序加载initrd到内存时可以使用的最大的内存位置。

2.04版:(2.6.14版内核制定)将syssize字段拓展为4个字节(也就说最大可以表示4GB)

2.05版:(2.6.20版内核制定)引入relocatable_kernelkernel_alignment字段 ,使保护模式的内核可以重定位。

2.06版:(2.6.22版内核制定)添加一个字段用来指定内核命令行内容的大小。

2.07版:(2.6.24版内核制定)新增虚拟化引导协议。引入hardware_subarchhardware_subarch_data字段。并在load_flags中添加KEEP_SEGMENTS标志。

2.08版:(2.6.26版内核制定)新增crc32奇偶检验码和ELF文件格式payloadELF format payload)。引入payload_offsetpayload_length字段以便于payload进行寻址。

2.09版:(2.6.26版内核制定)为单链表结构体setup_data新增一个64位物理指针字段。

2.10版:(2.6.31版内核制定)为了约定内核的边界对齐要求,新增kernel_alignmentinit_sizepref_address字段。新增扩展引导加载程序ID

 

内存布局

内核加载程序加载Image或zImage格式内核时的“常规内存“布局,如下:

 

 

 

0A0000

 

BIOS保留

 

不使用。为BIOS  EBDA保留。

09A000

 

命令行

堆栈

 

用于内核的实模式部分。

098000

 

内核 setup

 

内核的实模式部分

090200

 

内核引导扇区

 

内核的逻辑引导扇区

090000

 

内核的保护模式部分

 

除实模式部分外的内核的绝大部分都在这儿。

010000

 

引导加载程序

 

引导扇区的入口点是0000:7C00

001000

 

MBR/BIOS保留

 

000800

 

通常被用于MBR

 

000600

 

000000

 

BIOS使用

 

 

当使用bzImage内核打包类型时,内核的保护模式部分被重定位到0x100000(高位内存,1MB处),并且内核的实模式部分(引导扇区、setup和堆栈)也可以是被放置到0x10000到常规内存顶部之间的任意位置。不幸的是,在2.00和2.01版的引导协议中0x90000以上的内存区间还是会被内核使用,从而导致引导程序无法自由使用他们。不过该问题在2.02版的协议中已经解决。

       内核加载程序应该尽量使用常规内存的低端部分。因为,一些新版的BIOS会使用常规内存的高端部分做为扩展的BIOS数据区域(Extended BIOS Data Area,缩写为EBDA)。另外,引导加载程序应该调用BIOS的INT 12H中断去获取实模式部分由多少内存可以使用。

        不过,有时候INT 12H会告诉你,现在系统中只有很少的内存可以使用,以至于内核加载程序根本无法引导。内核加载程序只好显示错误信息并退出。所以,内核加载程序应该尽量少地使用内存并尽可能有效地使用内存。由于zImage和老版的bzImage类型的内核需要使用实模式的0x90000段,所以,内核加载程序应该确保不会使用0x9A000以上的区域。很多BIOS都会因为这个问题而崩溃。


        在>=2.02版本引导协议的bzImage类型的内核中,内存布局如下图所示:

 

内核的保护模式部分

 

100000

 

I/O memory hole

 

 

0A0000

 

BIOS保留

 

命令行

 

应该尽可能多的不使用

 

(请参考下面的“X+10000”节)

X+10000

 

堆栈

 

用于内核的实模式部分。

X+08000

 

内核setup

内核引导扇区

 

内核的实模式部分

内核的逻辑引导扇区

X

 

引导加载程序

 

引导扇区的入口点是0000:7C00

001000

 

MBR/BIOS保留

 

000800

 

通常被用于MBR

 

000600

 

000000

 

BIOS使用

 

注:内核引导程序应该将地址X设计地尽量的低。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多