这段程式是Linux操作系统启动boot程式,其思想原理可参看本人翻译的《Linux内核漫游》一篇。

中文注释:赵炯 gohigh@shtdu.edu.cn www.freedove.com

! bootsect.s (c) 1991, 1992 Linus Torvalds 版权任何

! Drew Eckhardt修改过

! Bruce Evans (bde)修改过

!

! bootsect.s 被bios-启动子程式加载至0x7c00 (31k)处,并将自己

! 移到了地址0x90000 (576k)处,并跳转至那里。

!

! bde - 不能盲目地跳转,有些系统可能只有512k的低

! 内存。使用中断0x12来获得(系统的)最高内存、等。

!

! 他然后使用BIOS中断将setup直接加载到自己的后面(0x90200)(576.5k),

! 并将系统加载到地址0x10000处。

!

! 注意! 现在的内核系统最大长度限制为(8*65536-4096)(508k)字节长,即使是在

! 将来这也是没有问题的。我想让他保持简单明了。这样508k的最大内核长度应该

! 是足够了,尤其是这里没有象minix中相同包含缓冲区高速缓冲(而且尤其是现在

! 内核是压缩的 :-)

!

! 加载程式已做的尽量地简单了,所以持续的读出错将导致死循环。只能手工重启。

! 只要可能,通过一次取得整个磁道,加载过程能够做的很快的。

#include /* 为取得CONFIG_ROOT_RDONLY参数 */

!! config.h中(即autoconf.h中)没有CONFIG_ROOT_RDONLY定义!!!?

#include

.text

SETUPSECS = 4 ! 默认的setup程式扇区数(setup-sectors)的默认值;

BOOTSEG = 0x7C0 ! bootsect的原始地址;

INITSEG = DEF_INITSEG ! 将bootsect程式移到这个段处(0x9000) - 避开;

SETUPSEG = DEF_SETUPSEG ! 配置程式(setup)从这里开始(0x9020);

SYSSEG = DEF_SYSSEG ! 系统加载至0x1000(65536)(64k)段处;

SYSSIZE = DEF_SYSSIZE ! 系统的大小(0x7F00): 要加载的16字节为一节的数;

!! 以上4个DEF_参数定义在boot.h中:

!! DEF_INITSEG 0x9000

!! DEF_SYSSEG 0x1000

!! DEF_SETUPSEG 0x9020

!! DEF_SYSSIZE 0x7F00 (=32512=31.75k)*16=508k

! ROOT_DEV & SWAP_DEV 现在是由"build"中编制的;

ROOT_DEV = 0

SWAP_DEV = 0

#ifndef SVGA_MODE

#define SVGA_MODE ASK_VGA

#endif

#ifndef RAMDISK

#define RAMDISK 0

#endif

#ifndef CONFIG_ROOT_RDONLY

#define CONFIG_ROOT_RDONLY 1

#endif

! ld86 需要一个入口标识符,这和通常的相同;

.globl _main

_main:

#if 0 /* 调试程式的异常分支,除非BIOS古怪(比如老的HP机)否则是无害的 */

int 3

#endif

mov ax,#BOOTSEG !! 将ds段寄存器置为0x7C0;

mov ds,ax

mov ax,#INITSEG !! 将es段寄存器置为0x9000;

mov es,ax

mov cx,#256 !! 将cx计数器置为256(要移动256个字, 512字节);

sub si,si !! 源地址 ds:si=0x07C0:0x0000;

sub di,di !! 目的地址es:di=0x9000:0x0000;

cld !! 清方向标志;

rep !! 将这段程式从0x7C0:0(31k)移至0x9000:0(576k)处;

movsw !! 共256个字(512字节)(0x200长);

jmpi go,INITSEG !! 间接跳转至移动后的本程式go处;

! ax和es现在已含有INITSEG的值(0x9000);

文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!