1. 程式人生 > >全面剖析《自己動手寫作業系統》第四章---載入Loader.bin

全面剖析《自己動手寫作業系統》第四章---載入Loader.bin

上一節我們已經詳細介紹了FAT12檔案系統的資料結構,下面我們需要思考的是兩個問題:1、引導扇區通過怎樣的步驟才能找到檔案;2、如何能夠把檔案內容全都讀出來並載入進入記憶體。

下面我們先解決第一個問題:

1、  如何讀取軟盤?

(1)    我們需要使用BIOS中斷int 13h來讀取軟盤。它的用法如下表所示:


在這裡我們只介紹了2種工作方式,中斷int 13h還有其他的工作方式,如果需要可以自行檢視內容。

(2)    由上表我們可以知道:當讀取某些扇區時,需要柱面(磁軌)號(ch),起始扇區號(cl),磁頭號(dh)。我們如何通過計算得到這些資料呢?


(3)    現在萬事俱備只欠東風了,下面我們就書寫讀取軟盤扇區的函式ReadSector。

首先我們要知道該函式需要什麼引數,這些引數儲存在什麼位置?

引數1:扇區號,儲存在ax中

引數2:要讀取扇區的個數,儲存在cl中

引數3:資料緩衝區,即讀取扇區資料後,將其儲存在什麼位置,用es:bx指向該緩衝區。

即函式的作用:從第ax個Sector開始,將cl個Sector讀入es:bx中。

;-----------------------------------------------------------------------
;函式名:ReadSector
;------------------------------------------------------
;作用:從第ax個Sector開始,將cl個Sector讀入es:bx中
ReadSector:
	;---------------------------------------------
	;怎樣由扇區號求扇區在磁碟中的位置(扇區號->柱面號,起始扇區,磁頭號)
	;---------------------------------------------
	;設扇區號為x
	;                           ┌ 柱面號 = y >> 1
	;       x           ┌ 商 y ┤
	; -------------- => ┤      └ 磁頭號 = y & 1
	;  每磁軌扇區數     │
	;                   └ 餘 z => 起始扇區號 = z + 1

	;闢出兩個位元組的堆疊區間儲存要讀取的扇區數:byte[bp-2]
	push bp
	mov bp, sp
	sub esp, 2			
	mov byte[bp-2], cl		;將引數cl,儲存在byte[bp-2],將要讀取扇區的個數。

	push bx				;儲存bx,因為下面要使用bx進行計算。
	mov bl, [BPB_SecPerTrk]		;bl:除數=18

	;ax儲存的是扇區號,bl是每磁軌扇區數,執行ax/bl=al----ah,
	;即商y在al中,商z在ah中。
	div bl				
	inc ah				;ah(z)++,即起始扇區號=z+1,
	mov cl, ah			;將ah值賦值給cl,中斷int 13h中,cl儲存的恰好是起始扇區號

	mov dh, al			;將al(y),賦值給dh

	shr al, 1			;對al(y)進行右移一位,即得到柱面號=y>>1,
	mov ch, al			;然後將al賦值給ch,在中斷int 13h中,ch儲存著柱面(磁軌)號

	and dh, 1			;將dl(y)進行&1運算,即得到磁頭號=y&1,在中斷int 13h中,dh儲存著
					;磁頭號
	pop bx				;恢復bx值
	;到此為止,“柱面(磁軌)號(ch),起始扇區號(cl),磁頭號(dh),緩衝地址(es:bx)”全部準備就緒
	mov dl, [BS_DrvNum]		;在中斷int 13中,dl儲存著驅動器號。此時dl=[BS_DrvNum]=0
.GoOnReading:
	;下面對ah,al進行賦值,ah=2,al=要讀取的扇區數,前面將引數cl儲存在byte[bp-2],現在從這裡重新獲取
	;並賦值給al。
	mov ah, 2
	mov al, byte[bp-2]
	;中斷int 13一切準備就緒,然後執行int 13
	int 13h
	jc	.GoOnReading		;如果讀取錯誤,CF會被置為1,這時就不停地讀,直到正確為止。

	add esp, 2			;恢復堆疊
	pop bp
	ret

2、  如何在軟盤中尋找Loader.bin檔案

(1)    結合上一節所介紹的FAT12資料結構,從中我們可以知道,要尋找一個檔案,首先需要在根目錄區中尋找該檔案的根目錄條目;然後根據根目錄條目獲取檔案開始簇數(也就是在資料區中儲存的扇區);最後讀取檔案內容到記憶體。

(2)    嗯,是的,下面就讓我們來完成第一步-----在根目錄區中尋找該檔案的根目錄條目。

讓我們開始思考這個問題,

首先要知道根目錄區的開始扇區號是19,也就是說從第19扇區開始,根目錄區佔用扇區總數為14,也就是說,如果不能發現Loader.bin,需要將14個扇區都進行查詢,於是需要一個大的迴圈在外圍,控制著扇區的讀取。

緊接著,我們每讀取一個扇區,一個扇區是512個位元組,一個根目錄條目佔32個位元組,故一個扇區中存在512/32=16個根目錄條目,所以需要新增一個迴圈,控制根目錄條目的變化,從0—16進行迴圈。

最後,針對每一個根目錄條目,我們只是要比較檔名,一個根目錄條目的檔名佔用11個位元組,所以需要對每一個位元組與"LOADER   BIN"中的每一個位元組進行比較,所以還是要新增一個迴圈,來控制字元的變化,即從0—11.

用C語言來表示該問題就是:

for( i = 根目錄區的起始扇區號(19); i < 根目錄區佔有的扇區數(14);  i++)      {

           for( j = 0;j < 一個扇區記憶體儲的根目錄條目個數(512/32=16); j++)    {

                    for(k =0; k < 根目錄條目中檔名佔用的空間(11個字元); k++)      {

                             if(k=10)jmp LABEL_FILENAMEFOUND

                             if(ds:si= es:di) si++; di++;

                             else  break;

                    }

           }

}

(3)    下面讓我們來分析程式碼:

首先需要介紹下面可能需要用到的幾個變數值:

BaseOfLoader           equ  09000h     ;LOADER.BIN被載入到的位置---段地址

OffsetOfLoader        equ  0100h       ;LOADER.BIN被載入到的位置---偏移地址

RootDirSectors         equ  14     ;根目錄佔用空間(BPB_RootEntCnt*32+511)/512

SectorNoOfRootDirectory        equ  19     ;Root Directory 的第一個扇區號

;變數

wRootDirSizeForLoop      dw    RootDirSectors         ;Root Directory佔用的扇區數,在迴圈中會遞減至0

wSectorNo                 dw    0                ;要讀取的扇區號

bOdd                           db     0                ;奇數還是偶數

;字串

LoaderFileName       db     "LOADER  BIN",     0       ;LOADER.BIN之檔名

;呼叫中斷int 13h,實現軟碟機復位
	xor ah, ah
	xor dl, dl
	int 13h	
	
	;下面在A盤的根目錄中尋找LOADER.BIN
	
	;wSectorNo表示要讀取的扇區號,SectorNoOfRootDirectory
	;表示根目錄區的開始扇區號=19
	mov word[wSectorNo], SectorNoOfRootDirectory	
LABEL_SEARCH_IN_ROOT_DIR_BEGIN:
	;wRootDirSizeForLoop=RootDirSectors,表示根目錄佔用的扇區數,即表示要讀取的扇區數;也就是
	;最外部迴圈中的控制變數(相當於i)。
	;判斷根目錄區所有扇區是不是已經讀取完畢,如果讀完表示沒有找到LOADER.BIN,
	;跳入到LABEL_NO_LOADERBIN,否則,減1。
	cmp word[wRootDirSizeForLoop], 0
	jz	LABEL_NO_LOADERBIN			
	dec	word[wRootDirSizeForLoop]

	;為ReadSector函式準備引數,從第ax個Sector開始讀,將cl個Sector讀入es:bx中
	mov ax, BaseOfLoader
	mov es, ax		;es<-BaseOfLoader
	mov bx, OffsetOfLoader	;bx<-OffsetOfLoader,於是es:bx=BaseOfLoader:OffsetOfLoader

	mov ax, [wSectorNo]	;ax<-Root Directory中的某Sector號,表示要讀取的扇區號
	mov cl, 1		;cl表示要讀取扇區個數=1
	call	ReadSector
	;呼叫ReadSector函式之後,es:bx將儲存該扇區資料。

	mov si, LoaderFileName	;ds:si->"LOADER  BIN"
	mov di, OffsetOfLoader	;es:di->BaseOfLoader:OffsetOfLoader=es:bx
				;即es:di指向儲存的該扇區資料
	cld

	;一個扇區是512個位元組,一個根目錄項佔32個位元組,故512/32=16,因此需要比較16個根目錄項的檔名,
	;故賦值dx=16,由dx來控制迴圈次數
	mov dx, 10h
LABEL_SEARCH_FOR_LOADERBIN:
	;判斷dx是否為0,0意味著這個扇區內的所有根目錄項進行比較完畢,然後跳入到下一個扇區,繼續進行比較,
	;dx=0,則跳入LABEL_GOTO_NEXT_SECTOR_IN_ROOT_DIR;否則,dx--
	cmp dx, 0
	jz	LABEL_GOTO_NEXT_SECTOR_IN_ROOT_DIR	
	dec dx
	
	;一個根目錄項的檔名佔用11個位元組,故必須對其每個位元組與"LOADER  BIN"一一對比
	;故賦值cx=11,由cx來控制迴圈次數
	mov cx, 11
LABEL_CMP_FILENAME:
	cmp cx, 0
	jz LABEL_FILENAME_FOUND	;如果cx=0,意味著11個字元都相等,表示找到,跳轉到LABEL_FILENAME_FOUND
	dec cx			;否則,cx--

	lodsb			;ds:si->al,ds:si指向的是字串"LOADER  BIN"
	cmp al, byte[es:di]	;進行一個字元的比較,如果相等,則比較下一個字元,
	jz LABEL_GO_ON		;跳入到LABEL_GO_ON
	jmp LABEL_DIFFERENT	;只要發現有一個不相等的字元就表明本Directory Entry不是我們要
				;找的LOADER.BIN,跳轉到LABEL_DIFFERENT,進如下一個Directory Entry比較。
LABEL_GO_ON:			
	inc di			;將di++,進行一個字元的比較。
	jmp LABEL_CMP_FILENAME	;跳轉到LABEL_CMP_FILENAME,繼續進行檔名比較。

LABEL_DIFFERENT:
	;di&=E0是為了讓它指向本條目開頭,di初始化為某個條目開頭,
	;在比較過程中,會將它不斷增1,當失敗之後,必須進行重新初始化
	;因為一個條目佔用32個位元組,故and di,0FFE0h   add di, 20h
	;之後,di就指向了下一個條目
	and di, 0FFE0h				
	add di, 20h	

	;重新初始化si,使其指向"LOADER  BIN"的開始位置
	mov si, LoaderFileName			
	jmp LABEL_SEARCH_FOR_LOADERBIN	;跳轉到LABEL_SEARCH_FOR_LOADERBIN

LABEL_GOTO_NEXT_SECTOR_IN_ROOT_DIR:	
	add word[wSectorNo], 1		;將要讀取的扇區號+1,進行下一個扇區的比較
	jmp LABEL_SEARCH_IN_ROOT_DIR_BEGIN	;跳轉到LABEL_SEARCH_IN_ROOT_DIR_BEGIN,開始一個扇區的比較

	;如果最後沒有找到"LOADER   BIN",則顯示“NO LOADER”字串來表示。
LABEL_NO_LOADERBIN:
	mov dh, 2				;"NO LOADER"
	call DispStr				;顯示字串
%ifdef	_BOOT_DEBUG_
	mov dh, 2				;"NO LOADER"
	call DispStr				;顯示字串
	mov ax, 4C00h
	int 21h					;沒有找到LOADER.BIN,返回到DOS
%else	
	jmp $					;沒有找到LOADER.BIN,死迴圈在這裡
%endif

	;如果找到"LOADER   BIN",則跳轉到LABEL_FILENAME_FOUNT,然後進行第二步驟,從
	;Directory Entry中讀取檔案在資料區的開始簇號。
LABEL_FILENAME_FOUND:

(4)    對上面這段程式碼畫出它的簡易流程圖如下:


3、  如何將Loader.bin檔案載入到記憶體?

現在我們已經有了Loader.bin的起始扇區號,我們需要用這個扇區號來做兩件事情:一件是把起始扇區裝入記憶體,另一件則是通過它找到FAT中的項,從而找到Loader佔用的其餘所有扇區。

此時裝入一個扇區對我們來說已經是很輕鬆的事了,可從FAT中找到一個項還是多少有些麻煩,下面我們就根據扇區號去FAT表中找到相應的項。在這裡,將要寫一個函式GetFATEntry,函式的輸入就是扇區號(ax),輸出則是其對應的FAT項的值(ax)。

我們一起來思考這個函式如何去實現,我們知道了扇區號x,然後我們去FAT1中尋找x所對應的FATEntry,我們已經知道一個FAT項佔1.5個位元組。所以我們用x*3/2=y………z,y為商(偏移量)(位元組),相對於FAT1的初始位置的偏移量;Z為餘數(0或者1),是判斷FATEntry是奇數還是偶數,0表示偶數,1表示奇數。然後我們讓y/512=m………n,m為商,n為餘數,此時m為FATEntry所在的相對扇區,n為在此扇區內的偏移量(位元組)。因為FAT1表前面還有1個引導扇區,所以FATEntry所在的實際扇區號為m+1。然後讀取m+1和m+2兩個扇區,然後在偏移n個位元組處,取出FATEntry,相當於讀取兩個位元組。此時再利用z,如果z為0的話,此FAT項為前一個位元組和後一個位元組的後4位,如果z為1的話,此FATEntry取前一個位元組的前4位和後一個位元組。

下面我們實現GetFATEntry函式,函式的輸入就是扇區號,輸出則是其對應的FATEntry的值。

;-----------------------------------------------------
;函式名:GetFATEntry
;-----------------------------------------------------
;作用:	找到序號為ax的Sector在FAT中的條目,結果放在ax中,需要注意的是,中間需要讀FAT的扇區es:bx處,
;	所以函式一開始儲存了es和bx
GetFATEntry:
	push es
	push bx
	push ax
	
	;在BaseOfLoader後面留出4K空間用於存放FAT
	mov ax, BaseOfLoader
	sub ax,0100h
	mov es, ax	;此時es-> (BaseOfLoader - 100h)

	pop ax		;ax儲存的是要讀取的扇區號
	mov byte[bOdd], 0
	;ax是要讀取的扇區號,如何獲得該扇區號在FAT1中的FATEntry
	;因為每個FATEntry佔有1個半位元組,所以計算ax*3/2,找到該FATEntry所在FAT1中的偏移量
	mov bx, 3
	mul bx
	mov bx, 2
	div bx		
	;ax*3/2=ax...dx,商為ax表示該FATEntry在FAT1中的偏移量,dx的值為(0或者1),
	;0表示該FATEntry為偶數,1表示該FATEntry為奇數,
	cmp dx, 0
	jz	LABEL_EVEN
	;我們使用byte[bOdd]來儲存dx的值,也就是該FATEntry是奇數項還是偶數項。
	mov byte[bOdd], 1
LABEL_EVEN:
	xor dx, dx	
	;此時ax中儲存著FATEntry在FAT1中的偏移量,下面來計算FATEntry
	;在哪個個扇區中(FAT1佔用9個扇區)。
	;ax/BPB_BytsPerSec=ax/512=ax...dx,商ax儲存著該FATEntry所在FAT1表的第幾個扇區,
	;餘數dx儲存著該FATEntry在該扇區內的偏移量。
	mov bx, [BPB_BytsPerSec]
	div bx		

	push dx		;將dx儲存在堆疊中.
	mov bx, 0	;es:bx=(BaseOfLoader-100):00=(BaseOfLoader-100h)*10h
	;我們知道ax是FATEntry所在FAT1中的相對扇區,而FATEntry所在的實際扇區,需要加上
	;FAT1表的開始扇區號,即加1,之後ax就是FATEntry所在的實際扇區
	add ax, SectorNoOfFAT1			
	mov cl, 2
	;讀取FATEntry所在的扇區,一次讀2個,避免在邊界發生錯誤,
	;因為一個FATEntry可能跨越兩個扇區
	call ReadSector		
	;從堆疊中彈出dx,FATEntry所在扇區的偏移量,將其與bx相加,此時es:bx指向的是該FATEntry所佔用
	;的兩個位元組空間
	pop dx
	add bx, dx
	;讀取該FATEntry
	mov ax, [es:bx]
	;下面是對bOdd進行判斷,如果其為0,則表示FATEntry為偶數,此時需要取byte1和byte2的後4位,
	;由於在80x86下,從記憶體中讀取資料之後,byte2在前,byte1在後。
	;所以當FATEntry為偶數時,需要將ax&0FFF,將byte2的前4位置0.
	;反之,如果bOdd為1,則表示FATEntry為奇數,此時需要取得byte1中的前4位和byte2.
	;所以,需要將ax右移4位,將byte1的後四位移除。
	cmp byte[bOdd], 1
	jnz	LABEL_EVEN_2
	shr ax, 4
LABEL_EVEN_2:
	and ax, 0FFFh

	;此時ax儲存的是FATEntry的值
LABEL_GET_FAT_ENTRY_OK:
	pop bx
	pop es
	ret
;--------------------------------------------------------------------

下面我們開始載入Loader.bin進入記憶體。

首先我們從根目錄區中的Loader.bin的條目,獲取檔案的起始扇區號,然後加上BPB_RsrvSecCnt+BPB_FATSz16*2-2+RootDirSectors=1+(9*2)+14-2=31,,其中DeltaSectorNo=BPB_RsrvSecCnt+BPB_FATSz16*2-2=17。得到的結果才是檔案的實際的起始扇區。獲得起始扇區後,我們就可以呼叫ReadSector來讀取扇區了。然後從FAT1表中獲取FATEntry的值,判斷是否為0FFFh,如果是,結束載入;如果不為0FFFh,意味著該檔案沒有讀取完成,需要讀取下一個扇區,此時的FATEntry的值,就是下一個扇區號,再將其轉換為實際扇區號,再進行讀取。

下面是函式的實現和註釋

LABEL_FILENAME_FOUND:			;找到了LOADER.BIN後便來到這裡繼續
	mov ax, RootDirSectors		;根目錄區所佔用扇區數=14
	and di, 0FFE0h			;di->當前Directory Entry的開始位置
	add di, 01Ah			;di->此條目對應的開始簇號,DIR_FstClus
	mov cx, word[es:di]		;將開始簇號儲存在暫存器cx中
	push cx				;將cx入棧
	;實現cx+RootDirSectors+DeltaSectorNo之後,此時cx儲存著檔案的實際開始扇區號,
	;即資料區內的扇區
	add cx, ax			
	add cx, DeltaSectorNo			

	mov ax, BaseOfLoader
	mov es, ax
	mov bx, OffsetOfLoader		;es:bx=BaseOfLoader:OffsetOfLoader
	mov ax, cx			;ax表示要讀取的扇區號

LABEL_GOON_LOADING_FILE:
	push ax
	push bx
	mov ah, 0Eh
	mov al, '.'
	mov bl, 0Fh
	int 10h				
	pop bx
	pop ax
	;每讀一個扇區就在”Booting   “後面打一個點,形成這樣的效果:Booting......

	;繼續為ReadSector函式的引數做準備,cl=1,表示要讀取一個扇區
	mov cl, 1		
	call ReadSector

	pop ax		;讀完一個扇區之後,然後重新讀取此Sector在FAT中的序號
	call GetFATEntry	
	cmp ax, 0FFFh
	jz	LABEL_FILE_LOADED	
	;如果讀取的FAT值為FFF,表示該扇區為該檔案的最後一個扇區,
	;因此結束載入,也就是載入成功
	;如果讀取的FAT表中的值不是FFF,則表示還有扇區,故儲存下一個扇區序號
	push ax		
				
	mov dx, RootDirSectors
	add ax, dx
	add ax, DeltaSectorNo
	add bx, [BPB_BytsPerSec]
	;為call ReadSector的引數做準備,es:bx表示要快取的地址,
	;ax表示要讀取的扇區號=DirEntry中的開始Sector號+根目錄佔用Sector數目+DeltaSectorNo
	;進入下一次迴圈。
	jmp LABEL_GOON_LOADING_FILE

LABEL_FILE_LOADED:
	mov dh, 1				;"Ready."
	call DispStr				;顯示字串


相關推薦

全面剖析自己動手作業系統---載入Loader.bin

上一節我們已經詳細介紹了FAT12檔案系統的資料結構,下面我們需要思考的是兩個問題:1、引導扇區通過怎樣的步驟才能找到檔案;2、如何能夠把檔案內容全都讀出來並載入進入記憶體。 下面我們先解決第一個問題: 1、  如何讀取軟盤? (1)    我們需要使用BIOS中斷int 13h來讀取軟盤。它的用法如下表所

全面剖析自己動手作業系統---程序

在一開始學習程序的時候,我們大概每個人都會遇到過這樣的問題,下面就讓我們帶著這些問題來認識認識程序。 1、程序是什麼? 2、什麼是多程序? 3、執行一個程序需要什麼? 4、多程序之間是如何排程的? 5、程序的上下文環境是什麼? 6、如何建立一個新的程序? 一、程序是什麼?

全面剖析自己動手作業系統》的pmtest1.asm

##段機制輕鬆體驗 段機制輕鬆體驗 記憶體定址: 真實模式下的記憶體定址: 讓我們首先來回顧真實模式下的定址方式 段首地址×16+偏移量 = 實體地址 為什麼要×16?因為在8086CPU中,地址線是20位,但暫存器是16位的,最高定址64KB,它無法定址到1M記憶體。於是,Int

自己動手作業系統2版:簡介

    今年剛畢業,從事電商java開發崗位,一直對著需求編碼的話感覺技術長進不會太大,碰巧對作業系統這塊有些許興趣,就想著學習這塊的知識,如果學得好的話看將來能不能轉型成作業系統,系統安全或者c/c++相關的開發人員。     於是在網上找了很多資料,其實大部分都是理論書

自己動手作業系統 pmtest1——從真實模式到保護模式

摘要:本節,我們將學習如何從真實模式進入保護模式,剖析pmtest1.asm原始碼。詳細講解如何從保護模式進入真實模式。 1.標頭檔案編寫: 這一部分,你需要把一些關鍵物理器件和資料結構的佈局記在腦子裡 GDT描述符:32b段基地址(B2、B3、B4、B7)+20b段限長

自己動手作業系統

                  用一個月左右的時間讀了《自己動手寫作業系統》,這是一本讓人讀著很過癮,卻也特別累的一本書。  對作業系統的興趣由來已久,只是一直未能找到入門之徑。作業系統教材是個令人生畏的東西,它可以告訴人有什麼,卻不能告訴人為什麼,從那裡瞭解的作業系統有如盲人摸到的象,得到各個部分,卻不

自己動手ORM框架():關係對映配置—Id屬性

上一篇中完成了Table自定義屬性的功能,現在來完成Id,因為一張表最主要的是結構就是表名(Table name)、主鍵(Id)、列(Column)、主鍵生成策略。 Id自定義屬性的用法程式碼塊1-1: [Table(name="Studen

自己動手作業系統學習筆記(一)

早就想抽時間系統的學習一下於淵寫的《自己動手寫作業系統》,但始終沒空,現在忙活一年,年底終於有點空閒,今天終於把書裡的第一個例子在windows下搞成功.這裡把實驗步驟記錄一下. 實驗全部在win7環境下進行,用到軟體版本和下載地址為: Win64位Bochs 下載地址:

自己動手作業系統(五)

  這裡開始就進入了core的啟動流程(類似於linux的kernel)。core的入口函式是start_core,如何定義如何函式呢?我們這裡通過編譯指令就可以了。參看下面的配置檔案: ENTRY (start_core) SECTIONS { . = 0x10

自己動手作業系統(二)

    系統啟動流程簡單來說就是下面的順序:    ===============================    1.BIOS:開機主動執行的韌體,會認識到第一個可開機的裝置    2.MBR:第一個可開機裝置的第一個扇區內的主引導分割槽塊,內包含引導載入程式  

自己動手作業系統載入程式成功寫入優盤啟動電腦

原文:http://freesoftman.iteye.com/blog/629598 輸入命令: nasm boot.asm -o boot.bin 一會兒就生成了一個映象檔案boot.bin. 該檔案就是我所謂的作業系統了。哈哈!其實只是一個boot sect

自己動手作業系統之1:bochs初步使用

0x00 前言 自己動手寫作業系統,自然需要一個承載程式的執行環境,這一章記錄我使用bochs遇到的坑,凌晨十二點半才填完坑。 這次記錄的是使用bochs完整實現一個最簡單的作業系統(其實根本不算作業系統,只是通過硬碟啟動個mbr程式)。 0x01 b

自己動手作業系統二(編寫核心Hello World 教程)

   By EvilBinary 小E     本文用到的boot.s 和setup.s 兩個檔案見本blog MyOs  分類相關文章。     我們編寫start.s 來啟動初始化資訊,然後進入main.c核心程式碼,然後顯示Evilbinary os字樣 //star

自己動手作業系統(一)

從去年就想好好的讀一下這本書,跟著書上做一下,但是給耽擱了,現在就好好的開始探索這麼書吧! 雖然我很想在這裡吹一段這本書有多麼的厲害,但是!我第一章都沒有看完,吹不了!!!等我讀的個七七八八再回來吹吧。 我是在搜尋嵌入式的學習路線中發現的這本書,當時他們說這本書很有趣,操作

計算機作業系統-:儲存器管理

儲存層次至少三級:CPU暫存器,主存,輔存。 暫存器和主儲存器又被稱為可執行儲存器。(可使用一條load或store指令對可執行儲存器訪問,但輔存需要通過io裝置實現) 主儲存器簡稱記憶體或主存,用於儲存程序執行時的程式和資料,也簡稱可執行儲存器。 暫存器具有與處理機相同的速度,對暫存器訪問速度最快,完

作業系統 1 程式的裝入和連結

1、建立程序的第一件事:將程式和資料裝入記憶體。 2、程式進記憶體的一般過程:  編譯程式:( 高階語言編譯為機器語言)形成目標模組。 連結程式:將形成的一組目標模組,及它們需要的庫函式連結在一起,形成一個完整的裝入模組。 裝入load:由裝入程式將裝入

作業系統 3 分頁、分段、段頁式儲存管理 +作業題

一、分頁儲存管理方式 1、(物理)塊:記憶體劃分成多個小單元,每個單元K大小         頁面:作業也按K單位大小劃分成片         物理劃分塊的大小 = 邏輯劃分的頁的大小

作業系統 2 儲存器管理 連續分配方式

1)單一連續分配: 記憶體分為系統區和使用者區兩部分 2)固定分割槽分配: 把記憶體分為一些大小相等或不等的分割槽,每個應用程序佔用一個分割槽。作業系統佔用其中一個分割槽。(劃分為幾個分割槽,便只允許幾道作業併發)    建立一記錄相關資訊的分割槽表(或分割槽連結

作業系統--儲存器管理_1

程式進記憶體的一般過程: 編譯compiler:編譯程式:將使用者原始碼編譯成若干個目標模組。 連結link:連結程式:將形成的一組目標模組,及它們需要的庫函式連結在一起,形成一個完整的裝入模組。 裝入load:由裝入程式將裝入模組裝入記憶體,構造PCB,形成程序,開始執行(使用實體地址)。

作業系統--儲存器管理_2

儲存管理的離散分配方式 基本分頁儲存管理方式 離散分配記憶體: 作業按規定大小劃分成小份;記憶體也按同樣大小劃分成小份 作業的任一小份可分散放入記憶體任意未使用的小份 分頁的目的:更細粒度的處理空間,減少粗放管理的浪費或開銷問題。 "頁"的概念:記憶體劃分成多個小單元,每個單元K