久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

30天自制操作系統(tǒng)day03如何用C來代替匯編寫操作系統(tǒng)(BIOS里面已經(jīng)固化了一段代碼它會(huì)把啟動(dòng)區(qū)的第一扇區(qū)的512字節(jié)的內(nèi)容復(fù)制到內(nèi)存的0x7c00的這個(gè)位置)

 山峰云繞 2022-03-19

https://m.toutiao.com/is/ND4LmFm/?=30天自制操作系統(tǒng)day03 


   (BIOS里面已經(jīng)固化了一段代碼它會(huì)把啟動(dòng)區(qū)的第一扇區(qū)的512字節(jié)的內(nèi)容復(fù)制到內(nèi)存的0x7c00的這個(gè)位置)



第一天直接寫了一個(gè)“操作系統(tǒng)”的二進(jìn)制文件,詳細(xì)在:
https://www.toutiao.com/a7003704649312141836

由于寫二進(jìn)制文件很不方便,,也太繁瑣,,所以我們使用了編譯器,編譯器可以將匯編語(yǔ)言編譯成二進(jìn)制的機(jī)器碼,,以后就直接寫匯編,,然后用編譯器把我們寫的匯編生成二進(jìn)制文件就行了。這就大大提高了人的編程效率,。

所以,,第二天我們用匯編語(yǔ)言來重寫了“操作系統(tǒng)”。

第二天我們用匯編語(yǔ)言寫的”操作系統(tǒng)“,,詳細(xì)在:
https://www.toutiao.com/a7005537960355512839

但是,,用匯編語(yǔ)言來寫操作系統(tǒng),效率還是太慢,。為了提升寫操作系統(tǒng)的效率,,我們?cè)诘?3天,改匯編為C語(yǔ)言來寫操作系統(tǒng),。本節(jié)程序代碼地址為:
https:///-/ide/project/mingminglaoshi/MakeComputerOperateSystemin30Days/edit/master/-/projects/03_day/harib00j/bootpack.c

由于C語(yǔ)言出現(xiàn)在計(jì)算機(jī)已經(jīng)發(fā)展積累了一段時(shí)間一后,,所以,要使用C來寫操作系統(tǒng),,需要與匯編語(yǔ)言配合做一些鋪墊工作,。具體做哪些鋪墊工作呢?外圍硬件的初始化,,以及CPU芯片內(nèi)部寄存器的初始化,。

要了解得更詳細(xì),需要了解一下前置知識(shí):

操作系統(tǒng)前,計(jì)算機(jī)做的事情

主要看上面的第3條:

BIOS 里面有一段寫死的代碼,,會(huì)幫我們把啟動(dòng)區(qū)的第一扇區(qū)的 512 字節(jié)的內(nèi)容,,原封不動(dòng)復(fù)制到內(nèi)存里 0x7c00 這個(gè)位置,并跳轉(zhuǎn)到此處,,這個(gè)是不用我們管的,。

更詳細(xì)可以參考:
https://blog.csdn.net/sinat_34560749/article/details/104060723

也就是說,BIOS里面已經(jīng)固化了一段代碼,,它會(huì)把磁盤上的512字節(jié)的內(nèi)容復(fù)制到內(nèi)存的0x7c00的這個(gè)位置,。注意到,它只復(fù)制512字節(jié),。

那么準(zhǔn)備用C來寫操作系統(tǒng)的話,,512字節(jié)不夠用了,因?yàn)樗挥?12Bytes,,太小了,。所以,我們會(huì)用這塊512b的內(nèi)存做一些準(zhǔn)備性的工作,,操作系統(tǒng)的真正的功能,,大部分的功能都不會(huì)在這512字節(jié)里。

所以,,這512KB的空間我們就稱為“啟動(dòng)區(qū)”了,。電腦去執(zhí)行操作系統(tǒng)的代碼前,先運(yùn)行這512KB區(qū)域內(nèi)的程序,,在這512KB內(nèi)的程序中,,我們做一些寄存器的設(shè)置等工作,在程序的最后,,跳轉(zhuǎn)到真正操作系統(tǒng)的代碼處去執(zhí)行,。

啟動(dòng)區(qū)與操作系統(tǒng)

綜上,也就是說,,首先我們要完成啟動(dòng)區(qū)的程序,,其次才是去完成操作系統(tǒng)的程序。

那么啟動(dòng)區(qū)應(yīng)該寫一些什么內(nèi)容呢,?啟動(dòng)區(qū)程序能不能用C語(yǔ)言,?

啟動(dòng)區(qū)程序的功能:

從軟盤/磁盤/U盤/硬盤等復(fù)制操作系統(tǒng)的代碼到內(nèi)存位置0x8200處,然后就跳轉(zhuǎn)到0x8200處,,開始執(zhí)行

啟動(dòng)區(qū)的程序就是復(fù)制功能,、一些設(shè)置功能,,所以似乎用匯編和C來寫都可以的,,但是最終我們還是選擇了匯編來寫。因?yàn)镃語(yǔ)言設(shè)置寄存器狀態(tài)還是沒有匯編方便。

操作系統(tǒng)代碼的功能:

首先:要設(shè)定一些硬件的狀態(tài),,顯示屏的狀態(tài)等,,鍵盤的狀態(tài),cpu周圍的寄存器的狀態(tài)等

其次:實(shí)現(xiàn)去組織調(diào)用鼠標(biāo),,鍵盤,,顯示屏等硬件供用戶隨時(shí)使用

因?yàn)橐O(shè)定硬件的狀態(tài),顯示屏狀態(tài)等,,需要調(diào)用BIOS,,而BIOS是工作在CPU16位模式的,C語(yǔ)言是工作在CPU32位模式的,,這就決定了操作系統(tǒng)也不能全是C寫的,,操作系統(tǒng)有一些基礎(chǔ)的功能還是需要用工作在16位模式的匯編來寫的。

也就是說,,啟動(dòng)區(qū)之后的操作系統(tǒng),,要使用匯編與C兩種語(yǔ)言來寫。

那么工作在操作系統(tǒng)之前的啟動(dòng)區(qū)程序,,負(fù)責(zé)從存儲(chǔ)介質(zhì)上講操作系統(tǒng)代碼復(fù)制到內(nèi)存上,,用匯編語(yǔ)言寫,代碼量也不大,,如果要設(shè)置硬件也容易,,所以,啟動(dòng)區(qū)的程序用匯編來寫,。

啟動(dòng)區(qū)代碼講解

電腦開機(jī)后,,會(huì)在BIOS里將磁盤上的512字節(jié)的程序復(fù)制到內(nèi)存的0x7c00處,然后跳到0x7c00處執(zhí)行,。

這512字節(jié)程序的作用,,就是將真正操作系統(tǒng)的代碼復(fù)制到內(nèi)存的0x8200處,然后跳轉(zhuǎn)到0x8200開始執(zhí)行,。

為何叫它啟動(dòng)區(qū),?因?yàn)樗颜嬲牟僮飨到y(tǒng)代碼“復(fù)制”到內(nèi)存里了。

那么 BIOS的代碼也是復(fù)制了512B的內(nèi)容到了內(nèi)存里,,為什么BIOS不叫啟動(dòng)區(qū),?

我想如果這512字節(jié)能放下一個(gè)操作系統(tǒng)的話,BIOS里的代碼叫啟動(dòng)區(qū)合適,。

目前來看,,操作系統(tǒng)的代碼遠(yuǎn)超過512字節(jié)。

所以,,”啟動(dòng)區(qū)“這個(gè)名字就歸這512字節(jié)了,。

我們要把啟動(dòng)區(qū)的這512字節(jié)的程序放在啟動(dòng)磁盤/U盤/光盤的前512字節(jié)處,,等待BIOS程序去調(diào)用。我們這里就以軟盤為例,,代碼如下ipl10.nas:

1 ; haribote-ipl 2 ; TAB=4 3 4 CYLS EQU 10 ; 設(shè)置軟磁盤的結(jié)束柱面號(hào),,操作系統(tǒng)放在軟磁盤的0-10柱面 5 6 ORG 0x7c00 ; 將本代碼放在內(nèi)存的0x7c00處 7 8 ; 以下是標(biāo)準(zhǔn)FAT12格式軟盤的描述 9 10 JMP entry 11 DB 0x90 12 DB 'HARIBOTE' ; 設(shè)置扇區(qū)的名稱 13 DW 512 ; 設(shè)置一個(gè)扇區(qū)的大小 一個(gè)扇區(qū)有多少betys,對(duì)于軟磁盤來說,這個(gè)是必須是512 14 DB 1 ; 集群大小 15 DW 1 ; FAT從第1扇區(qū)開始 16 DB 2 ; FAT的個(gè)數(shù) 17 DW 224 ; 根目錄最多有224個(gè)條目 18 DW 2880 ; 驅(qū)動(dòng)器有2880個(gè)扇區(qū) 19 DB 0xf0 ; 媒體類型 20 DW 9 ; FAT每個(gè)區(qū)域含9個(gè)扇區(qū) 21 DW 18 ; 一個(gè)柱面一共多少個(gè)扇區(qū) 22 DW 2 ; 磁頭數(shù)目 23 DD 0 ; 磁盤分區(qū)數(shù)目0 24 DD 2880 ; 驅(qū)動(dòng)器含有2880個(gè)扇區(qū) 25 DB 0,0,0x29 ; 26 DD 0xffffffff ; 當(dāng)前FAT格式的序列號(hào) 27 DB 'HARIBOTEOS ' ; 磁盤名稱 28 DB 'FAT12 ' ; 文件格式名稱 29 RESB 18 ; 對(duì)當(dāng)前的18個(gè)字節(jié)不做操作 30 31 32 entry: 33 MOV AX,0 ;用AX對(duì)寄存器SS初始化 34 MOV SS,AX 35 MOV SP,0x7c00 36 MOV DS,AX 37 38 ; 讀磁盤 39 40 MOV AX,0x0820 41 MOV ES,AX 42 MOV CH,0 ;柱面0 43 MOV DH,0 ;磁頭0 44 MOV CL,2 ;扇區(qū)2 45 readloop: 46 MOV SI,0 ;記錄失敗次數(shù) 47 retry: 48 MOV AH,0x02 ; AH=0x02 :讀磁盤 49 MOV AL,1 ; 1個(gè)扇區(qū) 50 MOV BX,0 51 MOV DL,0x00 ; A驅(qū)動(dòng)器 52 INT 0x13 ; 調(diào)用磁盤BIOS 53 JNC next ; 讀取成功,,跳轉(zhuǎn)到next,去讀區(qū)一下個(gè)扇區(qū) 54 ADD SI,1 ; 讀區(qū)失敗,,記錄失敗次數(shù):SI+1 55 CMP SI,5 ; 如果失敗次數(shù)SI>5,則顯示讀取失敗,跳轉(zhuǎn)到error 56 JAE error ; SI >= 5 57 MOV AH,0x00 ; 重置驅(qū)動(dòng)器 58 MOV DL,0x00 ; A 驅(qū)動(dòng)器 59 INT 0x13 ; 調(diào)用AH=0x00時(shí)對(duì)應(yīng)的中斷程序:重置驅(qū)動(dòng)器 60 JMP retry 61 next: 62 MOV AX,ES ;獲取當(dāng)前內(nèi)存地址 63 ADD AX,0x0020 ;在內(nèi)存地址上+0x0020 64 MOV ES,AX ; ADD ES,0x020 65 ADD CL,1 ; CL+1,扇區(qū)+1 66 CMP CL,18 ; 比較CL 與18,,查看有沒有到達(dá)18扇區(qū) 67 JBE readloop ; CL <= 18 還沒讀取到18扇區(qū),,則繼續(xù)去讀區(qū)數(shù)據(jù) 68 MOV CL,1 ; 如果已經(jīng)到了18扇區(qū),扇區(qū)設(shè)置為1 69 ADD DH,1 ; 磁頭+1 70 CMP DH,2 ; 對(duì)比磁頭與2 71 JB readloop ; DH < 2,磁頭小與2,,繼續(xù)復(fù)制 72 MOV DH,0 ; 磁頭>2,將磁頭設(shè)置位0 73 ADD CH,1 ; 柱面+1 74 CMP CH,CYLS ; 對(duì)比柱面與 CYLS=10 75 JB readloop ; CH < CYLS ,柱面<10,繼續(xù)復(fù)制 76 77 ;以上代碼完成了將操作系統(tǒng)代碼復(fù)制到內(nèi)存的0x8200處的作用 78 79 MOV [0x0ff0],CH ; 將CH的值存儲(chǔ)到內(nèi)存的[0x0ff0]位置處,,CH是柱面號(hào),柱面0-柱面10是啟動(dòng)區(qū)的程序 80 JMP 0xc200 ; 啟動(dòng)區(qū)的程序運(yùn)行結(jié)束,,跳轉(zhuǎn)到內(nèi)存的0xc200處執(zhí)行 81 82 error: 83 MOV SI,msg ; 如果運(yùn)行失敗,,就顯示msg,msg的內(nèi)容是'load error' 84 putloop: 85 MOV AL,[SI] ; 將msg中的字符放入AL 86 ADD SI,1 ; SI+1,等待區(qū) msg中的下一個(gè)字符 87 CMP AL,0 ; 查看是否取到了msg最后一個(gè)字符 88 JE fin ; 如果取到了最后一個(gè)字符,跳轉(zhuǎn)到fin 89 MOV AH,0x0e ; 定義中斷程序號(hào) 90 MOV BX,15 ; 設(shè)置顯示字符的顏色 91 INT 0x10 ; BIOS中斷程序調(diào)用,,顯示AL中的字符 92 JMP putloop 93 fin: 94 HLT ; 讓CPU在一個(gè)時(shí)鐘周期內(nèi)什么也不做 95 JMP fin ; 96 msg: 97 DB 0x0a, 0x0a ; 兩個(gè)換行符 98 DB 'load error' ; 等待被顯示的字符串 99 DB 0x0a ; 換行符100 DB 0 ; msg的最后一個(gè)字符0,,顯示程序遇到這個(gè)字符,就跳轉(zhuǎn)到fin101 102 RESB 0x7dfe-$ ; 以0x00來填充當(dāng)前程序所處的內(nèi)存,,一直到內(nèi)存地址的0x7dfe處103 104 DB 0x55, 0xaa ; 最后再寫0x55,0xaa到程序的最后,。用這兩個(gè)字節(jié)結(jié)束表示當(dāng)前程序是啟動(dòng)區(qū)程序。

以上程序?qū)⒈籅IOS程序自動(dòng)復(fù)制到0x7c00處,,然后運(yùn)行,。

程序復(fù)制了軟磁盤的內(nèi)容到0x8200處,若成功跳轉(zhuǎn)到0xc200處,,若不成功,,跳轉(zhuǎn)到error處。

不成功的話,,顯示錯(cuò)誤提示,。

成功的話,應(yīng)該跳轉(zhuǎn)到操作系統(tǒng)代碼處,,即內(nèi)存的0x8200處呀,?這里為甚么跳轉(zhuǎn)到了0xc200處?

這是因?yàn)樵谌?zhí)行真正的操作系統(tǒng)代碼之前,,需要做一些硬件設(shè)置,,cpu工作模式的改變等,而這些代碼就存放在0xc200處,,

我們看下0xc200處的代碼asmhead.asm:

; haribote-os boot asm; TAB=4BOTPAKEQU0x00280000; 將操作系統(tǒng)的代碼存放到0x00280000處,,等待執(zhí)行DSKCACEQU0x00100000; 將軟盤中的啟動(dòng)區(qū)代碼,,操作系統(tǒng)代碼等保存到0x00100000處DSKCAC0EQU0x00008000; 0x7c00+512,BIOS將軟盤的啟動(dòng)區(qū)代碼復(fù)制到了0x7c00處,,我們要把從0x8000處的內(nèi)容,,軟盤中除了啟動(dòng)區(qū)的代碼,,從內(nèi)存0x8000開始的代碼復(fù)制到0x001002ff處CYLSEQU0x0ff0; 復(fù)制的柱面數(shù)存放的地址0x0ff0LEDSEQU0x0ff1            VMODEEQU0x0ff2; 顯示屏顯示模式放在0x0ff2處SCRNXEQU0x0ff4; 寬度放在內(nèi)存0x0ff4處SCRNYEQU0x0ff6; 高度VRAMEQU0x0ff8; 像素?cái)?shù)據(jù)緩沖區(qū)ORG0xc200; 將此代碼放到內(nèi)存的0xc200處,,等待啟動(dòng)區(qū)程序跳轉(zhuǎn)到此處; 顯示屏顯示模式的設(shè)置MOVAL,0x13; 設(shè)定顯卡工作在VGA模式,分辨率為320x200x8bit位彩色MOVAH,0x00INT0x10            ;調(diào)用BIOS中的中斷程序,,對(duì)顯卡進(jìn)行設(shè)定MOVBYTE [VMODE],8; 將畫面模式放入內(nèi)存地址VMODE處MOVWORD [SCRNX],320; 將寬度放到內(nèi)存地址SCRNX處MOVWORD [SCRNY],200; 將高度放到內(nèi)存地址SCRNX處MOVDWORD [VRAM],0x000a0000; ;將0x000a0000放到內(nèi)存地址 VRAM處,,表明內(nèi)存的0x000a0000處,是放像素質(zhì)的地方,,0x000a0000通過查BIOS手冊(cè)可以得到; 鍵盤燈的設(shè)定MOVAH,0x02INT0x16 			; BIOS中關(guān)于鍵盤燈的中斷程序 		MOV[LEDS],AL; 根據(jù)AT兼容機(jī)的規(guī)格,,如果要初始化PIC,必須在關(guān)閉中斷前執(zhí)行,,否則會(huì)進(jìn)入終端程序無法返回,,造成“掛起”現(xiàn)象MOVAL,0xffOUT0x21,ALNOP; 連續(xù)OUT命令中間加上空指令,提高OUT指令成功率OUT0xa1,AL         ; 執(zhí)行OUT指令,,初始化PICCLI; 關(guān)閉中斷; 為了能讓CPU訪問1M以上的內(nèi)存,,設(shè)定第20根地址線可用,即A20可用CALLwaitkbdoutMOVAL,0xd1OUT0x64,ALCALLwaitkbdoutMOVAL,0xdf; enable A20OUT0x60,ALCALLwaitkbdout; 切換到保護(hù)模式,,芯片對(duì)保護(hù)操作系統(tǒng)有一定保護(hù)功能的模式[INSTRSET 'i486p']; 使用486的匯編指令LGDT[GDTR0]; 設(shè)定臨時(shí)GDT的地址,,GDT,全局內(nèi)存段記錄表,,這里用了一個(gè)表將內(nèi)存管理起來,,使用這個(gè)表可以對(duì)操作系統(tǒng)使用的內(nèi)存特殊保護(hù)MOVEAX,CR0         ; 獲取CR0寄存器的置,ANDEAX,0x7fffffff; 將CR0的 31位設(shè)置為0,,禁止頒OREAX,0x00000001; 將CRO寄存器的第0位設(shè)置為1,,切換到保護(hù)模式MOVCR0,EAXJMPpipelineflushpipelineflush:MOVAX,1*8;  可讀寫的段地址 32bitMOVDS,AXMOVES,AXMOVFS,AXMOVGS,AXMOVSS,AX; bootpack程序復(fù)制MOVESI,bootpack; 源地址MOVEDI,BOTPAK; 目的地址MOVECX,512*1024/4  ; 需要復(fù)制的雙字?jǐn)?shù)CALLmemcpy          ; 調(diào)用復(fù)制程序; 啟動(dòng)區(qū)程序,放在軟盤上的程序也要復(fù)制一下,,復(fù)制到DSKCAC處; 首先復(fù)制一個(gè)扇區(qū)MOVESI,0x7c00; 源地址MOVEDI,DSKCAC; 目的地址MOVECX,512/4       ; 傳送的雙字?jǐn)?shù)CALLmemcpy; 剩下的扇區(qū)MOVESI,DSKCAC0+512; 源地址MOVEDI,DSKCAC+512; 目的地址MOVECX,0MOVCL,BYTE [CYLS]  ; 到0x0ff0位置獲取讀區(qū)成功的柱面數(shù)IMULECX,512*18*2/4; 用柱面數(shù)計(jì)算雙字?jǐn)?shù)SUBECX,512/4; 減去IPL程序占用的雙字?jǐn)?shù)CALLmemcpy; 啟動(dòng)bootpack.c程序; 查看C代碼編譯好的二進(jìn)制文件,,發(fā)現(xiàn)程序的地址在內(nèi)存的:2*8:0x0000001b處,所以最終跳轉(zhuǎn)到了2*8:0x0000001b處; 至于跳轉(zhuǎn)前的復(fù)制不知道啥意思,,作者也沒提MOVEBX,BOTPAK      ; BOTPAK 0x00280000MOVECX,[EBX+16]    ; 需要復(fù)制的雙字?jǐn)?shù):0x11a8ADDECX,3; ECX += 3;SHRECX,2; ECX /= 4;JZskip; 不需要復(fù)制MOVESI,[EBX+20]; 復(fù)制的數(shù)據(jù)源0x10c8,,內(nèi)存這個(gè)地址是什么呢?需要復(fù)制到0x00310000處,?ADDESI,EBXMOVEDI,[EBX+12]; 復(fù)制的目的地 0x00310000處CALLmemcpyskip:MOVESP,[EBX+12];  將0x00310000設(shè)為棧地址JMPDWORD 2*8:0x0000001bwaitkbdout:IN		 AL,0x64AND		 AL,0x02JNZwaitkbdout; 如果AL與0x02 做AND操作后,,不為零,就重新讀區(qū)端口0x64的數(shù)據(jù)RETmemcpy:MOVEAX,[ESI]       ;將ESI地址處的內(nèi)容MOV到EDI地址處的內(nèi)容ADDESI,4MOV[EDI],EAXADDEDI,4SUBECX,1           ;移動(dòng)一次,,ECX -1JNZmemcpy; 如果ECX 不等于 0 ,,則復(fù)制下一個(gè)字節(jié)RETALIGNB16              ; 一直添加DB0,,一直到地址能被16整除GDT0:RESB8; 保留8個(gè)字節(jié),32位DW0xffff,0x0000,0x9200,0x00cf; 用32位的數(shù)據(jù),,設(shè)置可以讀寫的內(nèi)存段DW0xffff,0x0000,0x9a28,0x0047; 用32為的數(shù)據(jù),,設(shè)置可以存放操作系統(tǒng)代碼的內(nèi)存段(bootpack.c文件就保存在這里)DW0GDTR0:DW8*3-1DDGDT0            ;將內(nèi)存段的記錄表放到GDTR0處,等待被放到LGDT寄存器里ALIGNB16bootpack:

可以看到,,這里設(shè)定了顯示屏顯卡,,設(shè)定了顯示屏的像素地址,設(shè)定了鍵盤燈,,切換到了486的32位模式,,保護(hù)模式,設(shè)定了2個(gè)斷記錄表來管理內(nèi)存,,不再用段寄存器來訪問內(nèi)存了,,

設(shè)定完成后,本程序?qū)⒋疟P文件復(fù)制到了0x00100000處,,為甚么復(fù)制到這里,,沒有特別的用處,也可以空著,。

本程序?qū)⒉僮飨到y(tǒng)代碼復(fù)制到了第二個(gè)內(nèi)存段0x00280000處,。

然后就跳轉(zhuǎn)到了2*8:0x0000001b,第二個(gè)段的0x0000001b處,,這里就是我們寫的C程序編譯而成的二進(jìn)制文件,。

我們寫的c程序就是bootpack.c,它就在0x0000001b處,,它也及時(shí)操作系統(tǒng)的代碼,,如下:

操作系統(tǒng)代碼

bootpack.c

// 聲明函數(shù),這個(gè)函數(shù)來自匯編,,因?yàn)槲覀僣程序中要使用,,所以這里需要先聲明一下void io_hlt(void);void HariMain(void){fin: io_hlt(); /* cpu空一個(gè)時(shí)鐘周期 */ goto fin;}

這個(gè)代碼非常簡(jiǎn)單,就是cpu閑置,,程序一直等待,。

以后就可以在這個(gè)HariMain函數(shù)里寫控制顯示屏顯示的程序了,用C寫,,而不是用匯編寫,。

用C寫效率就很高了。

這個(gè)C代碼里有個(gè)函數(shù)需要說一下,,就是這個(gè)io_hlt函數(shù),,

這個(gè)函數(shù)定義在匯編代碼asmfunc.nas里,如下:

; naskfunc; TAB=4[FORMAT 'WCOFF']				; 指定目標(biāo)文件格式	[BITS 32]						; 編譯成32模式對(duì)應(yīng)的機(jī)器碼; 目標(biāo)文件其他信息指定[FILE 'naskfunc.nas']			; 源文件名		GLOBAL	_io_hlt			; 聲明_io_hlt為GLOBAL; 具體函數(shù)的實(shí)現(xiàn)[SECTION .text]		; 將一下代碼放在程序區(qū)_io_hlt:	; 定義 void io_hlt(void);		HLT		RET

代碼naskfunc.nas中,,定義了一個(gè)函數(shù)io_hlt,供C程序去調(diào)用,。

運(yùn)行:

將以上ipl10.nas, asmhead.nas,bootpack.c,naskfunc.nas四個(gè)文件編譯,,生成操作系統(tǒng)映像haribote.img,編譯規(guī)則如下:

ipl10.bin : ipl10.nas Makefile $(NASK) ipl10.nas ipl10.bin ipl10.lstasmhead.bin : asmhead.nas Makefile $(NASK) asmhead.nas asmhead.bin asmhead.lstbootpack.gas : bootpack.c Makefile $(CC1) -o bootpack.gas bootpack.cbootpack.nas : bootpack.gas Makefile $(GAS2NASK) bootpack.gas bootpack.nasbootpack.obj : bootpack.nas Makefile $(NASK) bootpack.nas bootpack.obj bootpack.lstnaskfunc.obj : naskfunc.nas Makefile $(NASK) naskfunc.nas naskfunc.obj naskfunc.lstbootpack.bim : bootpack.obj naskfunc.obj Makefile $(OBJ2BIM) @$(RULEFILE) out:bootpack.bim stack:3136k map:bootpack.map \ bootpack.obj naskfunc.obj# 3MB+64KB=3136KBbootpack.hrb : bootpack.bim Makefile $(BIM2HRB) bootpack.bim bootpack.hrb 0haribote.sys : asmhead.bin bootpack.hrb Makefile copy /B asmhead.bin+bootpack.hrb haribote.sysharibote.img : ipl10.bin haribote.sys Makefile $(EDIMG) imgin:../z_tools/fdimg0at.tek \ wbinimg src:ipl10.bin len:512 from:0 to:0 \ copy from:haribote.sys to:@: \ imgout:haribote.img

先將ipl10.nas編譯成ipl10.bin待用

將asmhead.nas編譯成asmhead.bin待用

將bootpack.c編譯成bootpack.obj待用

將naskfunc.nas編譯成naskfunc.obj待用

將naskfunc.obj與bootpack.obj鏈接在一起,生成bootpack.bim 然后編譯生成bootpack.hrb

bootpack.hrb與asmhead.bin文件連接成haribote.sys

將ipl10.bin與haribote.sys連接在一起生成操作系統(tǒng)映像文件haribote.img

然后用模擬器加載映像文件haribote.img即可看到運(yùn)行結(jié)果:顯示屏顯示一片黑,。

這次主要完成了一些鋪墊工作,,成功用C實(shí)現(xiàn)了顯示屏顯示黑色,然后等待的狀態(tài),。下一節(jié)開始,,就開始控制顯示屏顯示我們期待的內(nèi)容。

總結(jié):

為了用C來寫操作系統(tǒng),,我們不僅僅需要利用啟動(dòng)區(qū)的512字節(jié)的程序,,把磁盤文件復(fù)制到內(nèi)存中,,還需要在把cpu的工作模式切換到32位保護(hù)模式,,需要管理更大的超過1M的內(nèi)存,需要用內(nèi)存段記錄表的形式來管理內(nèi)存,。

只有當(dāng)以上工作完成之后,,我們才能夠讓cpu跳轉(zhuǎn)到我們寫的c程序里。

另外c程序里,,需要調(diào)用匯編代碼,,這里提供了c調(diào)用匯編代碼的方式;寫一個(gè)naskfunc文件,,內(nèi)部寫上_io_hlt的具體實(shí)現(xiàn),。

這里還有很多細(xì)節(jié),比如內(nèi)存段記錄表是什么,??jī)?nèi)存段記錄表寄存器LGDR的作用是什么,?這些等下次來介紹。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多