04.實現讀取其他扇區資料顯示
簡介
上一節我們使用C語言實現了3.5寸虛擬軟盤檔案結構,作業系統檔案必須突破頭512位元組的限制,需要把資料寫入其他扇區,在頭512位元組中實現載入其他扇區檔案到記憶體。
目標
使用自制的C語言虛擬軟盤模組,把顯示的字串資料寫入1磁軌、0磁頭、2扇區,在核心載入器中讀取該扇區字串顯示在螢幕上。
1.BIOS:
BIOS是英文"Basic Input Output System"的縮略詞,直譯過來中文名稱就是"基本輸入輸出系統"。它是一組固化到計算機內主機板上一個ROM晶片上的程式,它儲存著計算機最重要的基本輸入輸出的程式、開機後自檢程式和系統自啟動程式,它可從CMOS中讀寫系統設定的具體資訊。 其主要功能是為計算機提供最底層的、最直接的硬體設定和控制。
使用匯編讀取軟盤我們要呼叫相應的BIOS中斷,將要讀取的磁頭號,柱面,扇區號傳給中斷程式碼,讀取軟盤的彙編程式碼如下:
mov ch, 1 ;CH 用來儲存柱面號
mov dh, 0 ;DH 用來儲存磁頭號
mov cl, 2 ;CL 用來儲存扇區號
es:bx暫存器作為讀取磁碟扇區資料的快取區
mov ah, 0x02 ; AH = 02 表示要做的是讀盤操作
mov al, 1 ; AL 表示要練習讀取幾個扇區
mov dl, 0 ;驅動器編號,一般我們只有一個軟盤驅動器,所以寫死
;為0
int 0x13 ;呼叫BIOS中斷實現磁碟讀取功能
jc error ; 如果讀盤出現錯誤,跳轉到error處執行相應
2.程式碼:
boot.s 彙編檔案
;能用於操作記憶體的暫存器只能是bx、bp、si、di ;0x7c00--0x7dff 這512位元組用於啟動區 ;對記憶體的訪問都必須指定段暫存器,沒有顯示指定時將使用ds作為段暫存器 org 0x7c00; mov ax,0 mov ss,ax mov ds,ax mov es,ax mov bx,msg ;es:bx 指向位置為磁碟讀取操作資料的資料快取區 mov si,msg mov ch,1 ;柱面號 mov dh,0 ;磁頭號 mov cl,2 ;扇區號 mov ah,0x02 ;0x02表示讀盤操作 mov al,1 ;表示連續讀取扇區數 mov dl,0 ;驅動器號,早期有多個軟碟機,一般只有一個寫死0 int 0x13 ;呼叫BIOS實現磁碟讀取 jc error ;讀盤操作失敗,flag標誌暫存器cf 標誌位被置1 putloop: mov al,[si] inc si cmp al,0 je fin mov ah,0x0e ;中斷呼叫引數 mov bx,15 ;字元顏色 int 0x10 ;中斷呼叫號 jmp putloop fin: hlt jmp fin error: mov si,errorMsg jmp putloop msg: resb 512 ;預留64個位元組資料 db 0 errorMsg: db 'error'
終端使用: nasm boot.s -o boot.bat
生成機器指令
main.c 實現虛擬軟盤扇區寫入,floppy.h、floppy.c 檔案見上一博文
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "floppy.h"
int main(int argc,char **argv){
FILE *fp = initFloppy("floppy.img");
if(fp == NULL) {
printf("初始化磁碟失敗");
exit(0);
}
FILE *src = fopen("boot.bat", "r");
if(src == NULL) {
printf("檔案開啟失敗");
exit(0);
}
char buf[512];
memset(buf, 0, 512);
fread(buf, 512, 1, src);
buf[510] = 0x55;
buf[511] = 0xaa;
writeFloppy(0, 0, 1, fp, buf);
memset(buf, 0, 512);
char *msg = "this message from other sector";
for(int i=0;i<strlen(msg);i++){
buf[i] = *(msg+i);
}
writeFloppy(1, 0, 2, fp, buf);
fclose(fp);
return 1;
}
編譯執行C檔案將生成floppy.img 虛擬磁碟,使用虛擬機器載入執行該檔案結果如下:
使用C語言寫入的字串資料成功顯示在螢幕上,我們的核心載入器成功載入指定扇區的資料!