linux内核启动文档翻译(i386)

      本文档的翻译是基于linux内核版本2.6.11.1的,本人英语超难,但是由于学习linux内核代码也硬着头皮看英文文档,看的过程中感觉能够学到许多东西所以决定发点时间把这篇翻译下来了,里面很很多的不准确希望大家纠正和指导。希望共同探讨和学习,这也是自己学习linux源代码的一部分内容,接下来会有更多关于这方面的知识和大家分享,包括详细的内核运行原理和超详细的内核代码注释,期待和大家分享学习过程中的点点滴滴。每天成长一点点嘛!这篇文章虽然不长,但也发了我一天的时间,主要还是因为我英文太差的缘故吧。文章中翻译不当之处或错误还请大家提出来以便我尽快改正和学习。

写在前面的一点知识:

ramdisk一个作用就是用来解决boot过程中mount根文件系统的先有鸡还是先有蛋的问题的。
一般来说,根文件系统在形形色色的存储设备上,不同的设备又要不同的硬件厂商的驱动,比如intel的南桥自然需要intelide/sata驱动,VIA的南桥需要VIAide/sata驱动,根文件系统也有不同的文件系统的可能,比如ubuntu发行版可能一般用ext3suse可能就不是了,不同的文件系统也需要不同的文件系统模块;假如把所有驱动/模块都编译进内核,那自然没问题,但是这样就违背了内核的精神或本质,所以一般来说驱动/模块都驻留在根文件系统本身上/lib/modules/xxx,那么鸡蛋问题就来了,现在要mount根文件系统却需要根文件系统上的模块文件,怎么办?于是,就想出ramdisk,内核总是能安装ramdisk的,然后把所有可能需要的驱动/模块都放在ramdisk上,首先,让内核将ramdisk当作根文件系统来安装,然后再用这个根文件系统上的驱动来安装真正的根文件系统,就将这个矛盾问题解决了.

ramdisk还举出一个作用,现在的发行版在boot时一般都是图形界面的,那么,ramdisk就可以放framebuffer驱动和一些图片来做这种简单的动画。

说明:文章中的“命令行”都应该是“命令行参数”更好吧。从下面开始是英文和我翻译中文的对照。

 

 THE LINUX/I386 BOOT PROTOCOLLinux/I386启动协议)

 

     ----------------------------

    H. Peter Anvin <hpa@zytor.com>(作者邮箱)

Last update 2002-01-01(最后更新时间2002-01-01

 

On the i386 platform, the Linux kernel uses a rather complicated boot convention.  This has evolved partially due to historical aspects, as well as the desire in the early days to have the kernel itself be a bootable image, the complicated PC memory model and due to changed expectations in the PC industry caused by the effective demise of real-mode DOS as a mainstream operating system.

i386平台,linux内核使用了一个相当复杂的启动协议。这个特别的演变是由于历史各个方面,在早期的愿望是内核本身是可引导的镜像,复杂的PC机内存模型和由于期望改变在个人计算机产业中有效的终止实模式DOS而作为主流的操作系统。

Currently, four versions of the Linux/i386 boot protocol exist.

当前,四种版本的Linux/i386启动协议存在。

Old kernels: zImage/Image support only.  Some very early kernels may not even support a command line.

老的内核:zImage/Image格式仅仅被支持。一些非常早的内核甚至可能不支持命令行。

Protocol 2.00: (Kernel 1.3.73) Added bzImage and initrd support, as well as a formalized way to communicate between the boot loader and the kernel.  setup.S made relocatable,although the traditional setup area still assumed writable.

协议2.00:(Kernel 1.3.73)增加了bzImage 和 initrd支持,以及引导加载程序和内核之间的通信的正式方式。setup.S 作出可重定位,尽管传统setup区域仍假定可写。

Protocol 2.01: (Kernel 1.3.76) Added a heap overrun warning.

协议2.01(Kernel 1.3.76)添加堆溢出警告

Protocol 2.02: (Kernel 2.4.0-test3-pre3) New command line protocol.Lower the conventional memory ceiling. No overwrite of the traditional setup area, thus making booting safe for systems which use the EBDA from SMM or 32-bit BIOS entry points.  zImage deprecated but still supported.

协议2.02: (Kernel 2.4.0-test3-pre3) 新的命令行协议。降低常规的内存上限。传统setup区域不能重写,从而使安全的启动系统,使用从SMMSystem Management Mode系统管理模式)或32BIOS入口点 EBDAExtended BIOS Data Area可扩展的BIOS数据区域)。zImage 不赞成但是仍然支持。

Protocol 2.03: (Kernel 2.4.18-pre1) Explicitly makes the highest possible initrd address available to the bootloader.

协议2.03: (Kernel 2.4.18-pre1)  明白地安排最高initrd地址可用引导装入过程  

 

**** MEMORY LAYOUT(内存布局)

 

The traditional memory map for the kernel loader, used for Image or

zImage kernels, typically looks like:

传统的内核装载内存映射,使用Image or zImage内核,典型地看起来像:

|  |

0A0000 +------------------------+

|  Reserved for BIOS  | Do not use.  Reserved for BIOS EBDA.(不使用。为BIOS EBDA保留)

09A000 +------------------------+

|  Stack/heap/cmdline  | For use by the kernel real-mode code.(实模式内核代码使用)

098000 +------------------------+

|  Kernel setup  | The kernel real-mode code.(实模式内核代码)

090200 +------------------------+

|  Kernel boot sector  | The kernel legacy boot sector.(内核启动扇区)

090000 +------------------------+

|  Protected-mode kernel | The bulk of the kernel image.(保护模式,大的内核映像)

010000 +------------------------+

|  Boot loader  | <- Boot sector entry point 0000:7C00(启动装载进入点0000:7c00

001000 +------------------------+

|  Reserved for MBR/BIOS |(为MBRmaster boot record主引导记录)BIOS保留)

000800 +------------------------+

|  Typically used by MBR |(典型被MBR使用)

000600 +------------------------+ 

|  BIOS use only  |(仅仅被BIOS使用)

000000 +------------------------+

 

 

When using bzImage, the protected-mode kernel was relocated to 0x100000 ("high memory"), and the kernel real-mode block (boot sector,setup, and stack/heap) was made relocatable to any address between 0x10000 and end of low memory.

当使用bzImage,保护模式内核是移动到0x100000(“高内存”),实模式模块(boot sector,setup, and stack/heap)被装载到地址0x10000 到最低内存的结尾的任何地方。

Unfortunately, in protocols 2.00 and 2.01 the command line is still required to live in the 0x9XXXX memory range, and that memory range is still overwritten by the early kernel.The 2.02 protocol resolves that problem.

幸运地,在协议2.002.01中命令行仍然被要求存在0x9XXXXX内存区域,那段内存区域仍然被早期内核重写。2.02协议解决了那个问题。

It is desirable to keep the "memory ceiling" -- the highest point in low memory touched by the boot loader -- as low as possible, since some newer BIOSes have begun to allocate some rather large amounts of memory, called the Extended BIOS Data Area, near the top of low memory.  The boot loader should use the "INT 12h" BIOS call to verify how much low memory is available.

期望保持内存上限--在低内存的最高点被引导加载程序接触--尽可能的低,因为一些新的BIOSes 已经开始分配一些相当大的内存数量,叫做可扩展BIOS的数据区域,在低内存的顶端附近。引导加载程序应该使用 "INT 12h" BIOS 中断调用确定有多大的低内存是可利用的。

Unfortunately, if INT 12h reports that the amount of memory is too low, there is usually nothing the boot loader can do but to report an error to the user.  The boot loader should therefore be designed to take up as little space in low memory as it reasonably can.  For zImage or old bzImage kernels, which need data written into the

0x90000 segment, the boot loader should make sure not to use memory above the 0x9A000 point; too many BIOSes will break above that point.

幸运地,如果INT 12h中断调用报告内存总量太少,则通常没有引导加载程序能启动并且报告一个错误给用户。因此引导加载程序应该被设计在低内存占用尽量少量的空间。因为zImage 或 老的bzImage内核,需要数据被写在0x90000段处,引导加载程序应该确保不使用高于0x9A000点的内存;太多的BIOSes将破坏那个点以上的内存。

 

**** THE REAL-MODE KERNEL HEADER(实模式内核开头)

 

In the following text, and anywhere in the kernel boot sequence, "a sector" refers to 512 bytes.  It is independent of the actual sector size of the underlying medium.

在下面的文本中,在内核启动顺序的任何地方,“一个扇区”是指512字节。它是下面媒介的实际扇区大小的独立(意思不依赖具体的存储介质,一个扇区都是指512字节)。

The first step in loading a Linux kernel should be to load the real-mode code (boot sector and setup code) and then examine the following header at offset 0x01f1.  The real-mode code can total up to 32K, although the boot loader may choose to load only the first two sectors (1K) and then examine the bootup sector size.

第一步在装载一个linux内核应该被装载实模式代码(boot sector setup代码)然后检查接下来在偏移0x01f1处的header代码。实模式代码能达到32K,但是引导加载程序可能选择装载仅仅开始的两个扇区(1K)然后检查启动扇区的大小。

The header looks like:

Header看起来像:

Offset(偏移量)Proto(协议)Name(名字)Meaning(意思)

/Size(大小)

 

01F1/1  ALL setup_sects The size of the setup in sectors

           (所有)                  setup设置扇区的大小)

01F2/2  ALL       root_flags If set, the root is mounted readonly

如果被设置,root被只读挂载

01F4/2  ALL syssize DO NOT USE - for bootsect.S use only

不使用-仅仅被bootsect.S 使用

01F6/2 ALL swap_dev DO NOT USE - obsolete

(不使用-已不用的)

01F8/2 ALL ram_size DO NOT USE - for bootsect.S use only

不使用-仅仅被bootsect.S 使用

01FA/2 ALL vid_mode Video mode control

视频模式控制

01FC/2 ALL root_dev Default root device number

默认的根设备号

01FE/2 ALL boot_flag 0xAA55 magic number

0xAA55 魔法数字

0200/2 2.00+ jump Jump instruction

2.00以上 跳转指令

0202/4 2.00+ header Magic signature "HdrS"

魔法信号"HdrS"

0206/2 2.00+ version Boot protocol version supported

协议版本 启动协议版本支持

0208/4 2.00+ realmode_swtch Boot loader hook (see below)

实模式转换 引导装载程序钩子(看下面)

020C/2 2.00+ start_sys The load-low segment (0x1000) (obsolete)

开始系统段 低装载段0x1000(已过时)

020E/2 2.00+ kernel_version Pointer to kernel version string

内核版本 指向内核版本字符串

0210/1 2.00+ type_of_loader Boot loader identifier

装载类型 引导装载程序标志

0211/1 2.00+ loadflags Boot protocol option flags

装载标志 引导协议可选标志

0212/2 2.00+ setup_move_size Move to high memory size (used with hooks)

Setup移动大小 移动到高内存大小(使用钩子)

0214/4 2.00+ code32_start Boot loader hook (see below)

32位代码启动 引导装载程序钩子(看下面)

0218/4 2.00+ ramdisk_image initrd load address (set by boot loader)

Ramdisk镜像 initrd(初始化跟设备)装载地址(被引导装载程序设置)

021C/4 2.00+ ramdisk_size initrd size (set by boot loader)

Ramdisk大小 initrd 大小(被引导装载程序设置)

0220/4 2.00+ bootsect_kludge DO NOT USE - for bootsect.S use only

不使用-仅仅被bootsect.S 使用

0224/2 2.01+ heap_end_ptr Free memory after setup end

2.01以上 堆结束指针 setup结束以后是自由内存

0226/2 N/A pad1 Unused

0228/4 2.02+ cmd_line_ptr 32-bit pointer to the kernel command line

2.02以上 命令行参数指针 32位指向内核命令行参数

022C/4 2.03+ initrd_addr_max Highest legal initrd address

2.03以上 initrd最大地址 最高合法的initrd地址

For backwards compatibility, if the setup_sects field contains 0, the real value is 4.

为了后面的兼容性,如果setup_sects区域包含0,真实的值是4

If the "HdrS" (0x53726448) magic number is not found at offset 0x202,the boot protocol version is "old".  Loading an old kernel, the following parameters should be assumed:

如果"HdrS" (0x53726448) 魔法数字没有在偏移0x202处被找到,启动协议版本是“老的”。装载一个老的内核,下面的参数应该被假设:

Image type = zImage 映像内核=zImage

initrd not supported initrd不被支持

Real-mode kernel must be located at 0x90000.实模式内核必须位于0x90000

 

Otherwise, the "version" field contains the protocol version,e.g. protocol version 2.01 will contain 0x0201 in this field.  When setting fields in the header, you must make sure only to set fields supported by the protocol version in use.

否则,“version”区域包含协议版本,例如协议本版2.01将包含0x0201在这个区域。当设置区域在header中时,你必须确保仅仅设置区域被使用的协议版本所支持。

The "kernel_version" field, if set to a nonzero value, contains a pointer to a null-terminated human-readable kernel version number string, less 0x200.  This can be used to display the kernel version to the user.  This value should be less than (0x200*setup_sects).  For example, if this value is set to 0x1c00, the kernel version number string can be found at offset 0x1e00 in the kernel file.  This is a valid value if and only if the "setup_sects" field contains the value 14 or higher.

"kernel_version" 字段,如果被设置为一个非零值,包含一个指向(NULL)空结束的人可读的内核版本数字字符串,小于0x200。这个能够被使用显示内核版本给用户看。这个值应该小于(0x200*setup的扇区数)。例如,如果这个值被设置为0x1c00,内核版本数字字符串能够被找到在内核文件偏移0x1e00处。如果并且仅仅如果"setup_sects"字段包含值14或更高这是一个有效值

Most boot loaders will simply load the kernel at its target address directly.  Such boot loaders do not need to worry about filling in most of the fields in the header.  The following fields should be filled out, however:

大多数引导装载程序将简单直接的装载内核到它的目的地址。这样引导装载程序不需要担心在header填充很多的字段。然而,下面的字段应该被填充:

 vid_mode:Please see the section on SPECIAL COMMAND LINE OPTIONS.

视频模式:请看特殊的命令行可选部分

  type_of_loader:装载类型

If your boot loader has an assigned id (see table below), enter 0xTV here, where T is an identifier for the boot loader and V is a version number.  Otherwise, enter 0xFF here.

如果你的引导装载程序有一个被指派的id(看下面的表格),进入0xTV这儿,T是一个引导装载程序的标志符,V是一个版本数字。否则,进入0xFF这儿。

Assigned boot loader ids:指派的引导装载程序(以下9种)

0  LILO

1  Loadlin

2  bootsect-loader

3  SYSLINUX

4  EtherBoot

5  ELILO

7  GRuB

8  U-BOOT

 

Please contact <hpa@zytor.com> if you need a bootloader ID value assigned.

请联系 <hpa@zytor.com>如果你需要一个引导装载程序被指派的ID

 

  loadflags, heap_end_ptr:装载标志,堆结束指针

If the protocol version is 2.01 or higher, enter the offset limit of the setup heap into heap_end_ptr and set the 0x80 bit (CAN_USE_HEAP) of loadflags.  heap_end_ptr appears to be relative to the start of setup (offset 0x0200).

如果协议版本是2.01或更高,设置setup堆栈的限制到heap_end_ptr(堆结束指针)处和设置0x80位(能够使用堆栈)标志。heap_end_ptr(堆结束指针)显示相对setup的开始(偏移0x0200)。

  setup_move_size: setup移动的大小

When using protocol 2.00 or 2.01, if the real mode kernel is not loaded at 0x90000, it gets moved there later in the loading sequence.  Fill in this field if you want additional data (such as the kernel command line) moved in addition to the real-mode kernel itself.

当使用协议2.002.01,如果实模式内核是不装载在0x90000,它在加载序号以后被移动那里。如果你需要额外的数据(例如内核命令行)被移动,那么填充这个字段增加到实模式内核自身。

  ramdisk_image, ramdisk_size:内存盘映像,内存盘大小

If your boot loader has loaded an initial ramdisk (initrd), set ramdisk_image to the 32-bit pointer to the ramdisk data and the ramdisk_size to the size of the ramdisk data.

如果你的引导装载程序已经装载一个初始化的内存盘(initrd),设置内存盘映像(ramdisk_image)为一个32位指针指向内存盘数据和设置内存盘大小(ramdisk_size)为内存盘数据的大小。

The initrd should typically be located as high in memory as possible, as it may otherwise get overwritten by the early kernel initialization sequence.  However, it must never be located above the address specified in the initrd_addr_max field. The initrd should be at least 4K page aligned.

初始化的内存盘(initrd)应该典型地位于尽可能的高的内存,因为它可能被早的内核初始化序列覆盖写。然而,它必须从来不位于在专门化的initrd_addr_max 字段以上的地址。初始化的内存盘(initrd)应该被设置至少4K页对齐。

  cmd_line_ptr:命令行指针

If the protocol version is 2.02 or higher, this is a 32-bit pointer to the kernel command line.  The kernel command line can be located anywhere between the end of setup and 0xA0000.Fill in this field even if your boot loader does not support a command line, in which case you can point this to an empty string (or better yet, to the string "auto".)  If this field is left at zero, the kernel will assume that your boot loader does not support the 2.02+ protocol.

如果协议是2.02或更高,这是一个32位指针指向内核命令行。内核命令行能位于setup结束至0xA0000的任何地方。填充这个字段虽然你的引导装载程序不支持一个命令行,它能使你这个字段指向一个空字符串(或更好,是一个“auto”字符串)如果这个字段被留下在零,内核将假设你的引导装载程序不支持2.02以上的协议。

  ramdisk_max:内存盘最大

The maximum address that may be occupied by the initrd contents.  For boot protocols 2.02 or earlier, this field is not present, and the maximum address is 0x37FFFFFF.  (This address is defined as the address of the highest safe byte, so if your ramdisk is exactly 13107131072 2 bytes long and this field is 0x37FFFFFF, you can start your ramdisk at 0x37FE0000.)

可能被初始化内存盘内容占用最大地址。对于引导协议2.02或更早,这个字段是不存在的,并且最大地址是0x37FFFFFF。(这个地址被定义为最高的安全字节,因此如果你的内存盘确切的131072 字节长并且这个区域是0x37FFFFFF,你能开始你的内存盘在0x37FE0000)。

 

**** THE KERNEL COMMAND LINE内核命令行

 

The kernel command line has become an important way for the boot loader to communicate with the kernel.  Some of its options are also relevant to the boot loader itself, see "special command line options"below.

内核命令行已近是改变引导装载程序和内核通信的一种重要方式。一些它的可选项也是有关于引导装载程序自身的,看下面的“特殊的命令行可选项”。

The kernel command line is a null-terminated string up to 255 characters long, plus the final null.

内核命令行是一个NULL(空)终止的加上最后的null到达255个字符长度的字符串。

If the boot protocol version is 2.02 or later, the address of the kernel command line is given by the header field cmd_line_ptr (see above.)

如果引导协议版本是2.02或更晚,内核的命令行地址被header字段 cmd_line_ptr 给出(看上面)。

If the protocol version is *not* 2.02 or higher, the kernel command line is entered using the following protocol:

如果协议版本不是2.02或更高,内核命令行被输入使用下面的协议:

At offset 0x0020 (word), "cmd_line_magic", enter the magic number 0xA33F.

在偏移0x0020(字),“cmd_line_magic”,输入魔法数字0xA33F

At offset 0x0022 (word), "cmd_line_offset", enter the offset of the kernel command line (relative to the start of the real-mode kernel).

在偏移0x0022(字),"cmd_line_offset", 输入内核命令行的偏移量(与实模式内核开始有关)

The kernel command line *must* be within the memory region covered by setup_move_size, so you may need to adjust this field.

内核命令行必须在被setup_move_size内存区域大小覆盖以内,因此你可能需要调整这个字段。

 

**** SAMPLE BOOT CONFIGURATION引导程序配置样例

 

As a sample configuration, assume the following layout of the real mode segment:

作为一个样例配置,假设实模式段有下面的布局:

0x0000-0x7FFF Real mode kernel实模式内核

0x8000-0x8FFF Stack and heap栈和堆

0x9000-0x90FF Kernel command line内核命令行

 

Such a boot loader should enter the following fields in the header:

如此一个引导装载程序应该进入下面字段,在header中。

unsigned long base_ptr; /* base address for real-mode segment */实模式的段地址

 

if ( setup_sects == 0 ) {

setup_sects = 4;

}

 

if ( protocol >= 0x0200 ) {

type_of_loader = <type code>;

if ( loading_initrd ) {

ramdisk_image = <initrd_address>;

ramdisk_size = <initrd_size>;

}

if ( protocol >= 0x0201 ) {

heap_end_ptr = 0x9000 - 0x200;

loadflags |= 0x80; /* CAN_USE_HEAP */

}

if ( protocol >= 0x0202 ) {

cmd_line_ptr = base_ptr + 0x9000;

} else {

cmd_line_magic = 0xA33F;

cmd_line_offset = 0x9000;

setup_move_size = 0x9100;

}

} else {

/* Very old kernel */

 

cmd_line_magic = 0xA33F;

cmd_line_offset = 0x9000;

 

/* A very old kernel MUST have its real-mode code

   loaded at 0x90000 */一个老的内核必须有它的实模式代码装载在0x90000 

 

if ( base_ptr != 0x90000 ) {

/* Copy the real-mode kernel */复制实模式内核

memcpy(0x90000, base_ptr, (setup_sects+1)*512);

/* Copy the command line */复制命令行

memcpy(0x99000, base_ptr+0x9000, 256);

 

base_ptr = 0x90000;  /* Relocated */重映射

}

 

/* It is recommended to clear memory up to the 32K mark */它要求清除内存到32K标志

memset(0x90000 + (setup_sects+1)*512, 0,

       (64-(setup_sects+1))*512);

}

 

 

**** LOADING THE REST OF THE KERNEL(装载剩余的内核部分)

 

The non-real-mode kernel starts at offset (setup_sects+1)*512 in the kernel file (again, if setup_sects == 0 the real value is 4.)  It should be loaded at address 0x10000 for Image/zImage kernels and 0x100000 for bzImage kernels.

非实模式内核开始在内核文件偏移 (setup_sects+1)*512 处(重复一下,如果 setup_sects == 0 真实值是4)。作为Image/zImage它应该被装载在地址0x10000 ,作为bzImage它应该被装载在地址0x100000 

The kernel is a bzImage kernel if the protocol >= 2.00 and the 0x01 bit (LOAD_HIGH) in the loadflags field is set:

如果协议大于等于2.00并且在装载标志(loadflags )字段的0x01位(高装载)被设置,则内核是一个bzImage(大模式内核)。

is_bzImage = (protocol >= 0x0200) && (loadflags & 0x01);//伪代码表示

load_address = is_bzImage ? 0x100000 : 0x10000;//伪代码表示

 

Note that Image/zImage kernels can be up to 512K in size, and thus use the entire 0x10000-0x90000 range of memory.  This means it is pretty much a requirement for these kernels to load the real-mode part at

0x90000.  bzImage kernels allow much more flexibility.

注意that Image/zImage(小模式内核)能够到达512K大小,因此使用整个 0x10000-0x90000 内存区域。这意味着对这些内核它是相当多的要求来装载实模式部分在0x90000bzImage内核允许更多的灵活性。

 

**** SPECIAL COMMAND LINE OPTIONS(特殊的命令行可选项)

 

If the command line provided by the boot loader is entered by the user, the user may expect the following command line options to work. They should normally not be deleted from the kernel command line even

though not all of them are actually meaningful to the kernel.  Boot loader authors who need additional command line options for the boot loader itself should get them registered in Documentation/kernel-parameters.txt to make sure they will not conflict with actual kernel options now or in the future.

如果被引导装载程序提供的命令行被用户输入,用户可能期望根据下面的命令行的可选项来运行。通常不应该从内核命令行删除他们,即使不是所有的他们对内核来说都有实际上的意义。针对引导装载程序自身的需要额外的命令行可选项的引导装载程序作者应该从注册在Documentation/kernel-parameters.txt这个文件中得到他们,来确保他们将不会和现在或将来的实际的内核可选项产生冲突。

  vga=<mode>VGA=《模式》(也就是显卡模式配置)

<mode> here is either an integer (in C notation, either decimal, octal, or hexadecimal) or one of the strings

"normal" (meaning 0xFFFF), "ext" (meaning 0xFFFE) or "ask" (meaning 0xFFFD).  This value should be entered into the vid_mode field, as it is used by the kernel before the command line is parsed.

<模式>这儿不是一个整数(在C语言中的记号,不是十进制,八进制,就是十六进制)就是一个字符串“正常”(0xFFFF代表的意义),“ext”(0xFFFE代表的意义),“ask”(0xFFFD代表的意义)。这个值应该被输入视频模式(vid_mode)字段,在命令行被解析以前被内核使用。

  mem=<size>

<size> is an integer in C notation optionally followed by K, M or G (meaning << 10, << 20 or << 30).  This specifies the end of memory to the kernel. This affects the possible placement of an initrd, since an initrd should be placed near end of memory.  Note that this is an option to *both* the kernel and the bootloader!

C语言的表示<size> 是随意地跟着KMG的一个整数(意思左移10,20,30位), 这指定内核的内存末端。这可能影响的地方是一个初始化的内存盘(initrd),因为初始化的内存盘(initrd)应该被放置在内存末端的附近。注意在内核(kernel)和引导装载程序(bootloader)都是一个可选项。

  initrd=<file>

An initrd should be loaded.  The meaning of <file> is obviously bootloader-dependent, and some boot loaders (e.g. LILO) do not have such a command.

这个初始化的内存盘应该被装载。<file>的意思明显是依赖于引导装载程序(bootloader),并且一些引导装载程序(bootloader)(像LILO)没有如此的一个命令。

In addition, some boot loaders add the following options to the user-specified command line:

 另外,一些启动装载程序增加以下选择项到用户指定的命令行:  

  BOOT_IMAGE=<file>

The boot image which was loaded.  Again, the meaning of <file> is obviously bootloader-dependent.

被装载的引导镜像。再一次,<file>的意思明显是依赖于引导装载程序(bootloader)。

  Auto(自动)

The kernel was booted without explicit user intervention.

内核被引导没有明显的用户交互。

If these options are added by the boot loader, it is highly recommended that they are located *first*, before the user-specified or configuration-specified command line.  Otherwise, "init=/bin/sh" gets confused by the "auto" option.

如果这些选择项由启动装载程序增加,在用户指定或配置指定的命令行之前我们极力推荐他们是被第一个被找出的。  否则, “init=/bin/sh”由“自动”选项拒绝。

**** RUNNING THE KERNEL运行内核

 

The kernel is started by jumping to the kernel entry point, which is located at *segment* offset 0x20 from the start of the real mode kernel.  This means that if you loaded your real-mode kernel code at 0x90000, the kernel entry point is 9020:0000.

内核跳转到位于的内核入口点被启动的, 从实模式内核开始的地址处段偏移 0x20。这意味着如果您加载您的实时模式内核代码在 0x90000,内核入口点是 9020:0000

At entry, ds = es = ss should point to the start of the real-mode kernel code (0x9000 if the code is loaded at 0x90000), sp should be set up properly, normally pointing to the top of the heap, and interrupts should be disabled.  Furthermore, to guard against bugs in the kernel, it is recommended that the boot loader sets fs = gs = ds =es = ss.

在入口,ds = es = ss应该指向实模式内核代码开始的地方(如果代码被装载在ox90000处就是0x9000),SP(堆栈指针)的开始应该适当地设定,通常指向堆的顶端,并且所有的中断应该被禁止。此外,为了在内核控制产生错误(bugs),建议启动装载程序设置fs = gs = ds =es = ss

In our example from above, we would do:

在来至上面我们的例程,我们应该做:

/* Note: in the case of the "old" kernel protocol, base_ptr must be == 0x90000 at this point; see the previous sample code */

注意:在老内核协议的情况下,在base_ptr这一点必须是在0x90000 ,看以前样例代码

seg = base_ptr >> 4;

 

cli(); /* Enter with interrupts disabled! */禁止中断

 

/* Set up the real-mode kernel stack */建立实模式内核堆栈

_SS = seg;

_SP = 0x9000; /* Load SP immediately after loading SS! */在装载了SS(堆栈段)以后立即装载堆栈指针(SP

 

_DS = _ES = _FS = _GS = seg;

jmp_far(seg+0x20, 0); /* Run the kernel */运行内核

 

If your boot sector accesses a floppy drive, it is recommended to switch off the floppy motor before running the kernel, since the kernel boot leaves interrupts off and thus the motor will not be switched off, especially if the loaded kernel has the floppy driver as a demand-loaded module!

如果您的引导扇区访问(软盘)磁盘驱动器,推荐在运行内核之前关闭马达。因为内核引导停止中断,因此电机将不会关闭,特别是如果在加载的内核有软盘驱动程序作为需求加载的模块 !

**** ADVANCED BOOT TIME HOOKS先进的启动时间挂钩

 

If the boot loader runs in a particularly hostile environment (such as LOADLIN, which runs under DOS) it may be impossible to follow the standard memory location requirements.  Such a boot loader may use the following hooks that, if set, are invoked by the kernel at the appropriate time.  The use of these hooks should probably be

considered an absolutely last resort!

如果你的引导装载程序运行在一个特别的不稳定的环境中(例如LOADIN,运行在DOS之下)它可能不能按照标准内存位置的要求。因为一个引导装载程序可能使用下面那样的钩子,如果设置,被内核在合适的时间调用。使用这些钩子可能应考虑一个绝对最后的手段。

IMPORTANT: All the hooks are required to preserve %esp, %ebp, %esi and %edi across invocation.

重要:所有在调用的钩子要求保护esp寄存器, ebp寄存器, esi寄存器 和edi寄存器 

  realmode_swtch:实模式切换

A 16-bit real mode far subroutine invoked immediately before entering protected mode.  The default routine disables NMI, so your routine should probably do so, too.

在进入保护模式以前16位实模式远子程序立即调用。默认例程禁止NMI(不可屏蔽中断),因此你的例程也应该可能这样做。

 

  code32_start:32位代码开始

A 32-bit flat-mode routine *jumped* to immediately after the transition to protected mode, but before the kernel is uncompressed.  No segments, except CS, are set up; you should set them up to KERNEL_DS (0x18) yourself.

在过渡到保护模式以后立即跳转到一个32位的线性平板模式运行路线,但是在内核被解压之前。除了CS代码段是没有段被建立;你应该建立你自己的内核数据段(KERNEL_DS)(0x18)。

After completing your hook, you should jump to the address that was in this field before your boot loader overwrote it.

 在完成您的勾子以后,您应该跳到在这个字段的地址,在您的启动装载程序重写它之前。

posted @ 2010-07-27 00:07  蔷薇理想人生  阅读(1014)  评论(0编辑  收藏  举报