操作系统的第一个程序 - MBR程序

MBR程序必须是操作系统运行的第一个程序吗?

正常运行的操作系统,MBR程序确实是第一个运行的程序。但是在开发操作系统的时候,MBR程序却是可以不需要的,完全可以在另一个操作系统启动自己操作系统来调试。其实EFI启动就是在一个操作系统里启动另一个操作系统,难道你还想自己写EFI?

为了照顾那些认定开发操作系统就必须先开发MBR程序的人,也就只能先说MBR程序了。

MBR程序要干些什么事情

我认为,是的,就仅仅是我认为,因为我没找到明确的规范说MBR应该干什么。我认为MBR仅仅是提供了让你接管CPU的方法,至于接管CPU后,你能干什么,那就是你自己的事情了。

MBR程序要做的事情一般是:找到活动分区,然后读入活动分区的首扇区,就把这个扇区称为活动分区的启动扇区吧,然后执行活动分区的启动扇区的代码。

常规的流程是POST之后,BIOS就会把MBR读入内存,然后跳转到这个地方开始执行,就是俗称的启动程序

MBR程序涉及的问题

MBR程序因为可用的空间很小,最多就446个字节,稍微不注意就超了,

内存分配的问题

要记得,这个时候是没有人帮你管理内存的,只能自己管理设置。比如,BIOS把MBR读到了0000:7C00处 ,但是,你知道这个时候栈在哪里吗?还有,活动分区的启动扇区你要读到什么位置?这些问题都要自己处理的,

这个就要求你知道POST之后的内存布局了,或者说PC典型的内存布局。一般的安排是这个样子

地址范围(32位表示)用途
0x00000000 - 0x000003FF实模式中断向量表
0x00000400 - 0x000005FFBIOS数据区
0x00000600 - 0x00007BFF可用区域
0x00007C00 - 0x00007DFFMBR扇区,启动过后可用
0x00007E00 - 0x0009FFFF可用区域,总共640K,这也是DOS可用内存是640K的原因
0x000A0000 - 0x000B7FFF图形显示模式的显存
0x000B8000 - 0x000BFFFF字符显示模式的显存
0x000C0000 - 0x000EF7FF各种设备的ROM
0x000EF800 - 未知其实是我不知道

MBR为什么会装到7C00这个位置

真正的可用内存地址是从600开始,但为什么BIOS会把MBR读到7C00这个位置呢?不能直接读到600吗?后面就可以连续起来了。毕竟windows的MBR程序就把自己从7C1B复制到61B了,也就是说明其实可以到这个位置的。

其实吧,这是因为要向前兼容,因为早期的DOS用了这个位置作为MBR程序空间,以及紧接着的512个字节作为数据空间,然后就一直保留下来了。有兴趣的可以在网上搜搜这个这个历史,

活动分区的启动扇区又该放到哪里

如果只是测试的话,在640K以内随便找个地方就行,但是为了方便后面程序的载入,还是需要优化一下的。

我是根据我的需要啊。
我不用考虑什么向前兼容,所以MBR我就不换地方了,就让他在7C00那里呆着。然后活动分区的启动扇区就读到600处。另外我还在活动分区的保留扇区中用了8K的空间,这个地方的数据我安排在90000处,用表格来看是这样的

地址范围用途
00600 - 03FFF活动分区的启动扇区
07C00 - 07DFFMBR扇区
08100 - 17FFF16位装载程序,64K的空间,完成基本设置和文件装载,足够了
20000 - 8FFFF32位装载程序,这个地方给的很大,足够干很多事情了
90000 - 97FFF活动分区的装载程序,分配了32K

为什么需要一个额外的8K空间呢?
是因为我的编程水平不够,没办法在412个字节的程序里,完成在分区里查找文件,还要把文件读到内存里,只好另外找了一个空间来放这个功能的程序。方便定位的,也就保留扇区了,如果有其他程序用到保留扇区,那结果自然就是凉了。

检测INT 13H的版本

检测INT 13H的版本不能缺,我虽然只用INT 13H的扩展功能,但不能保证某个人拿个20、30年前的老电脑来试试,BIOS没有INT 13H扩展功能,也许还真的就出现问题了。

我的MBR程序

注释基本是我的中国式英语,如果看不懂,那就看不懂吧,等我能写出靠谱的英文在说了。代码的中文解释放在书里,这里就不写了。

这个程序编译出来,257个字节,如果发现有遗漏的地方,还有增加一些代码的空间

程序代码

我觉个肯定会有人纠结为什么一定要0000:7C00,弄成07B0:0100,不也是一样吗?这样还方便在DOS下调试。好吧,确实可以,不过我是放在书里解释这个问题了。

;
;==============================================================================
;                                    ROBIX
;         Robin's Operating System. Order Source Studio @ 2011 - 2019
;                             ALL RIGHTS RESERVED
;                     ***------------------------------***
;Name   : mbr.asm
;Create : 2017-05-26. robin
;Purpose: this asm program is MBR booter. should be complied to COM format 
;       executable file with 16-BIT asm complier. this program would be written
;       to MBR.
;        it read active parition boot sector to 0000:0600, and jmp to that 
;       address
;==============================================================================
;
.386p
.model tiny

DAP             STRUC
DAPSIZE         DB      0;
Rsvd            DB      0;
Count           DW      0;
Buf             DD      0;
SectL32         DD      0;
SectH32         DD      0;
DAP             ENDS

; if found the active partition, booter will save the active partition start
; sector at 0000:03F8, 8 bytes, the active partition booter can use this
TEXT   SEGMENT  USE16 PUBLIC 'CODE'
 assume cs:TEXT,ds:TEXT
    org 07C00h
start:
    ;cli
    mov     ax, cs
    mov     ds, ax
    mov     es, ax
    mov     ss, ax
    mov     sp, 07BF8h

; MBR need to use extend INT 13h, so check it
    mov     ah, 041h
    mov     bx, 055AAh
    mov     dl, 080h
    int     013h
    cmp     bx, 0aa55h
    jnz     failed;
; search active partition
; dx: contain the active partition number
; di: contain the active item pointer
    mov     cx, 4
    mov     si, 07DBEh
    xor     di, di
    xor     dx, dx
serach_active_part:
    cmp     byte ptr [si],080h
    jne     next_item
    inc     dx
    cmp     di, 0
    jnz     next_item
    mov     di, si
 next_item:
    add     si,16
    loop    serach_active_part

; the active partition must be 1, if not, boot failed
    cmp     dx, 1
    je      found_active_part
    int     018h  ; this is not the ROM BASIC, it is boot failed
found_active_part:
; if the partition is extend partition, boot failed
    cmp     byte ptr [di + 4], 05h
    je      failed
    cmp     byte ptr [di + 4], 0Fh
    je      failed
    
    mov     cx, 3
read_active_part:
    push    di
    push    cx
    mov     bx,03F8h
    xor     si,si
    
; read active partition boot sector to 0000:0600
; save the active partition start sector at 0000:03F8, 8 bytes
    mov     ax,[di + 8]
    mov     dx,[di + 10]

    mov     [bx    ], ax    ; save the active partition start sector to 3F8,
    mov     [bx + 2], dX    ; 8 byte
    mov     [bx + 4], si    ; 
    mov     [bx + 6], si    ;

    push    si              ; construct DAP
    push    si              ; dap.SectH32 = 0
    push    dx
    push    ax              ; dap.SectL32 = start sector
    push    si            
    push    0600h           ; dap.Buf = 0000:0600
    push    1               ; dap.Count = 1
    push    010h            ; dap.DAPSIZE = 16
                            
    mov     si, sp
    mov     ah, 042h
    mov     dl, 080h
    int     013h
    popa
    jnc     run_active_part
    pop     cx
    test    cx, cx
    jz      failed          ; retry 3 times failed, terminated
    dec     cx
    push    cx
    xor     ah, ah          ; if reading failed, reset disk, and try again
    mov     dl, 080h
    int     013h
    pop     cx
    pop     di
    jmp     read_active_part

; run the active partition boot sector, JMP 0000:0600
run_active_part:
    DB      0EAh
    DW      00600h
    DW      00000h

failed:
    sti
    push    cs
    pop     es
    
    mov     ah,03h
    xor     bh,bh
    int     010H
    lea     ax,errmsg
    mov     bp,ax
    mov     bx,0Fh
    mov     cx,65
    mov     ax,01301h
    int     010h
    xor     ax,ax
    int     016h
    cmp     al,'r'
    je      reboot
    cmp     al,'R'
    je      reboot
    jmp     failed
reboot:
    ; jmp FFFF:0000
    DB      0EAh
    DW      0
    DW      0FFFFh
align qword
    ; err message
    errmsg  DB "PARTITION TABLE INVALID OR DISK IO ERROR, PRESS 'R' TO REBOOT",
                0Dh,0Ah,0dh,0ah
TEXT ENDS
    end start
    

编译

这是一个批处理代码,把文件编译成COM格式的文件。这里只不过把文件命名为MBR.BIN,实际还是COM格式

@ECHO off
echo ==========================================================================
echo          this file is used to create MBR.BIN under windows
echo  [NOTE] it need MASM32 v11 or early, because the later version do not 
echo         support TINY mode. 
echo         if failed, maybe the command path is wrong.
echo ==========================================================================

ml /AT /omf MBR.ASM
link16 /TINY MBR.OBJ, MBR.BIN, nul, nul, nul
@ECHO on

编译结果

放一个编译的结果,链接给出了一个警告,没办法,因为设定的地址是7C00,
MBR编译结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值