作者:餓得扶墻走
其實(shí)我覺(jué)得樓主問(wèn)了個(gè)非常好的問(wèn)題,核心就是想知道如果自己動(dòng)手怎么能寫一個(gè)系統(tǒng)讓機(jī)子轉(zhuǎn)起來(lái)。我就利用你給的假設(shè)來(lái)給你講講計(jì)算機(jī)的歷史,看完也許你就明白了計(jì)算機(jī)操作系統(tǒng)歷史了。
let's begin!
首先我們把這臺(tái)計(jì)算機(jī)的硬盤拿掉,把主板上的bios芯片拿掉。因?yàn)樽钤缬?jì)算機(jī)運(yùn)行的程序是寫在紙帶上的,當(dāng)紙帶插入后,計(jì)算機(jī)開始從第一句執(zhí)行。我們?yōu)榱俗鞒鲆粋€(gè)紙帶,采用以下辦法:
1.寫一段匯編程序,例如:
mov cx,100000
L1:
mov ax,0
mov bx,0
add ax,bx
inc bx
loop L1
這段程序是計(jì)算從0到100000的等差數(shù)列之和,算是科學(xué)計(jì)算吧(什么你說(shuō)有公式?)
然后我們把它編譯成二進(jìn)制文件(利用nasm配合參數(shù)即可實(shí)現(xiàn))?,F(xiàn)在紙帶上的數(shù)字有了,我們要一個(gè)紙帶。
2.這一步比較神棍,就是為了實(shí)現(xiàn)一個(gè)紙帶:我們?nèi)ヒ患抑谱鱞ios芯片的工廠,讓他把我們剛才寫的二進(jìn)制代碼燒錄到一個(gè)bios芯片上。在pc接通電源以后,首先cpu要去bios的一個(gè)特定地址順序執(zhí)行之后的語(yǔ)句,我們插上這個(gè)假的bios芯片,機(jī)器上來(lái)就不自檢了,而執(zhí)行我們寫的代碼。
這就是第一代操作系統(tǒng),由此可見(jiàn)第一代計(jì)算機(jī)根本沒(méi)有操作系統(tǒng),人們吧精心編制的二進(jìn)制代碼刻在紙帶上,cpu就開始順序執(zhí)行。
人們痛恨每次都要裝卸紙帶,尤其是有多個(gè)人等候使用計(jì)算機(jī)的時(shí)候,所以大家希望把程序事先存儲(chǔ)在某個(gè)地方,讓計(jì)算機(jī)自己調(diào)用就好了,于是就有了外存?,F(xiàn)在計(jì)算機(jī)發(fā)展了,所以我們把硬盤和bios都裝上。還是原來(lái)的二進(jìn)制代碼,我們把它刻錄在硬盤里(可以先插到一個(gè)linux系統(tǒng)里,一個(gè)dd命令就實(shí)現(xiàn)了。這里要注意一定要刻錄在硬盤的第一個(gè)扇區(qū),而且最后倆字節(jié)一定要是55aa,至于為什么我們不討論,畢竟我們是模擬)。這樣紙帶這種東西就消失在計(jì)算機(jī)的歷史中了。但是你可能會(huì)問(wèn),這步就是把紙帶換成硬盤了嗎?的確是。
我們的前輩們也不滿意,他們希望直接想計(jì)算機(jī)傳達(dá)命令。
繼續(xù)改進(jìn),我們先寫這樣一段代碼:(本來(lái)想寫純匯編代碼,但是不能使用int9中斷的話實(shí)在太長(zhǎng),我先寫偽代碼,以后有時(shí)間我在完善)
start:
如果鍵盤寄存器的值為0
讀取硬盤第二個(gè)扇區(qū)到內(nèi)存地址yyyy
jmp yyyy
否則
funcinput:
如果鍵盤的寄存器有新的值
讀取鍵盤的寄存器
存入到內(nèi)存地址xxxx
地址xxxx+1
jmp funcinput
else 把剛才寫的那一個(gè)內(nèi)存塊放入硬盤的第二個(gè)扇區(qū)
jmp start
(話擦這是什么偽代碼,你大學(xué)在家上的吧)
把這一段代碼寫在硬盤第一個(gè)扇區(qū),以后每次開機(jī)輸入0就運(yùn)行程序,而輸入非0則先錄入程序在執(zhí)行。
技術(shù)上講,剛才這一小段代碼就已經(jīng)算是一個(gè)操作系統(tǒng)了,操作系統(tǒng)只是一個(gè)概念,并沒(méi)有題主顯得那么復(fù)雜。
但是到目前為止我們的程序只能一個(gè)接一個(gè)的完成,如果一個(gè)很長(zhǎng)的程序后面跟一個(gè)很短的,那么對(duì)短程序是相當(dāng)不利的,因此前輩們又研究出了多道批處理。
多道的核心思想就是設(shè)置時(shí)間片,每個(gè)任務(wù)都運(yùn)行一個(gè)時(shí)間片,時(shí)間片結(jié)束以后,就換到下一個(gè)任務(wù),這樣對(duì)每個(gè)任務(wù)都是公平的。盡管現(xiàn)在的cpu都是雙核四核,但是這個(gè)思想到如今依然是家用電腦系統(tǒng)的基石,我們能一邊聽(tīng)音樂(lè)一邊打游戲就是拜這個(gè)思想所賜。
好了現(xiàn)在我們來(lái)實(shí)現(xiàn)?,F(xiàn)在我們要給這臺(tái)電腦裝一個(gè)叫做8583的芯片,他的作用就是每隔一段時(shí)間就向cpu發(fā)出一個(gè)中斷。而我們的核心代碼就是在收到這個(gè)中斷以后執(zhí)行。
timeInterrupt:
mov al,20h
out 20h,al
mov ax,dataSegment-gdt
mov ds,ax
mov eax,1
cmp eax,[current]
je .1
mov [current],eax
jmp tss1Segment-gdt:0
jmp .2
.1:
mov byte [current],0
jmp tss0Segment-gdt:0
.2:
iret
(這個(gè)是我畢業(yè)設(shè)計(jì)《小型操作系統(tǒng)原理實(shí)現(xiàn)》所用到的實(shí)現(xiàn)時(shí)間片的代碼部分,省事就粘過(guò)來(lái)了)
這個(gè)代碼的核心思想就是接到時(shí)鐘中斷以后,保存第一個(gè)任務(wù)的現(xiàn)場(chǎng),恢復(fù)第二個(gè)任務(wù)的現(xiàn)場(chǎng),在跳轉(zhuǎn)到第二個(gè)任務(wù))
多道的實(shí)現(xiàn)不光只是分配時(shí)間片那么簡(jiǎn)單,因?yàn)槎嗟老到y(tǒng)同時(shí)有多個(gè)程序在內(nèi)存,而編制程序的時(shí)候都是從邏輯地址0開始的,這樣必然會(huì)造成地址沖突,于是intel8086推出了段的概念,多道程序中要防止自己編寫的程序由于bug或其他因素破壞掉操作系統(tǒng)程序,于是intel386推出了保護(hù)模式,等等。可以說(shuō)多道是現(xiàn)在操作系統(tǒng)的一大分支。
到此為止,樓主的問(wèn)題我基本解答了,首先你覺(jué)得沒(méi)有操作系統(tǒng)沒(méi)法輸入,這是錯(cuò)的,我們直接插了一塊bios芯片,沒(méi)有輸入任何代碼。然后我們修改了“刻”進(jìn)去的代碼,實(shí)現(xiàn)了我們?cè)跈C(jī)器了編制程序。如今的操作系統(tǒng)也一樣,你第一次給裸機(jī)安裝系統(tǒng)的時(shí)候,一定是找了一個(gè)刻錄好的媒介(光盤,u盤)。
以上就是我用代碼幫你模擬了計(jì)算機(jī)操作系統(tǒng)的發(fā)展,看得出題主能從這方面思考問(wèn)題說(shuō)明你對(duì)計(jì)算機(jī)底層有興趣,這里推薦你基本書:《匯編語(yǔ)言》(王爽的那本)《linux內(nèi)核注釋》(趙炯那本)《匯編語(yǔ)言:從實(shí)模式到保護(hù)模式》《orangs:一個(gè)操作系統(tǒng)的實(shí)現(xiàn)》我推薦的這基本都是自己寫內(nèi)核來(lái)了解操作系統(tǒng)原理,非常對(duì)題主胃口,而非ldd,ldk之類的直接剖析一個(gè)操作系統(tǒng)內(nèi)核。
聯(lián)系客服