linux 0.11内核源码(1)之开机启动过程

1.开机

        当我们按下电脑开机键的时候,BIOS程序会充当搬运工的身份,将磁盘0盘0道1扇区(启动区)的代码原封不动的搬运到内存的0x07c0的位置,然后CPU就开始从0x07c0的位置不停机的运行着,具体运行什么内容,我们后面慢慢分析。

1.1什么是启动区

启动区:只要磁盘0盘0道1扇区的结尾的两个字节分别是0x55和0xaa,BIOS即可认为该扇区是启动区。

2.磁盘0盘0道1扇区的代码是什么

磁盘0盘0道1扇区的代码是位于boot文件夹下面的bootsect.s的二进制文件                

3.bootsect.s代码讲解

mov ax,0x07c0

mov ds,ax

设置段寄存器的值,因为汇编限制,ds这些寄存器不可以直接赋值,我们需要通过ax寄存器进行赋值,ds是段寄存器,设置好了段寄存器,我们写地址的时候可以直接写偏移地址即可,不需要加段地址了,可以省很多重复性工作。

   mov    ax,BYTE PTR INITSEG        ;// 将es段寄存器置为9000h
    mov    es,ax
    mov    cx,256            ;// 移动计数值 = 256字 = 512 字节
    sub    si,si            ;// 源地址   ds:si = 07C0h:0000h
    sub    di,di            ;// 目的地址 es:di = 9000h:0000h
    rep movsw            ;// 重复执行,直到cx = 0;移动1个字

这段代码的意思就是将内存地址0x7c00处的代码移动512字节,也就是复制到0x90000处。

;    jmp INITSEG:[go]     ;// 间接跳转。这里INITSEG指出跳转到的段地址。
    db 0eah                ;// 间接跳转指令码
    dw go
    dw INITSEG
go:    mov    ax,cs            ;// 将ds、es和ss都置成移动后代码所在的段处(9000h)。
    mov    ds,ax            ;// 由于程序中有堆栈操作(push,pop,call),因此必须设置堆栈。
    mov    es,ax 

    mov    ss,ax
    mov    sp,0FF00h        ;/* 由于代码段移动过了,所以要重新设置堆栈段的位置。
                        ;   sp只要指向远大于512偏移(即地址90200h)处
                        ;   都可以。因为从90200h地址开始处还要放置setup程序,
                        ;   而此时setup程序大约为4个扇区,因此sp要指向大
                        ;   于(200h + 200h*4 + 堆栈大小)处。 */
 

go是一个标签,经过编译之后,会生成一个偏移地址。这段代码的意思就是跳转到go标签去执行程序。 这段代码就是一些准备工作,准备加载setup模块的代码数据。

load_setup:
    ;// 以下10行的用途是利用BIOS中断INT 13h将setup模块从磁盘第2个扇区
    ;// 开始读到90200h开始处,共读4个扇区。如果读出错,则复位驱动器,并
    ;// 重试,没有退路。
    ;// INT 13h 的使用方法如下:
    ;// ah = 02h - 读磁盘扇区到内存;al = 需要读出的扇区数量;
    ;// ch = 磁道(柱面)号的低8位;  cl = 开始扇区(0-5位),磁道号高2位(6-7);
    ;// dh = 磁头号;                  dl = 驱动器号(如果是硬盘则要置为7);
    ;// es:bx ->指向数据缓冲区;  如果出错则CF标志置位。 
    mov    dx,0000h                ;// drive 0, head 0
    mov    cx,0002h                ;// sector 2, track 0
    mov    bx,0200h                ;// address = 512, in INITSEG
    mov    ax,0200h+SETUPLEN        ;// service 2, nr of sectors
    int    13h                    ;// read it
    jnc    ok_load_setup            ;// ok - continue
    mov    dx,0000h
    mov    ax,0000h                ;// reset the diskette
    int    13h
    jmp    load_setup

ok_load_setup:

int 指令就是汇编指令里面的中断指令,根据中断号去中断描述符表里面找到段选择子和偏移地址 .

段选择子去全局描述符表找到段描述符,根据现在的段描述符和偏移地址就可以去找到程序入口地址,然后去执行。0x13是BIOS提取给我们写好的中断程序,是读取磁盘相关的函数。

 这些代码,用途是利用BIOS中断INT 13h将setup模块从磁盘第2个扇区开始的数据,加载到内存0x90200处,共加载4个扇区(1-5扇区)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值