Try   HackMD

Chapter 3:增強 MBR

這是讀書筆記

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

作者:鄭鋼
出版社:佳魁資訊股份有限公司
出版日期:2017/05/31


這邊討論都是 x86 架構下的組合語言,組譯工具是 nasm
如果是 ARM 架構下的組合語言,組譯工具是 armasm

位址、section、vstart

  • 編譯器的主要工作就是給各種符號編址。
  • CPU 無法判斷是指令還是一般資料。
  • 組合語言裡面的 section 僅是在邏輯上方便程式開發人員整理程式用。
  • vstart 是虛擬的起始位址,loader 應該要根據其位址載入到記憶體相對應位址。

CPU 的真實模式

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

參考資料:CPU Registers x86

  • CPU 分成三個部分:控制單元、運算單元、儲存單元。

  • CPU 定址模式:

    • 暫存器定址:存取暫存器
    • 立即數定址:常數
    • 記憶體定址:存取記憶體。
  • 真實模式下的 ret/retf。

  • 真實模式下的 call。

    • Near call
    • Far call
  • 真實模式下的 jmp。

    • jmp short
    • jmp near
    • jmp far
  • 標示暫存器 flags。

    Image Not Showing Possible Reasons
    • The image was uploaded to a note which you don't have access to
    • The note which the image was originally uploaded to has been deleted
    Learn More →

  • Conditional Jumps

    Image Not Showing Possible Reasons
    • The image was uploaded to a note which you don't have access to
    • The note which the image was originally uploaded to has been deleted
    Learn More →

顯示器

x86 I/O 通訊

  • Intel x86 的 I/O 是使用 PMI/O。

ARM 通常使用 MMI/O。

顯示卡、顯示記憶體、顯示器

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

改寫 MBR,直接操作顯示卡

Source Code

;主引導程序 ; ;LOADER_BASE_ADDR equ 0xA000 ;LOADER_START_SECTOR equ 0x2 ;------------------------------------------------------------ SECTION MBR vstart=0x7c00 mov ax,cs mov ds,ax mov es,ax mov ss,ax mov fs,ax mov sp,0x7c00 mov ax,0xb800 mov gs,ax ; 清屏 ;利用0x06號功能,上卷全部行,則可清屏。 ; ----------------------------------------------------------- ;INT 0x10 功能號:0x06 功能描述:上卷窗口 ;------------------------------------------------------ ;輸入: ;AH 功能號= 0x06 ;AL = 上卷的行數(如果為0,表示全部) ;BH = 上卷行屬性 ;(CL,CH) = 窗口左上角的(X,Y)位置 ;(DL,DH) = 窗口右下角的(X,Y)位置 ;無返回值: mov ax, 0600h mov bx, 0700h mov cx, 0 ; 左上角: (0, 0) mov dx, 184fh ; 右下角: (80,25), ; 因為VGA文本模式中,一行只能容納80個字符,共25行。 ; 下標從0開始,所以0x18=24,0x4f=79 int 10h ; int 10h ; 輸出背景色綠色,前景色紅色,並且跳動的字符串"1 MBR" mov byte [gs:0x00],'1' mov byte [gs:0x01],0xA4 ; A表示綠色背景閃爍,4表示前景色為紅色 mov byte [gs:0x02],' ' mov byte [gs:0x03],0xA4 mov byte [gs:0x04],'M' mov byte [gs:0x05],0xA4 mov byte [gs:0x06],'B' mov byte [gs:0x07],0xA4 mov byte [gs:0x08],'R' mov byte [gs:0x09],0xA4 jmp $ ; 通過死循環使程序懸停在此 times 510-($-$$) db 0 db 0x55,0xaa

Compile

nasm -o mbr.bin mbr.S

Hard Disk Image

dd if=../code/mbr.bin of=./sr_hd60m.img bs=512 count=1 conv=notrunc

Result

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

bochs 偵錯方法

./bochs -debugger

查看 help 資訊

截圖 2025-04-12 晚上11.48.55

查看 BIOS 的入口點:0xFFFF0

截圖 2025-04-12 晚上11.57.51

反組譯機器碼

截圖 2025-04-13 凌晨12.01.19

查看 MBR 的入口點:0x7c00

一開始是沒有值,BIOS 負責把 MBR 從硬碟載到 0x7c00

順便可以看看 BIOS 吐出來的資訊,而游標的位置就是上一章的範例,MBR 印出字元的位置。

截圖 2025-04-13 凌晨12.42.10

硬碟介紹

一些歷史和原理介紹我就不贅述了。

如何操控硬碟

參考資料:Bochs' map of I/O ports to functions

0x1F7 / 0x177 Status Register for read.

截圖 2025-04-13 凌晨4.17.31

資料傳送方式

  • CPU 直接取資料:registers, memory.
  • Polling
  • Interrupt
  • DMA (硬體需支援)
  • I/O處理器 (硬體需支援)

MBR 載入 Loader

載入硬碟資料

Source Code

boot.inc

;------------- loader和kernel ---------- LOADER_BASE_ADDR equ 0x900 LOADER_START_SECTOR equ 0x2

mbr.S

;主引導程序 ;------------------------------------------------------------ %include "boot.inc" SECTION MBR vstart=0x7c00 mov ax,cs mov ds,ax mov es,ax mov ss,ax mov fs,ax mov sp,0x7c00 mov ax,0xb800 mov gs,ax ; 清屏 ;利用0x06號功能,上卷全部行,則可清屏。 ; ----------------------------------------------------------- ;INT 0x10 功能號:0x06 功能描述:上卷窗口 ;------------------------------------------------------ ;輸入: ;AH 功能號= 0x06 ;AL = 上卷的行數(如果為0,表示全部) ;BH = 上卷行屬性 ;(CL,CH) = 窗口左上角的(X,Y)位置 ;(DL,DH) = 窗口右下角的(X,Y)位置 ;無返回值: mov ax, 0600h mov bx, 0700h mov cx, 0 ; 左上角: (0, 0) mov dx, 184fh ; 右下角: (80,25), ; 因為VGA文本模式中,一行只能容納80個字符,共25行。 ; 下標從0開始,所以0x18=24,0x4f=79 int 10h ; int 10h ; 輸出字符串:MBR mov byte [gs:0x00],'1' mov byte [gs:0x01],0xA4 mov byte [gs:0x02],' ' mov byte [gs:0x03],0xA4 mov byte [gs:0x04],'M' mov byte [gs:0x05],0xA4 ;A表示綠色背景閃爍,4表示前景色為紅色 mov byte [gs:0x06],'B' mov byte [gs:0x07],0xA4 mov byte [gs:0x08],'R' mov byte [gs:0x09],0xA4 mov eax,LOADER_START_SECTOR ; 起始扇區lba地址 mov bx,LOADER_BASE_ADDR ; 寫入的地址 mov cx,1 ; 待讀入的扇區數 call rd_disk_m_16 ; 以下讀取程序的起始部分(一個扇區) jmp LOADER_BASE_ADDR ;------------------------------------------------------------------------------- ;功能:讀取硬盤n個扇區 rd_disk_m_16: ;------------------------------------------------------------------------------- ; eax=LBA扇區號 ; ebx=將數據寫入的內存地址 ; ecx=讀入的扇區數 mov esi,eax ;備份eax mov di,cx ;備份cx ;讀寫硬盤: ;第1步:設置要讀取的扇區數 mov dx,0x1f2 mov al,cl out dx,al ;讀取的扇區數 mov eax,esi ;恢覆ax ;第2步:將LBA地址存入0x1f3 ~ 0x1f6 ;LBA地址7~0位寫入端口0x1f3 mov dx,0x1f3 out dx,al ;LBA地址15~8位寫入端口0x1f4 mov cl,8 shr eax,cl mov dx,0x1f4 out dx,al ;LBA地址23~16位寫入端口0x1f5 shr eax,cl mov dx,0x1f5 out dx,al shr eax,cl and al,0x0f ;lba第24~27位 or al,0xe0 ; 設置74位為1110,表示lba模式 mov dx,0x1f6 out dx,al ;第3步:向0x1f7端口寫入讀命令,0x20 mov dx,0x1f7 mov al,0x20 out dx,al ;第4步:檢測硬盤狀態 .not_ready: ;同一端口,寫時表示寫入命令字,讀時表示讀入硬盤狀態 nop in al,dx and al,0x88 ;第4位為1表示硬盤控制器已準備好數據傳輸,第7位為1表示硬盤忙 cmp al,0x08 jnz .not_ready ;若未準備好,繼續等。 ;第5步:從0x1f0端口讀數據 mov ax, di mov dx, 256 mul dx mov cx, ax ; di為要讀取的扇區數,一個扇區有512字節,每次讀入一個字, ; 共需di*512/2次,所以di*256 mov dx, 0x1f0 .go_on_read: in ax,dx mov [bx],ax add bx,2 loop .go_on_read ret times 510-($-$$) db 0 db 0x55,0xaa

Compile

nasm -I inc/ -o mbr.bin mbr.S

Hard Disk Image

dd if=../code/mbr.bin of=./sr_hd60m.img bs=512 count=1 conv=notrunc

準備一個簡單的 Loader

Source Code

loader.S

%include "boot.inc" section loader vstart=LOADER_BASE_ADDR ; 輸出背景色綠色,前景色紅色,並且跳動的字符串"1 MBR" mov byte [gs:0x20],'2' mov byte [gs:0x21],0xA4 ; A表示綠色背景閃爍,4表示前景色為紅色 mov byte [gs:0x22],' ' mov byte [gs:0x23],0xA4 mov byte [gs:0x24],'L' mov byte [gs:0x25],0xA4 mov byte [gs:0x26],'O' mov byte [gs:0x27],0xA4 mov byte [gs:0x28],'A' mov byte [gs:0x29],0xA4 mov byte [gs:0x2a],'D' mov byte [gs:0x2b],0xA4 mov byte [gs:0x2c],'E' mov byte [gs:0x2d],0xA4 mov byte [gs:0x2e],'R' mov byte [gs:0x2f],0xA4 jmp $ ; 通過死循環使程序懸停在此

Compile

nasm -I inc/ -o loader.bin loader.S

Hard Disk Image

dd if=../code/loader.bin of=./sr_hd60m.img bs=512 count=1 seek=2 conv=notrunc

Result

截圖 2025-04-13 晚上11.32.55