過程:
成都創(chuàng)新互聯(lián)公司專注于企業(yè)網(wǎng)絡(luò)營銷推廣、網(wǎng)站重做改版、渭濱網(wǎng)站定制設(shè)計、自適應(yīng)品牌網(wǎng)站建設(shè)、成都h5網(wǎng)站建設(shè)、商城網(wǎng)站制作、集團公司官網(wǎng)建設(shè)、外貿(mào)網(wǎng)站制作、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計等建站業(yè)務(wù),價格優(yōu)惠性價比高,為渭濱等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。(1)程序被加載器(軟件或硬件)加載到內(nèi)存某個區(qū)域。
(2)CPU的cs:ip寄存器被指向這個程序的起始地址。
BIOS從按下主機上的power鍵后,第一個運行的軟件是BIOS
BIOS全稱叫Base Input &Output System,即基本輸入輸出系統(tǒng)。
實模式下的 1MB內(nèi)存布局? 先從低地址看,地址0~0x9FFFF處是DRAM(Dynamic Random Access Memory),即動態(tài)隨機訪問內(nèi)存,我們所裝的物理內(nèi)存就是DRAM,如DDR、DDR2 等。
? 內(nèi)存地址0~0x9FFFF的空間范圍是640KB,這片地址對應(yīng)到了DRAM,也就是插在主板上的內(nèi)存條。
在CPU眼里,我們插在主板上的物理內(nèi)存不是它眼里“全部的內(nèi)存”。
地址總線寬度決定了可以訪問的內(nèi)存空間大小,如16位機的地址總線為20位,其地址范圍是1MB,32位地址總線寬度是32位,其地址范圍是4GB。但以上的地址范圍是指地址總線可以觸及到的邊界,是指計算機在尋址上可以到達的疆域。
在計算機中,并不是只有咱們插在主板上的內(nèi)存條需要通過地址總線訪問,還有一些外設(shè)同樣是需要通過地址總線來訪問的,這類設(shè)備還很多呢。若把全部的地址總線都指向物理內(nèi)存,那其他設(shè)備該如何訪問呢?由于這個原因,只好在地址總線上提前預(yù)留出來一些地址空間給這些外設(shè)用,這片連續(xù)的地址給顯存,這片連續(xù)的地址給硬盤控制器等。留夠了以后,地址總線上其余的可用地址
再指向DRAM,也就是指插在主板上的內(nèi)存條、我們眼中的物理內(nèi)存。物理內(nèi)存多大都沒用,主要是看地線總線的寬度。還要看地址總線的設(shè)計,是不是全部用于訪問DRAM。所以說,地址總線是決定我們訪問哪里、訪問什么,以及訪問范圍的關(guān)鍵。我們平時用的機器一般是32位,上面的內(nèi)存條并不是全部都用到了,按理說內(nèi)存條大小超過 4GB 就沒意義了,超過了地址總線的勢力就是浪費。不過通過前面的介紹,即使內(nèi)存條大小沒有超過地址總線的范圍,也不會全都能被訪問到,畢竟要預(yù)留一些地址用來訪問其他外設(shè),所以最終還得看地址總線把地址指向哪塊內(nèi)存了。這就是安裝了 4GB 內(nèi)存,電腦中只顯示3.8GB左右的原因。
? 看頂部的 0xF0000~0xFFFFF,這64KB的內(nèi)存是ROM。這里面存的就是BIOS的代碼。BIOS 的主要工作是檢測、初始化硬件,怎么初始化的?硬件自己提供了一些初始化的功能調(diào)用,BIOS 直接調(diào)用就好了。BIOS 還做了一件偉大的事情,建立了中斷向量表,這樣就可以通過“int中斷號”來實現(xiàn)相關(guān)的硬件調(diào)用,當然BIOS建立的這些功能就是對硬件的IO操作,也就是輸入輸出,但由于就64KB大小的空間,不可能把所有硬件的IO操作實現(xiàn)得面面俱到,而且也沒必要實現(xiàn)那么多,畢竟是在實模式之下,對硬件支持得再豐富也白搭,精彩的世界是在進入保護模式以后才開始,所以挑一些重要的、保證計算機能運行的那些硬件的基本IO操作,就行了。這就是BIOS稱為基本輸入輸出系統(tǒng)的原因。
BIOS是如何蘇醒的? BIOS是計算機上第一個運行的軟件,所以它不可能自己加載自己,由此可以知道,它是由硬件加載的。那這個硬件是誰呢?其實前面已經(jīng)提到過了,相當于是只讀存儲器ROM,因為它一直就睡在那里不動。
? BIOS代碼所做的工作也是一成不變的,而且在正常情況下,其本身是不需要修改的,平時聽說的那些主板壞了要刷BIOS的情況屬于例外。于是BIOS順理成章地便被寫進此ROM。ROM也是塊內(nèi)存,內(nèi)存就需要被訪問。此ROM被映射在低端1MB內(nèi)存的頂部,即地址0xF0000~0xFFFFF處,可以參考表2-1頂部的BIOS部分。只要訪問此處的地址便是訪問了BIOS,這個映射是由硬件完成的。
? BIOS本身是個程序,程序要執(zhí)行,就要有個入口地址才行,此入口地址便是0xFFFF0。最重要的一點來了,知道了BIOS在哪里后,CPU如何去執(zhí)行它,即CPU中的cs:ip值是如何組合成0xFFFF0的。既然作為第一個運行的程序都沒開始執(zhí)行,自然就沒辦法用軟件搞定這件事了,還是得靠硬件支持才行。
? 在開機的一瞬間,也就是接電的一瞬間,CPU的cs:ip寄存器被強制初始化為0xF000:0xFFF0。由于開機的時候處于實模式,再重復一遍加深印象,在實模式下的段基址要乘以16,也就是左移4位,于是0xF000:0xFFF0的等效地址將是0xFFFF0。上面說過了,此地址便是BIOS的入口地址。
? BIOS是在實模式下運行的,而實模式只能訪問1MB空間(20位地址線,2的20 次方是1MB)。而地址0xFFFF0距1MB只有16個字節(jié)了(見表2-1),這么小的空間夠干嗎?BIOS 又要檢測硬件,做各種初始化工作,還要建立中斷向量表……16 字節(jié)的機器指令肯定干不了這么多事。既然此處只有16字節(jié)的空間了,這只能說明BIOS真正的代碼不在這,那此處的代碼只能是個跳轉(zhuǎn)指令才能解釋得通了。
? 在內(nèi)存物理地址0xFFFF0處的內(nèi)容是一條跳轉(zhuǎn)指令jmp far f000:e05b
,這是條跳轉(zhuǎn)指令。那CPU的執(zhí)行流是跳到哪里了呢?段基址0xf000左移4位+0xe05b,即跳向了0xfe05b
處,這是BIOS代碼真正開始的地方。接下來BIOS 便馬不停蹄地檢測內(nèi)存、顯卡等外設(shè)信息,當檢測通過,并初始化好硬件后,開始在內(nèi)存中0x000~0x3FF
處建立數(shù)據(jù)結(jié)構(gòu),中斷向量表IVT并填寫中斷例程。
? BIOS最后一項工作校驗啟動盤中位于0盤0道1扇區(qū)的內(nèi)容。
在此插播一段小告示:在計算機中是習慣以0作為起始索引的,因為人們已經(jīng)習慣了偏移量的概念,無論是機器眼里和程序員眼里用“相對”的概念,即偏移量來表示位置顯得很直觀,所以很多指令中的操作數(shù)都是用偏移量表示的。0盤0道1扇區(qū)本質(zhì)上就相當于0盤0道0扇區(qū)。為什么稱為1呢,因為硬盤扇區(qū)的表示法有兩種,我們描述0盤0道1扇區(qū)用的便是其中的一種:CHS方法,即柱面Cylinder磁頭Header扇區(qū)Sector(另外一種是LBA 方式,暫不關(guān)心),“0盤”說的是0磁頭,因為一張盤是有上下兩個盤面的,一個盤面上對應(yīng)一個磁頭,所以用磁頭Header 來表示盤面。“0道”是指0柱面,柱面Cylinder指的是所有盤面上、編號相同的磁道的集合,形象一點描述就是把很多環(huán)疊摞在一起的樣子,組合在一起之后是一個立體的管狀?!?扇區(qū)”才是我們要解釋的部分,將磁道等距劃分成一段段的小區(qū)間,由于磁道是圓形的,確切地說是圓環(huán),這些被劃分出來的小區(qū)間便是扇形,所以稱為扇區(qū)。好了,背景交待完了,重點來了,在CHS 方式中扇區(qū)的編號是從1開始的,不是0,不是0,所以0盤0道1扇區(qū)其實就相當于0盤0道0扇區(qū),它就是磁盤上最開始的那個扇區(qū)。而LBA方式中,扇區(qū)編號是從0開始的。先不要著急,只要知道MBR所在的位置是磁盤上最開始的那個扇區(qū)就行了。
? 如果此扇區(qū)末尾的兩個字節(jié)分別是魔數(shù)0x55和0xaa,BIOS 便認為此扇區(qū)中確實存在可執(zhí)行的程序(在此先劇透一下,此程序便是久聞大名的主引導記錄MBR),便加載到物理地址0x7c00,隨后跳轉(zhuǎn)到此地址,繼續(xù)執(zhí)行。
不過,這就又拋出兩個問題:
(1)為什么是0盤0道1扇區(qū)的內(nèi)容?
在計算機中處處充滿了協(xié)議、約定,所以,將0盤0道1扇區(qū)作為mbr的棲身之地,我完全可以理解
為規(guī)定。我們反證一下,如果不存在這個“規(guī)定”,會發(fā)生什么。當然,此扇區(qū)最初是給BIOS 使用的,
咱們設(shè)想一下 BIOS 的工作將變成怎樣。主引導記mbr 是段程序,無論位于軟盤、硬盤或者其他介質(zhì),總該有個地方保存它。Ok,現(xiàn)在不告
訴BIOS它存儲在哪個位置了。BIOS只好將所有檢測到的存儲設(shè)備上的每一個存儲單位都翻一遍,挨個
對比,如果發(fā)現(xiàn)該存儲單位最后的兩個字節(jié)是0x55和0xaa,就認為它是mbr。這就好比查字典一樣,不
用偏旁部首和拼音檢索的方法,只能一頁一頁翻了。由于0盤0道1扇區(qū)是磁盤的第一個扇區(qū),mbr選擇了離BIOS最近的位置
(2)為什么是物理地址0x7c00,而不是個好記或好看的其他地址?
讓MBR先飛一會兒 $ 和 $$1981年8月,IBM公司生產(chǎn)了世界上第一臺個人計算機PC 5150,它是個人兼容機的祖先,個人計算機肯定要運行操作系統(tǒng),在這臺計算機上,運行的操作系統(tǒng)是DOS 1.0,不清楚此系統(tǒng)要求的最小內(nèi)存是16KB,還是32KB,反正 PC 5150 BIOS研發(fā)工程師就假定其是32KB的,所以此版本BIOS是按最小內(nèi)存32KB研發(fā)的。
MBR不是隨便放在哪里都行的,首先不能覆蓋已有的數(shù)據(jù),其次,不能過早地被其他數(shù)據(jù)覆蓋。不覆蓋已有數(shù)據(jù),這個好理解。說一下后面這個“其次”。通常,MBR的任務(wù)是加載某個程序(這個程序一般是內(nèi)核加載器,很少有直接加載內(nèi)核的)到指定位置,并將控制權(quán)交給它。所謂的交控制權(quán)就是jmp過去而已。之后MBR 就沒用了,被覆蓋也沒關(guān)系。我說的過早被覆蓋,是指不能讓mbr破壞自己,比如被加載的程序,如內(nèi)核加載器,其放置的內(nèi)存位置若是MBR自己所在的范圍,這不就是破壞自己了嗎,這就是
我所說的“過早”了,怎么也得等MBR執(zhí)行完才行。8086CPU要求物理地址0x0~0x3FF存放中斷向量表,所以此處不能動了,再選新的地方看看。按DOS 1.0要求的最小內(nèi)存32KB來說,MBR希望給人家盡可能多的預(yù)留空間,這樣也是保全自己的作法,免得過早被覆蓋。所以MBR只能放在32KB的末尾。
MBR本身也是程序,是程序就要用到棧,棧也是在內(nèi)存中的,MBR雖然本身只有512字節(jié),但還要為其所用的棧分配點空間,所以其實際所用的內(nèi)存空間要大于512字節(jié),估計1KB內(nèi)存夠用了。
結(jié)合以上三點,選擇32KB中的最后1KB最為合適,那此地址是多少呢?32KB換算為十六進制為0x8000,
減去1KB(0x400)的話,等于0x7c00。這就是倍受質(zhì)疑的0x7c00的由來,這下清楚了。
? 和 和 和$是編譯器NASM預(yù)留的關(guān)鍵字,用來表示當前行和本section的地址,起到了標號的作用,它是NASM提供的,并不是CPU原生支持的,相當于偽指令一樣,對CPU來說是假的。
? 屬于“隱式地”藏在本行代碼前的標號,也就是編譯器給當前行安排的地址,看不到卻又無處不在, 屬于“隱式地”藏在本行代碼前的標號,也就是編譯器給當前行安排的地址,看不到卻又無處不在, 屬于“隱式地”藏在本行代碼前的標號,也就是編譯器給當前行安排的地址,看不到卻又無處不在,在每行都有?;蛘哌@種說法并不是很正確,只有“顯示地”用了$的地方,nasm 編譯器才會將此行的地址公布出來。
? $$指代本section的起始地址,此地址同樣是編譯器給安排的。
? 對于
和
和
和
的意義,是編譯器給安排的地址,默認情況下,它們的值是相對于本文件開頭的偏移量。至于實際安排的是多少,還要看程序員同學是否在
s
e
c
t
i
o
n
中添加了
v
s
t
a
r
t
。這個關(guān)鍵字可以影響編譯器安排地址的行為,如果該
s
e
c
t
i
o
n
用了
v
s
t
a
r
t
=
x
x
x
x
修飾,
的意義,是編譯器給安排的地址,默認情況下,它們的值是相對于本文件開頭的偏移量。至于實際安排的是多少,還要看程序員同學是否在section中添加了vstart。這個關(guān)鍵字可以影響編譯器安排地址的行為,如果該section用了vstart=xxxx修飾,
的意義,是編譯器給安排的地址,默認情況下,它們的值是相對于本文件開頭的偏移量。至于實際安排的是多少,還要看程序員同學是否在section中添加了vstart。這個關(guān)鍵字可以影響編譯器安排地址的行為,如果該section用了vstart=xxxx修飾,
的值則是此
s
e
c
t
i
o
n
的虛擬起始地址
x
x
x
x
。
的值則是此section的虛擬起始地址xxxx。
的值則是此section的虛擬起始地址xxxx。的值是以xxxx為起始地址的順延。如果用了vstart關(guān)鍵字,想獲得本section在文件中的真實偏移
量(真實地址)該怎么做?nasm編譯器提供了這個方法。section.節(jié)名.start
。如果沒有定義section,nasm默認全部代碼同為一個section,起始地址為0。
這里我們需要提前安裝 nasm編譯器 方便后面的使用
只需要在終端輸入指令sudo apt-get install nasm
即刻完成安裝下載
小知識:bin
純二進制文件 cpu可直接食用elf
給操作系統(tǒng)程序加載器食用的
下面就是編寫內(nèi)容了
其實只完成了清空屏幕和輸出字符串的功能
; 主引導程序
;-------------------------------------------------------
section MBR vstart=0x7c00
; 初始化段寄存器
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
mov fs, ax
mov sp, 0x7c00 ;這個時候 ds = es = ss = 0 棧指針指向MBR開始位置
; 初始化段寄存器結(jié)束
; 清屏 利用0x06號功能,上卷全部行,則可清屏。
; -----------------------------------------------------------
;INT 0x10 功能號:0x06 功能描述:上卷窗口
;------------------------------------------------------
;輸入:
;AH 功能號= 0x06
;AL = 上卷的行數(shù)(如果為0,表示全部)
;BH = 上卷行屬性
;(CL,CH) = 窗口左上角的(X,Y)位置
;(DL,DH) = 窗口右下角的(X,Y)位置
;無返回值:
mov ax, 0x600 ; 設(shè)置AH為06, 即功能號= 0x06, 上卷全部行數(shù)
mov bx, 0x700
mov cx, 0 ; 窗口左上角的(0,0)位置
mov dx, 0x184f ;窗口右下角的(24,79)位置, 因為默認為80x25的VGA文本模式, 0x18=24, 0x4f=79
int 0x10
; 清屏結(jié)束
;;;;;;;;; 下面這三行代碼是獲取光標位置 ;;;;;;;;;
;.get_cursor獲取當前光標位置,在光標位置處打印字符.
mov ah, 3 ; 輸入: 3號子功能是獲取光標位置,需要存入ah寄存器
mov bh, 0 ; bh寄存器存儲的是待獲取光標的頁號
; 輸出: ch=光標開始行,cl=光標結(jié)束行
; dh=光標所在行號,dl=光標所在列號
int 0x10
;;;;;;;;; 獲取光標位置結(jié)束 ;;;;;;;;;;;;;;;;
;;;;;;;;; 往光標處打印字符串 ;;;;;;;;;;;
;還是用10h中斷,不過這次是調(diào)用13號子功能打印字符串
mov ax, message ;往ax寫入字符串首地址
mov bp, ax ; es:bp 為串首地址, es此時同cs一致,
; 光標位置要用到dx寄存器中內(nèi)容,cx中的光標位置可忽略
; .get_cursor輸出: ch=光標開始行,cl=光標結(jié)束行
; dh=光標所在行號,dl=光標所在列號
mov cx, 5 ; 顯示字符串長度
mov ax, 0x1301 ; 子功能號13是顯示字符及屬性,要存入ah寄存器,al設(shè)置寫字符方式 al=01: 顯示字符串,光標跟隨移動
mov bx, 0x2 ; bh存儲要顯示的頁號,此處是第0頁,bl中是字符屬性, 屬性黑底綠字(bl = 02h)
int 0x10 ; 執(zhí)行BIOS 0x10 號中斷
;;;;;;;;; 打字字符串結(jié)束 ;;;;;;;;;;;;;;;
jmp $ ; 使程序懸停在此
message db "1 MBR"
times 510-($-$$) db 0 ;times偽指令,重復執(zhí)行db 0 指令 510-($-$$)次
db 0x55,0xaa ;在最后寫入魔數(shù) 0x55 0xaa
編譯并檢驗mbr.bin譯時輸入指令nasm -o mbr.bin mbr.S
如果沒有報錯的話 可以看到你編譯的文件夾中多了一個mbr.bin
的文件
并且我們的mbr引導區(qū)域要求是512字節(jié)
我想為什么最少是512字節(jié)呢
我感覺應(yīng)該是 一個扇區(qū)規(guī)格一般是512字節(jié)
那么mbr剛好占用了一個扇區(qū)則剛好為那么大
之后我們再用指令ls -l
看看當前目錄下文件 和文件的屬性
發(fā)現(xiàn)也恰好是我們要求的512字節(jié) 那應(yīng)該是沒有其他的問題了
如果有問題回來再檢查一下指令
mbr.bin文件布局:
linux命令總結(jié)dd命令詳解
這里是我存儲位置的代碼 供參考
dd if=/home/steven/bochs/mbr.bin of=/home/steven/bochs/hd60M.img bs=512 count=1 conv=notrunc
這里就發(fā)現(xiàn) 已經(jīng)把我們的代碼通過dd指令
這把利刃插進了 我們創(chuàng)建的虛擬磁盤中的0號扇區(qū)
測試成功😀
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧