国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 操作系統 > 正文

x01.os.18: MBR

2024-06-28 13:22:48
字體:
來源:轉載
供稿:網友
x01.os.18: MBR

硬盤不同于軟盤,它是要分區的。這時,mbr(master boot record)便不可少了。安裝 os 硬盤的第一扇區,開始有一小段不多于 446 字節的程序,然后是分區表 512-446-2 字節,然后是引導標志 0xAA55 兩字節。這一小段程序,便是 mbr 的主體。mbr 首先將其自身復制到 0x0600 處,代碼如下:

; 0x7C00 => 0x0600    mov        si, sp    push       si    mov        di, 0x0600    mov        cx, 0x200    cld    rep        movsw    

這是要給分區的引導代碼騰位置。操作系統的引導代碼,可能位于軟盤,光盤等 Media 中,其代碼首先便是 org 0x7C00,所以 mbr 復制自身進行重定位,就必不可少了。

第二步,當然就是尋找活動分區的啟動代碼了。有這么一句:test dl, dl。這個 dl 的值,便是 drive number, 由 bios 的 int 0x19 取得。通過 dl 判斷設備的類型,作不同的選擇。mbr.s 的內容如下:

; ----------------------; mbr.s (c) 2014 by x01; ----------------------P_EntrySize        equ        16        ; 分區表每項為 16 字節P_PartOffset    equ        0x1BE     ; 分區表在引導扇區的偏移位置P_BootOffset    equ        0        ; 分區項中引導標志的偏移位置P_TypeOffset    equ        4        ; 分區項中分區類型的偏移位置P_LbaOffset        equ        8        ; 分區項中起始扇區 LBA 的偏移位置; Partition table struct; ----------------------; offset    len                    description;   0         1            狀態(80h=可引導,00h=不可引導,其他不合法);    1         1            起始磁頭號;    2         1            起始扇區號(僅用了低 6 位,高 2 位為起始柱面號的第 8-9 位;    3         1            起始柱面號的低 8 位;    4         1            分區類型(System ID);    5         1            結束磁頭號;    6         1            結束扇區號(僅用了低 6 位,高 2 位為結束柱面號的第 8-9 位;    7         1            結束柱面號的低 8 位;    8         4            起始扇區的 LBA;    12         4            扇區數目boot:    xor        ax, ax    mov        ds, ax    mov        es, ax    cli    mov        ss, ax        ; ds = es = ss = 0, 段偏移地址直接映射為物理地址    mov        sp, 0x7C00    sti    ; 0x7C00 => 0x0600    mov        si, sp    push    si    mov        di, 0x0600    mov        cx, 0x200    cld    rep        movsw    jmp        0:0x0600 + activeactive:    test    dl, dl        ; BIOS int 19h => dl = drive_nr                        ; SF <- MSB(dl): most significact bit, 1 is -, 0 is +    jns        nextdisk    mov        si, 0x0600 + P_PartOffset    find:    cmp        byte [si + P_TypeOffset], 0        ; if not equal 0 then can use    jz        nextpart    test    byte [si + P_BootOffset], 0x80    ; 0x80: bootable    jz        nextpartloadpart:    call    load    jc        error    ret                ; goto secondary boot => 0x0000:0x7C00    nextpart:    add        si, P_EntrySize    cmp        si, 0x0600 + P_PartOffset + 4 * P_EntrySize    jb        find        call    PRint    db        "No active partition/0"    jmp        reboot    nextdisk:    inc        dl    test    dl, dl    js        nexthd    int        0x11        ; get active drive info    shl        ax, 2        ; floppy info at al[6-7], but after shl at ah[0-1]    and     ah, 3    cmp        dl, ah        ; dl <= ah then floppy exist    ja        nextdisk    call    loadfloppy    jc        nextdisk    ret    nexthd:    call    loadfloppyerror:    jc        handle_err    ret; load floppy 0 sectorloadfloppy:    mov        si, 0x0600 + zero - P_LbaOffset    ; load hd bootload:    mov        di, 3    retry:    push    dx    ; dl = old drive_nr protect        push    es    push    di        ; Get disk info(int 0x13: ah=0x8)    ; ch: cyl low 8 bit, cl[6-7]: cyl high 2 bit    ; cl[0-5]: sectors per track    ; dh: heads, dl: drive_nr    mov        ah, 0x08    int        0x13        pop        di    pop        es        and        cl, 0x3F    ; sectors base 1    inc        dh            ; heads base 0, so inc        mov        al, cl        ; al = cl = sectors per track    mul        dh            ; ax = cyl sectors = heads * sectors_per_track    mov        bx, ax        mov        ax, Word [si + P_LbaOffset + 0]    mov        dx, word [si + P_LbaOffset + 2]    ; dx:ax = secondary boot offset        cmp        dx, (0x16390 * 0xFF * 0x3F - 0xFF) >> 0x10    jae        bigdisk        div        bx        ; /: ax is cyl_nr, mod: dx is cyl_offset    xchg    ax, dx    mov        ch, dl    ; ch is cyl_nr low 8 bit        div        cl        ; /: al is head_nr, mod: ah is track offset(base 0)    xor        dl, dl    shr        dx, 2    ; dl[6-7] = cyl_nr high 2 bit    or        dl, ah    ; dl low 5 bit store track offset    mov        cl, dl    ; cl high 2 bit is cyl high 2 bit, cl low 5 bit is track offset    inc        cl        ; base 1    pop        dx        ; old drive_nr    mov        dh, al    ; head_nr => dh    mov        bx, 0x7C00    ; es:bx is load addr    mov        ax, 0x0201    ; read disk sector entry_point parameter    int        0x13        ; read 1 sector to es:bx    jmp        read_check    bigdisk:    mov        bx, dx    pop        dx    push    si    mov        si, 0x0600 + dap_offset    ; dap: disk addr packet, for up 8G    mov        word [si + 8], ax        ; low     mov        word [si + 0xA], bx        ; high    mov        ah, 0x42                ; extend read parameter    int        0x13    pop        si    read_check:    jnc        read_ok    cmp        ah, 0x80    ; timeout    je        read_bad    dec        di    jl        read_bad    xor        ah, ah    int        0x13    jnc        retry    read_bad:    stc    ret        ; have a bug, need clear zero    read_ok:    cmp        dword [0x7C00 + 510], 0xAA55    jne        notboot    ret    notboot:    call    print    db        "Not bootable/0"    jmp        reboot    handle_err:    mov        si, 0x7C00 + err_nr + 1        ; err_nr low bit    print_num:    mov        al, ah    ; ah: int 0x13 error code    and        al, 0x0F    cmp        al, 0xA    jb        digit    add        al, 0x7    digit:    add        byte [si], al    ; err_nr low bit is '0', after add is correct number    dec        si                ; err_nr high bit    mov        cl, 4    shr        ah, cl    jnz        print_num    call    print    db        "Read error"    err_nr:    db        "00/0"    reboot:    call     print    db        "Hit any key reboot./0"    xor        ah, ah    int        0x16    ; wait key    call    print    db        "/r/n/0"    int        0x19    ; reboot    print:    pop        si        ; ip => get string addrprint_next:    lodsb            ; al = *si++    test    al, al    jz        print_done    mov        ah, 0x0E    mov        bx, 0x0001    int        0x10    jmp        print_next    print_done:    jmp        si    dap_offset:    PacketSize        db    0x10    Reserved        db    0x0    BlockCount        dw    0x1    BufferOffset    dw    0x7C00    BufferSegment    dw    0x0    BlockNumLow        dd    0x0zero:    BlockNumHigh    dd    0x0    times 510-($-$$)     db    0BootFlag            dw    0xAA55                                                                        
View Code

后面加了兩句引導標志,是為了快速檢驗一下運行效果,實際是不需要的。minix 通過 installboot 程序來完成組裝與添加。檢驗方法如下:

1.編譯: nasm -o mbr mbr.s

2.寫入硬盤:dd if=mbr of=c.img bs=512 count=1 conv=notrunc

其中,c.img 是硬盤映像。配置 bochs 后運行,可看到因找不到活動分區而停止。當然,這又是另一個問題,就不多說了。


上一篇:rpm軟件包

下一篇:x01.os.17: 換心術

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 含山县| 贵德县| 丹江口市| 慈利县| 高安市| 枣强县| 桑植县| 隆尧县| 荆门市| 嵊州市| 潮州市| 南涧| 铜陵市| 晋中市| 德阳市| 翁牛特旗| 永宁县| 桦南县| 铅山县| 蒲城县| 益阳市| 凉山| 电白县| 游戏| 洛扎县| 杨浦区| 桃江县| 古丈县| 临夏县| 唐海县| 抚州市| 宝鸡市| 文山县| 凤翔县| 永春县| 图片| 微博| 宁安市| 聊城市| 遵义县| 宁陕县|