打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Linux内核x86架构引导协议6(翻译)

简单的引导示例

在示例中,我们假设有实模式内存段布局:

 

    当加载内核实模式部分到0x90000后,该内存段中的内容为:

 

       0x0000-0x7fff              内核实模式部分

       0x8000-0xdfff              堆栈

       0xe000-0xffff        内核命令行

 

    当加载内核实模式部分到0x90000或者引导协议为2.01及之前的版本:

 

       0x0000-0x7fff              内核实模式部分

       0x8000-0x97ff              堆栈

       0x9800-0x9fff              内核命令行

 

内核加载程序应该对数据头做以下检查:

 

       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 >= 0x0202 && loadflags & 0x01 )

                     heap_end = 0xe000;

              else

                     heap_end = 0x9800;

 

              if ( protocol >= 0x0201 ) {

                     heap_end_ptr = heap_end - 0x200;

                     loadflags |= 0x80; /* CAN_USE_HEAP */

              }

 

              if ( protocol >= 0x0202 ) {

                     cmd_line_ptr = base_ptr + heap_end;

                     strcpy(cmd_line_ptr, cmdline);

              } else {

                     cmd_line_magic     = 0xA33F;

                     cmd_line_offset = heap_end;

                     setup_move_size = heap_end + strlen(cmdline)+1;

                     strcpy(base_ptr+cmd_line_offset, cmdline);

              }

       } else {

              /* Very old kernel */

 

              heap_end = 0x9800;

 

              cmd_line_magic     = 0xA33F;

              cmd_line_offset = heap_end;

 

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

                 loaded at 0x90000 */

 

              if ( base_ptr != 0x90000 ) {

                     /* Copy the real-mode kernel */

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

                     base_ptr = 0x90000;             /* Relocated */

              }

 

              strcpy(0x90000+cmd_line_offset, cmdline);

 

              /* It is recommended to clear memory up to the 32K mark */

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

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

       }

加载内核的其余部分

内核的32位(非实模式)部分处于内核文件的(setup_sects+1)*512偏移处(再次提醒一下,如果setup_sects == 0,其真实值是4)。如果是Image/zImage类型的内核,它需要被加载到0x10000处。如果是bzImage类型的内核则需要加载到0x100000

       如果引导一些大于等于2.00并且loadflagsLOAD_HIGH位置位的话,那么内核肯定是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.

需要特别留意的几个命令行选项

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.

 

  vga=<mode>

       <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.

 

  mem=<size>

       <size> is an integer in C notation optionally followed by

       (case insensitive) K, M, G, T, P or E (meaning << 10, << 20,

       << 30, << 40, << 50 or << 60).  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!

 

  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.

 

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.

 

  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.
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
linux 启动协议分析--由boot.txt翻译而来
LInux 问题集1
Linux内存初始化
Using the initial RAM disk (initrd)
OS linux - uboot 引导 kernel
什么是initrd?
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服