Linux內(nèi)核源碼學(xué)習(xí)——bootsect.s

1.啟動(dòng)BIOS

加電瞬間強(qiáng)行將CS值設(shè)置為0xF000演熟,IP值置為0xFFF0. CS:IP=0xFFFF0,指向BIOS的地址范圍

BIOS在內(nèi)存最開始的位置(0x00000)用1KB構(gòu)建了中斷向量表区匣,后面緊接著256字節(jié)構(gòu)建BIOS數(shù)據(jù)區(qū)杨伙,大約57KB以后的位置加載了中斷服務(wù)程序

中斷向量表:256個(gè)中斷向量拳球,每個(gè)中斷4個(gè)字節(jié)舀瓢,2個(gè)是CS滞乙,2個(gè)是IP债蓝,每個(gè)向量指向一個(gè)中斷服務(wù)程序

2.把軟盤中的操作系統(tǒng)程序加載到內(nèi)存
2.1 BIOS中斷0x19把第一扇區(qū)bootsect內(nèi)容加載進(jìn)去

CPU接收到一個(gè)int 0x19中斷壳鹤,然后再去中斷向量表里找這個(gè)中斷向量。中斷向量指向0x0e6f2(中斷服務(wù)程序入口地址)饰迹,這個(gè)中斷服務(wù)程序的作用是把軟盤第一扇區(qū)中的程序(512B)加載到內(nèi)存中的指定位置芳誓,即將軟驅(qū)0號磁頭對應(yīng)盤面的0磁道1扇區(qū)的內(nèi)容復(fù)制到內(nèi)存0x7C00處。

2.2 把第二批和第三批程序加載到內(nèi)存

規(guī)劃內(nèi)存


.globl begtext, begdata, begbss, endtext, enddata, endbss

.text

begtext:

.data

begdata:

.bss

begbss:

.text

!對后續(xù)操作涉及的內(nèi)存位置進(jìn)行設(shè)置

SETUPLEN = 4    ! nr of setup-sectors

BOOTSEG  = 0x07c0   ! original address of boot-sector

INITSEG  = 0x9000   ! we move boot here - out of the way

SETUPSEG = 0x9020   ! setup starts here

SYSSEG  = 0x1000    ! system loaded at 0x10000 (65536).

ENDSEG  = SYSSEG + SYSSIZE  ! where to stop loading

復(fù)制bootsect

將源地址0x07C00的bootsect復(fù)制到目的地址0x90000


啊鸭!將源地址0x07C00的bootsect復(fù)制到目的地址0x90000

! 代碼主要設(shè)定源地址和目標(biāo)地址后锹淌,使用循環(huán)指令rep和移動(dòng)指令movw進(jìn)行移動(dòng)

entry start

start:

mov ax,#BOOTSEG      !BOOTSEG  = 0x07c0

mov ds,ax            ! ds寄存器置為0x07c0

mov ax,#INITSEG      赠制!INITSEG  = 0x9000

mov es,ax

mov cx,#256          赂摆!計(jì)數(shù)器,提供需要復(fù)制的字的數(shù)量 256字=512字節(jié)

sub si,si            !sub是做減法操作钟些,此處將si烟号,di自己減自己,即置0政恍。

sub di,di

                !移動(dòng)時(shí)源地址ds:si=0x07c0:0x0000汪拥,目的地址es:di=0x9000:0x0000

                  !即將BIOS移動(dòng)到0x9000(0x07c0用于放置bootsect.s)

    rep                  !rep指令作用:重復(fù)執(zhí)行后面一句操作,并遞減cx的值篙耗,直到cx=0停止

    movw                  !movw指令作用:這里從內(nèi)存[si]處移動(dòng)cx個(gè)字到[di]迫筑;注意一次的移動(dòng)單位是“字”,  mov指令+w(word)是一次移動(dòng)一個(gè)字

jmpi    go,INITSEG    !將BIOS移動(dòng)到0x9000后宗弯,跳轉(zhuǎn)(go)到INITSEG(0x9000)脯燃,CS=0x90000


! 對ds,ex,ss,sp進(jìn)行調(diào)整

go: mov ax,cs

mov ds,ax

mov es,ax

! put stack at 0x9ff00.  !下面兩條指令是將堆棧指針sp指向0x9ff00處(即0x9000:0xff00)

mov ss,ax

mov sp,#0xFF00  ! arbitrary value >>512

將setup程序加載到內(nèi)存

借助0x13中斷向量,從第二個(gè)扇區(qū)開始的4個(gè)扇區(qū)


!INT 0x13的使用方法:

!ah = 0x20-讀磁盤扇區(qū)到內(nèi)存罕伯; al = 需要讀出的扇區(qū)數(shù)量曲伊;

!ch=磁道(柱面)號的低8位;  cl =開始扇區(qū)(位0-5)追他,磁道號高2位(位6-7);

!dh = 磁頭號岛蚤;  dl = 驅(qū)動(dòng)器號邑狸;

!es:bx = 指向數(shù)據(jù)緩沖區(qū);

!如果出錯(cuò)則CF標(biāo)志置位涤妒,ah中是出錯(cuò)碼单雾。

load_setup:

mov dx,#0x0000  ! drive 0, head 0 磁頭號0,驅(qū)動(dòng)器號0

mov cx,#0x0002  ! sector 2, track 0,開始扇區(qū)2硅堆,磁道號0

mov bx,#0x0200  ! address = 512, in INITSEG  es:bx=0x9000:0x0200 即數(shù)據(jù)緩沖區(qū)為0x90200

mov ax,#0x0200+SETUPLEN ! service 2, nr of sectors,SETUPLEN初始設(shè)置為4,ax=0x0210,ah=0x02-讀磁盤扇區(qū)到內(nèi)存屿储,需要讀出的扇區(qū)數(shù)量-4

int 0x13    ! read it 打開中斷

jnc ok_load_setup   ! ok - continue jnc指令:如果(上條指令)成功,則跳轉(zhuǎn)渐逃,即中斷INT 0x13成功够掠,則繼續(xù)執(zhí)行ok_load_setup

mov dx,#0x0000      ! 如果不成功,則復(fù)位驅(qū)動(dòng)器茄菊,并重試(重新跳轉(zhuǎn)函數(shù)load_setup)

mov ax,#0x0000  ! reset the diskette

int 0x13

j   load_setup


ok_load_setup:

! Get disk drive parameters, specifically nr of sectors/track 利用BIOS中斷0x13取磁盤參數(shù)表中當(dāng)前啟動(dòng)引導(dǎo)盤的參數(shù)

! 這段代碼主要還是獲得每磁道的扇區(qū)數(shù)量疯潭,保存在了sectors中

mov dl,#0x00        !驅(qū)動(dòng)器號為0

mov ax,#0x0800  ! AH=8 is get drive parameters,AH=8,是INT 0x13取磁盤驅(qū)動(dòng)器的參數(shù)面殖,AL初始化0竖哩,作為返回值

int 0x13            ! 打開中斷

mov ch,#0x00

seg cs              ! 此條指令表示下一條語句的操作數(shù)在cs段寄存器所指的段中

mov sectors,cx

mov ax,#INITSEG

mov es,ax

將system模塊加載到內(nèi)存,加載240個(gè)扇區(qū)


! Print some inane message

! 顯示信息:“Loading system ... 回車”脊僚,共顯示24個(gè)字符

! 使用BIOS中斷0x10功能號ah=0x03和ah=0x13實(shí)現(xiàn)

! BIOS中斷0x10功能號ah=0x03相叁,功能:讀光標(biāo)位置

! 輸入:bh=頁號

! 返回:ch=掃描開始線;cl=掃描結(jié)束線辽幌;dh=行號钝荡; dl=列號

! BIOS中斷0x10功能號ah=0x13,功能:顯示字符串

! 輸入:al=放置光標(biāo)方式及規(guī)定屬性舶衬。0x01表示使用bl中屬性值埠通,光標(biāo)停在字符串結(jié)尾處;

!      es:bp 指向要顯示的字符串起始位置逛犹。 cx=顯示字符串個(gè)數(shù)端辱; bh=顯示頁面號

!      bl=字符屬性; dh=行號虽画; dl=頁號

mov ah,#0x03    ! read cursor pos 讀光標(biāo)

xor bh,bh          ! 將bh置為0

int 0x10

mov cx,#24          ! 24個(gè)字符

mov bx,#0x0007  ! page 0, attribute 7 (normal) bh=0,頁=0; bl=7,字符屬性=7

mov bp,#msg1        ! es:bp指向要顯示的字符串

mov ax,#0x1301  ! write string, move cursor ah=0x13使用中斷0x10功能號舞蔽;al=0x01,使用bl中屬性值

int 0x10            ! 打開中斷码撰,串口打印字符串

! 上面使用中斷0x10顯示字符渗柿,首先使用ah=0x03功能獲取光標(biāo)位置以及行號列號,作為ah=0x13中斷的入?yún)ⅲ?
! 而后使用ah=0x13中斷將存在es:bp寄存器的字符串打印在串口屏幕脖岛,只要在使用中斷時(shí)朵栖,將輸入設(shè)定好即可。

! ok, we've written the message, now

! we want to load the system (at 0x10000) 將system模塊加載到內(nèi)存0x10000往后的120KB中

mov ax,#SYSSEG  !SYSSEG=0x10000

mov es,ax   ! segment of 0x010000

call    read_it

call    kill_motor

此時(shí)整個(gè)操作系統(tǒng)的代碼已經(jīng)全部加載至內(nèi)存柴梆。

確定一下根設(shè)備號


! After that we check which root-device to use. If the device is

! defined (!= 0), nothing is done and the given device is used.

! Otherwise, either /dev/PS0 (2,28) or /dev/at0 (2,8), depending

! on the number of sectors that the BIOS reports currently.

! 確定根文件系統(tǒng)設(shè)備號并保存其設(shè)備號于root_dev

! Linux中陨溅,軟驅(qū)的主設(shè)備號是2,次設(shè)備號=type*4+nr绍在,其中nr為0-3分別對應(yīng)軟驅(qū)A门扇、B雹有、C和D;

! type是軟驅(qū)類型(2->1.2MB或7->1.44MB)臼寄。

! 因?yàn)?*4+0=28霸奕,所以/dev/PS0 (2,28)指1.44MB A驅(qū)動(dòng)器,其設(shè)備號是0x021c(2*256+28)

! 同理吉拳,/dev/at0 (2,8)值1.2MB A驅(qū)動(dòng)器质帅,設(shè)備號是0x0208

! 取上面獲得的每磁道扇區(qū)數(shù),如果sectors=15說明是1.2MB的驅(qū)動(dòng)器合武;如果sectors=18說明是1.44M軟驅(qū)(為什么临梗?);

! 因?yàn)槭强梢龑?dǎo)的驅(qū)動(dòng)器稼跳,所以肯定是A驅(qū)

seg cs

mov ax,root_dev

cmp ax,#0

jne root_defined  ! 檢查root_dev是否是空盟庞,如果否,則說明其已經(jīng)存入根設(shè)備號汤善,直接跳轉(zhuǎn)后面

seg cs            ! 此條指令表示下一條語句的操作數(shù)在cs段寄存器所指的段中如果以Masm語法寫什猖,

                    seg cs和mov bx,sectors兩句合起來,等價(jià)于mov bx, cs:[sectors], 這里使用了間接尋址方式红淡。

                        重復(fù)一下前面的解釋不狮,mov [sectors],ax表示將ax中的內(nèi)容存入ds:sectors內(nèi)存單元,而mov cs:[sectors],ax強(qiáng)制以cs作為段地址寄存器在旱,因此是將ax的內(nèi)容存入cs:sectors內(nèi)存單元

mov bx,sectors

mov ax,#0x0208  ! /dev/ps0 - 1.2Mb

cmp bx,#15          ! 將sectors與15對比摇零,如果相同,則ax=0x0208桶蝎,最終賦值給root_defined

je  root_defined

mov ax,#0x021c  ! /dev/PS0 - 1.44Mb

cmp bx,#18          ! 將sectors與18對比驻仅,如果相同,則ax=0x021c登渣,最終賦值給root_defined

je  root_defined

undef_root:

jmp undef_root

root_defined:        !將獲取的驅(qū)動(dòng)設(shè)備號存入root_dev

seg cs

mov root_dev,ax

跳轉(zhuǎn)到setup的第一條指令


! after that (everyting loaded), we jump to

! the setup-routine loaded directly after

! the bootblock:

jmpi    0,SETUPSEG      ! 跳轉(zhuǎn)到setup程序開始處(即0x90200)執(zhí)行setup程序

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末噪服,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子胜茧,更是在濱河造成了極大的恐慌粘优,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件呻顽,死亡現(xiàn)場離奇詭異雹顺,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)芬位,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進(jìn)店門无拗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人昧碉,你說我怎么就攤上這事英染。” “怎么了被饿?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵四康,是天一觀的道長。 經(jīng)常有香客問我狭握,道長闪金,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任论颅,我火速辦了婚禮哎垦,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘恃疯。我一直安慰自己漏设,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布今妄。 她就那樣靜靜地躺著郑口,像睡著了一般。 火紅的嫁衣襯著肌膚如雪盾鳞。 梳的紋絲不亂的頭發(fā)上犬性,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天,我揣著相機(jī)與錄音腾仅,去河邊找鬼乒裆。 笑死,一個(gè)胖子當(dāng)著我的面吹牛推励,可吹牛的內(nèi)容都是我干的鹤耍。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼吹艇,長吁一口氣:“原來是場噩夢啊……” “哼惰蜜!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起受神,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤抛猖,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后鼻听,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體财著,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年撑碴,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了撑教。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,675評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡醉拓,死狀恐怖伟姐,靈堂內(nèi)的尸體忽然破棺而出收苏,到底是詐尸還是另有隱情,我是刑警寧澤愤兵,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布鹿霸,位于F島的核電站,受9級特大地震影響秆乳,放射性物質(zhì)發(fā)生泄漏懦鼠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一屹堰、第九天 我趴在偏房一處隱蔽的房頂上張望肛冶。 院中可真熱鬧,春花似錦扯键、人聲如沸睦袖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽扣泊。三九已至,卻和暖如春嘶摊,著一層夾襖步出監(jiān)牢的瞬間延蟹,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工叶堆, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留阱飘,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓虱颗,卻偏偏與公主長得像沥匈,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子忘渔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評論 2 360