其實博主本來想在寒假自己寫乙個oskernal的,高高興興的影印了本《乙個作業系統的實現》。
然後又去圖書館借來《30天自製作業系統》和《x86/x64體系探索程式設計》,結果還是被自己的懶惰給打敗了。。。
原本我感覺自制力還不錯的,好歹春節前也看了很多東西,但是過了乙個春節就懶散了。。
當然也有一部分原因是因為《30天》寫的實在是太亂了。。缺少乙個理論的上的指導和概括,看的雲裡霧裡。
再就是彙編。。。博主原來只學過8086和at&t彙編啊。。。這下又來個nasm彙編。。這學期還開了個arm彙編。。orz。。。
不過nasm彙編真的是很好用,它還有類似c++預設構造的巨集指令,很強大啊!
廢話了這麼多,開始進入主題吧。。
首先,bootsector是個什麼東西呢?其實就是個引導的作用,引導到bootloader或者是作業系統上。
注意,bootsector不是雙系統的那種引導,而是在它之前的程式。
那麼bootsector程式是如何發揮作用的呢?這得從計算機的開機流程講起。
還記得學校上的作業系統教材上面說,計算機開機加電直接就去讀取硬碟上的作業系統。(但其實漏掉了好些東西啊!!國產教材誤人子弟啊!!!!)
其實一開機,並不是直接讀硬碟,而是從主機板的bios啟動。
上電後,bios的rom中程式通過硬體載入到記憶體。
根據bios的rom中的程式,來檢測相關硬體是否安裝正確。然後才是尋找作業系統。
完整流程如下:
bios->bootsector->bootloader->kernel(後面兩個以後再說)
這樣就有問題了,bios怎麼知道作業系統放在哪呢?
這需要了解通用計算機所遵循的規範了,bios只從硬碟的第乙個扇區讀取並引導程式。
扇區又是什麼呢?這裡我簡單的帶著你聯想一下.
由於原來32位位址匯流排只能定址4g的大小。那麼硬碟不斷發展,64位匯流排還沒出現,但是硬碟大小超過4g。
所以,硬碟就出現了所謂的扇區!一般乙個扇區的大小為512b。4g*512b=2t的樣子。
這樣來算,現在的發展已經夠用了,以後換到64位系統就不用擔心位址不夠了。
回到正題。由於bios只能自動讀乙個扇區,512b的大小。
這麼點大小肯定裝不下作業系統~所以只好用bootsector來轉讓計算機使用的權力了。
於是我們就清楚了bootsector的作用----讀入硬碟上的其他程式,並將cpu交給它。
下面是我寫的bootsector。由於沒有檔案系統也不想用fat12,所以讀取loader的位置是我自己隨便定的。
如果fat12那一段不注釋的話,u盤就可以被識別了,但是u盤中的內容都是亂的~~~
linux下可以用dd命令直接寫到你的u盤中去。
dd if=$(oboot) of=$(device) bs=512 count=1 conv=notrunc
oboot表示生成檔案,直接用nasm彙編生成.bin檔案即可。
device就是你u盤在linux下的路徑了。
然後就可以通過u盤啟動,來執行你的bootsector了~
%include "boot.inc"
%ifdef debug
org 0100h ;07c00h 0100
%else
org 07c00h
%endif
jmp short label_start
nop;head of fat12
; bs_oemname db 'meiboyu ' ; oem string, 必須 8 個位元組
; bpb_bytspersec dw 512 ; 每扇區位元組數
; bpb_secperclus db 1 ; 每簇多少扇區
; bpb_rsvdseccnt dw 1 ; boot 記錄占用多少扇區
; bpb_numfats db 2 ; 共有多少 fat 表
; bpb_rootentcnt dw 224 ; 根目錄檔案數最大值
; bpb_totsec16 dw 2880 ; 邏輯扇區總數
; bpb_media db 0xf0 ; **描述符
; bpb_fatsz16 dw 9 ; 每fat扇區數
; bpb_secpertrk dw 18 ; 每磁軌扇區數
; bpb_numheads dw 2 ; 磁頭數(面數)
; bpb_hiddsec dd 0 ; 隱藏扇區數
; bpb_totsec32 dd 0 ; wtotalsectorcount為0時這個值記錄扇區數
; bs_drvnum db 0 ; 中斷 13 的驅動器號
; bs_reserved1 db 0 ; 未使用
; bs_bootsig db 29h ; 擴充套件引導標記 (29h)
; bs_volid dd 0 ; 卷序列號
; bs_vollab db 'mos by mby '; 卷標, 必須 11 個位元組
; bs_filesystype db 'fat12 ' ; 檔案系統型別, 必須 8個位元組
times 18 db 0
label_start:
mov ax, cs
mov ds, ax
mov es, ax ;make all pointer point null place
mov dx,0
mov ax,bootmessage
mov cx,bmlength
mov dh,0
call showstr ;show string function
call loader ;loader getting loading
jmp fin ;while(1)
loader:
mov ax,4200h
mov dl,0x80
mov cx,0
mov ds,cx
mov si,dap
int 0x13
jc loadererror
mov ax,0 ;clean es register
mov es,ax
mov dx,0
mov ax,lsuccess
mov cx,lslength
mov dh,1
call showstr
jmp baseoffloader:setoffloader ;jump to loader !
loadererror:
mov ax,0
mov es,ax
mov ax,lerror
mov cx,lelength
mov dh,1
call showstr
fin:
hltjmp fin
showstr:
mov bp,ax
mov ax,01301h
mov bx,000fh
mov dl,0
int 10h
retlsuccess: db "loader ok!"
lslength equ $-lsuccess
lerror: db "booting loader get wrong!"
lelength equ $-lerror
bootmessage: db "boot sector start!"
bmlength equ $-bootmessage
dap:
db 16 ;packet size
db 0 ;must 0
dw 100 ;number of block need to read
dw 0 ;the offset
dw 8000h ;the segment address
dw 1h ;start block
dw 0
dw 0
dw 0
times 510-($-$$) db 0
dw 0xaa55
程式短,所以懶得用巨集了。。這樣對於新手看著也方便。
具體彙編的內容很簡單,我就不講了,這裡說一下我寫這個遇到的個坑。。。
使用bios的int 13h+al=02h的時候,在真機上是無法載入loader的!!軟盤跟u盤還是有區別的!
我看《乙個作業系統 的實現》和《30天》的時候,就是這裡。。他們都使用的是軟盤,但是用u盤就有問題!!
於是發現要用擴充套件bios中斷,詳細的可以去google擴充套件bios中斷。(我記得我是在wiki上看到的,但是現在找不到了)
當然看我的**也可以~
bootsector就介紹到這裡了。過幾天我再來寫loader的部分~
恩。。現在正在寫,並且寫圖形化介面的時候又遇到坑了。。
ps:裝過win+linux雙系統的知道,得先裝windows再裝linux。
我估計就是windows直接重寫bootsetor,然後直接引導到他的loader了,而linux的引導程式grub會識別原來的系統。
寫自己的作業系統 個人實踐
近期開始看於淵的 自己動手寫作業系統 這本書,剛開始看就發現做系統的引導盤居然是軟盤!心裡那個汗啊!如今都是u盤了,誰還用軟盤。於是考慮用u盤。於是開始下面步驟 1 既然書上說給先要把軟盤做引導盤,那我就相似地把u盤做成引導盤。在網上找了半天,發現usboot,於是就用它給自己的u盤做了乙個引導盤。...
作業系統開發之 乙個簡單的Bootsect
先嚇唬一下讀者朋友呵呵,直接發 這是uos作業系統的bootsect 有興趣的朋友能夠增加我們,在最後 檔名稱 bootsect.asm 檔案建立者 imcjy 檔案編碼 utf 8 狀態 o build 3 檔案建立日期 2015年7月24日 檔案最後改動日期 2015年8月12日 備註 本檔案為...
不用作業系統寫HelloWorld
原因是前些天在楊老師的討論課上楊老師提出了這個問題 沒有作業系統的光板機器,要寫乙個helloworld怎麼辦?有乙個哥們提出了可以用bios的中斷寫,我也記得于淵的 自己動手寫作業系統 一書中提到過,但是忘了具體要怎麼辦。回到宿舍找到于淵的書,看到了如下的 並按書上的方法實驗了一下,執行成功了。如...