02-使用BIOS中斷 顯示字元/讀取磁碟 【實現boot中載入loader的功能】

卡卡发發表於2024-07-19

bios提供了一組服務,可以幫助我們操縱硬體,避免我們直接與硬體細節打交道

當觸發軟中斷時,會自動從中斷向量表中取出想用的中斷程式的首地址,來執行中斷程式,引數透過暫存器傳遞



一、Bios的INT10中斷


  • INT10中斷是BIOS用於控制螢幕的關鍵介面,包括設定顯示器模式、游標管理和顯示特性等

    INT 0x10 是顯示類指令:

    INT 0x10, AH = 1 -- set up the cursor
    INT 0x10, AH = 3 -- 獲取游標位置
    INT 0x10,AH = 0xE -- 顯示字元
    INT 0x10, AH = 0xF -- get video page and mode
    INT 0x10, AH = 0x11 -- set 8x8 font
    INT 0x10, AH = 0x12 -- detect EGA/VGA
    INT 0x10, AH = 0x13 -- 顯示字串,具體暫存器設定可以參考:http://www.ctyme.com/intr/rb-0210.htm
    INT 0x10, AH = 0x1200 -- Alternate print screen
    INT 0x10, AH = 0x1201 -- turn off cursor emulation
    INT 0x10, AX = 0x4F00 -- video memory size
    INT 0x10, AX = 0x4F01 -- VESA get mode information call
    INT 0x10, AX = 0x4F02 -- select VESA video modes
    INT 0x10, AX = 0x4F0A -- VESA 2.0 protected mode interface

  • 在呼叫 BIOS 函式之前,需要先設定 AH 或 AX(或 EAX) 暫存器,然後執行對應的 INT 指令

  • AH=0xE 的功能是顯示字元,同時游標前移(暫存器值的設定:AL=字元,BL=在圖形模式下表示文字的顏色,BH=目前的顯示頁·在圖形模式下為0)



二、實操(顯示字元)


透過INT10中斷的AH中斷功能來在qemu顯示器上顯示字元,從而表明載入程式已經正常執行了(即把磁碟的第一個扇區512位元組的內容成功的載入到了記憶體中的0x7C00處)


接著編譯一下,再除錯,結果如下:



三、Bios的INT13中斷


bios提供了磁碟讀取介面,方便我們從磁碟載入loader


  • 先透過BIOS把boot程式的程式碼(也就是磁碟第0扇區的內容)載入到記憶體中,再透過執行boot程式來載入loader到記憶體中。

  • 目前loader還暫時未編寫,接下來先編寫boot模組中用來載入loader的程式碼

  • boot程式的功能是:載入磁碟上的從第1扇區開始到指定扇區結束的內容(也就是存放loader的幾個扇區)到記憶體中的指定的位置


  • INT 13H直接磁碟服務Direct Disk Service

    00H —磁碟系統復位
    01H —讀取磁碟系統狀態
    02H —讀扇區
    03H —寫扇區
    04H —檢驗扇區
    05H —格式化磁軌
    06H —格式化壞磁軌
    07H —格式化驅動器
    08H —讀取驅動器引數
    09H —初始化硬碟引數
    0AH —讀長扇區
    0BH —寫長扇區
    0CH —查尋
    0DH —硬碟系統復位
    0EH —讀扇區緩衝區
    0FH —寫扇區緩衝區
    10H —讀取驅動器狀態
    11H —校準驅動器
    12H —控制器RAM診斷
    13H —控制器驅動診斷
    14H —控制器內部診斷
    15H —讀取磁碟型別
    16H —讀取磁碟變化狀態
    17H —設定磁碟型別
    18H —設定格式化媒體型別
    19H —磁頭保護
    1AH —格式化ESDI驅動器



  • 02H 功能:讀扇區

    入口引數:AH=02H
    出口引數:CF=0——操作成功,AH=00H,AL=傳輸的扇區數,否則,AH=狀態程式碼,參見功能號01H中的說明

    暫存器值的設定:
    AL=扇區數
    CH=柱面 (填0)
    CL=扇區 (填1,表示從第1個扇區開始讀取)
    DH=磁頭 (填0)
    DL=驅動器,00H7FH:軟盤;80H0FFH:硬碟 (填0x80,表示硬碟)
    ES:BX=緩衝區的地址 (段地址+一個偏移的形式)(前面的_start程式碼裡面已經將es暫存器設為0了,e而BX暫存器是存放如上圖所示的記憶體的0x8000這個地址)


四、實操(磁碟讀取)


接著編譯一下。編譯後,用16進位制方式開啟磁碟映像檔案,定位到第一個扇區:

簡單的修改一下用來測試:

除錯後,接著在除錯控制檯(是與GDB互動的一個介面)輸入一些命令來檢視測試結果:

-exec x /20xb 0x8000 檢視記憶體中0x8000地址開始的20個位元組,20xb中的x意思是用16進製表示

(上面的除錯過程試了好幾次才成功,之前提示無法進行下一步,這次等的時間長一點成功了,可能是讀寫磁碟比較慢所以需要等待一段時間?也可能是其他原因,暫時沒有搞明白具體原因。)





相關文章