《30天自制操做系統》筆記3 --- (Day2 上節)徹底解析文件系統 FAT32中文版分析+補充(2) FAT32中文版分析+補充(2)

Day2 彙編語言學習與Makefile入門html

 本文僅帶着思路,研究源碼裏關於文件系統的參數linux

 關於day2主程序部分及更多內容,請看《30天自制操做系統》筆記架構

 導航ide

  1. 發現學習中的變化
  2. 源碼差別分析
  3. FAT12/FAT16/FAT32相關資料
  4. 開始全面分析

 

發現學習中的變化

day1代碼(只簡單地使用DB DW DD RESB指令) 工具

 1 ; hello-os
 2 ; TAB=4
 3 
 4 ; 標準FAT12格式軟盤專用的代碼 Stand FAT12 format floppy code
 5 
 6         DB        0xeb, 0x4e, 0x90
 7         DB        "HELLOIPL"        ; 啓動扇區名稱(8字節)
 8         DW        512                ; 每一個扇區(sector)大小(必須512字節)
 9         DB        1                ; 簇(cluster)大小(必須爲1個扇區)
10         DW        1                ; FAT起始位置(通常爲第一個扇區)
11         DB        2                ; FAT個數(必須爲2)
12         DW        224                ; 根目錄大小(通常爲224項)
13         DW        2880            ; 該磁盤大小(必須爲2880扇區1440*1024/512)
14         DB        0xf0            ; 磁盤類型(必須爲0xf0)
15         DW        9                ; FAT的長度(必??9扇區)
16         DW        18                ; 一個磁道(track)有幾個扇區(必須爲18)
17         DW        2                ; 磁頭數(必??2)
18         DD        0                ; 不使用分區,必須是0
19         DD        2880            ; 重寫一次磁盤大小
20         DB        0,0,0x29        ; 意義不明(固定)
21         DD        0xffffffff        ; (多是)卷標號碼
22         DB        "HELLO-OS   "    ; 磁盤的名稱(必須爲11字?,不足填空格)
23         DB        "FAT12   "        ; 磁盤格式名稱(必??8字?,不足填空格)
24         RESB    18                ; 先空出18字節
25 
26 ; 程序主體
27 
28         DB        0xb8, 0x00, 0x00, 0x8e, 0xd0, 0xbc, 0x00, 0x7c
29         DB        0x8e, 0xd8, 0x8e, 0xc0, 0xbe, 0x74, 0x7c, 0x8a
30         DB        0x04, 0x83, 0xc6, 0x01, 0x3c, 0x00, 0x74, 0x09
31         DB        0xb4, 0x0e, 0xbb, 0x0f, 0x00, 0xcd, 0x10, 0xeb
32         DB        0xee, 0xf4, 0xeb, 0xfd
33 
34 ; 信息顯示部分
35 
36         DB        0x0a, 0x0a        ; 換行兩次
37         DB        "hello, world"
38         DB        0x0a            ; 換行
39         DB        0
40 
41         RESB    0x1fe-$            ; 填寫0x00直到0x001fe
42 
43         DB        0x55, 0xaa
44 
45 ; 啓動扇區之外部分輸出
46 
47         DB        0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
48         RESB    4600
49         DB        0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
50         RESB    1469432
View Code

 

如下是day2代碼(使用了真正的彙編指令,編譯出來的文件和day1的徹底一致,我用二進制文件對比工具對比過了)oop

 1 ; hello-os
 2 ; TAB=4
 3 
 4         ORG        0x7c00            ; 指明程序裝載地址
 5 
 6 ; 標準FAT12格式軟盤專用的代碼 Stand FAT12 format floppy code
 7 
 8         JMP        entry
 9         DB        0x90
10         DB        "HELLOIPL"        ; 啓動扇區名稱(8字節)
11         DW        512                ; 每一個扇區(sector)大小(必須512字節)
12         DB        1                ; 簇(cluster)大小(必須爲1個扇區)
13         DW        1                ; FAT起始位置(通常爲第一個扇區)
14         DB        2                ; FAT個數(必須爲2)
15         DW        224                ; 根目錄大小(通常爲224項)
16         DW        2880            ; 該磁盤大小(必須爲2880扇區1440*1024/512)
17         DB        0xf0            ; 磁盤類型(必須爲0xf0)
18         DW        9                ; FAT的長度(必??9扇區)
19         DW        18                ; 一個磁道(track)有幾個扇區(必須爲18)
20         DW        2                ; 磁頭數(必??2)
21         DD        0                ; 不使用分區,必須是0
22         DD        2880            ; 重寫一次磁盤大小
23         DB        0,0,0x29        ; 意義不明(固定)
24         DD        0xffffffff        ; (多是)卷標號碼
25         DB        "HELLO-OS   "    ; 磁盤的名稱(必須爲11字?,不足填空格)
26         DB        "FAT12   "        ; 磁盤格式名稱(必??8字?,不足填空格)
27         RESB    18                ; 先空出18字節
28 
29 ; 程序主體
30 
31 entry:
32         MOV        AX,0            ; 初始化寄存器
33         MOV        SS,AX
34         MOV        SP,0x7c00
35         MOV        DS,AX
36         MOV        ES,AX
37 
38         MOV        SI,msg
39 putloop:
40         MOV        AL,[SI]
41         ADD        SI,1            ; 給SI加1
42         CMP        AL,0
43         JE        fin
44         MOV        AH,0x0e            ; 顯示一個文字
45         MOV        BX,15            ; 指定字符顏色
46         INT        0x10            ; 調用顯卡BIOS
47         JMP        putloop
48 fin:
49         HLT                        ; 讓CPU中止,等待指令
50         JMP        fin                ; 無限循環
51 
52 msg:
53         DB        0x0a, 0x0a        ; 換行兩次
54         DB        "hello, world"
55         DB        0x0a            ; 換行
56         DB        0
57 
58         RESB    0x7dfe-$        ; 填寫0x00直到0x001fe
59 
60         DB        0x55, 0xaa
61 
62 ; 啓動扇區之外部分輸出
63 
64         DB        0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
65         RESB    4600
66         DB        0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
67         RESB    1469432
View Code

 注意:RESB    0x7dfe-$        ; 填寫0x00直到0x001fe這一行沒有錯,編譯出來的二進制的確能和day一致post

因此咱們要研究出:day2與day1彙編代碼對應關係,如MOV AX,0是怎麼表達成二進制的學習

 

 

首先是這個ORG 0x7c00,對比後面的測試

0x7dfe-$居然和0x1fe-$同樣,並且7dfe與1fe恰好差了7c00,結合註釋,推斷這個ORG規定了在內存中被開始加載的地址url

ORG 0x7c00  就是讓主板從內存0x7c00處開始加載咱們寫的helloos.img。

能夠猜得出,day1版本是用了相對地址,在源碼中 把helloos.img的開頭用0x0000表示,因此實際在哪一個內存地址被加載 應該是由彙編編譯器或主板BIOS決定的,

而day2用了絕對地址,指定helloos.img要在內存0x7c00處加載。

 

先找不一樣

 ↑↑↑上半部分源碼,      下半部分源碼↓↓↓

 FAT資料

這個0xeb 0x4e 0x90是什麼意思咱們還不知道,他就用匯編改了,因此有重點,搜索一下發現了一篇:

[第1天] 二進制代碼和nasm

file allocation table - 16bit: http://www.beginningtoseethelight.org/fat16/index.htm 以及

FAT32中文版分析+補充(1) 和 FAT32中文版分析+補充(2)

這裏引用這篇文章裏的 BS_jmpBoot    (跳轉指令),如圖

因此helloos可能不能在非Intel x86架構的主板上工做?

好了,看完資料,咱們發現書中的啓動區源碼是爲FAT12格式軟盤服務的,因此若是之後咱們要作fat32(甚至須要主板驅動支持的exfat、NTFS),就須要本身去找對應分區格式的啓動區參數。

 


 

 開始全面分析

從day1的啓動區開始吧,再貼一次圖片,方便對比

 

 Day1的helloOS.nas前半部分

 

 後半部分(程序主體、信息顯示部分、啓動扇區之外部分輸出)

 

 

 開頭的 eb 4e 90,結合fat啓動區分區分析圖,能夠知道在Intel x86裏這就是JMP 0x4e,而3e到4f是都是零,4e恰好位於程序主體前面的兩個0x00。那這裏4e能不能寫成3e到50裏任意hex呢?用改img文件的十六進制就能夠測試。

day2裏面把程序主體寫做entry,因此源碼裏的JMP entry就和0xeb 0x4e 0x90做用相同了:

Ps.做者在書裏解釋說是JMP 0x7c50

 而JMP entry下面的東西是fat12的分區扇區參數。(分區扇區參數的都是計算機行業規定,通常不能本身隨便改的),如圖(引用自FAT32中文版分析+補充(1) )

 

恰好就對應着咱們的

0x00到0x10(0x0F是15,0x10就是16,偏移量16就是0x10)

偏移量 啓動分區[boot sector] helloos裏的值 大小 helloos值的說明
0x0 BS_jmpBoot(跳轉指令) 4E 3bits 跳轉到指定地址4E
0x3 BS_OEMName(OEM、OS版本號) HELLOIPL 8bits 操做系統名字

零扇區BPB[BIOS Parameter Block]從下面內容能夠看出它的做用,即儲存了文件系統的參數信息

偏移量 零扇區BPB helloos裏的值 大小 helloos值的說明
0xB BPB_BytesPersec(每扇字節數) 512 2bits

可填512,1024,2048,4096,

因爲書裏用的軟盤,因此是512

0xC BPB_SecPerClus(每簇扇區數) 1 1bit 2^n, (n>=0)
0xD BPB_RsvdSecCnt(保留扇區數) 1 2bits FAT12/16硬性規定爲1,FAT32爲32
0x10 BPB_NumFATs(FAT副本數) 2 1bit FAT 建議寫2

 

從0x11到20

偏移量   helloos裏的值 大小 helloos值的說明
0x11  BPB_RootEntCnt(根目錄項數)  224  2bits  FAT12/16爲32的偶數倍,FAT32必須爲0
 0x13  BPB_TotSec16(總扇區數)  2880  2bits  FAT12/16填總扇區數
 0x15  BPB_Media(媒體描述符)  0xf0  1bit  可移動存儲介質常用0xF0
 0x16  BPB_FATSz16(每FAT扇區數)  9  2bits  FAT12/16一個FAT表所佔的扇區數
 0x18  BPB_SecPerTrk(每磁道扇區數)  18  2bits  每磁道扇區數,這個數用於BIOS中斷0x13
 0x1A  BPB_NumHeads(磁頭數)  2  2bits  磁頭數,也用於0x13中斷
 0x1C  BPB_HiddSec(隱藏扇區數)  0  4bits

 FAT分區以前所隱藏的扇區數,

調用0x13中斷可獲得,

對於沒有分區的儲存介質,此域必須爲0,

具體使用什麼由操做系統決定

 0x20  BPB_TotSec32(總扇區數)  2880  4bits

 FAT12/16中,如果總扇區>=10000(64KB)

,那麼此域就是總扇區

註解:這裏的磁頭數等東西指的是邏輯上的,若是沒有實體,那麼指的就是邏輯磁頭數。其餘參數同理

 

 對比一下源碼,這下子就明明白白了

 1 ; hello-os
 2 ; TAB=4
 3 
 4         ORG        0x7c00            ; 指明程序裝載地址
 5 
 6 ; 標準FAT12格式軟盤專用的代碼 Stand FAT12 format floppy code
 7 
 8         JMP        entry
 9         DB        0x90
10         DB        "HELLOIPL"        ; 啓動扇區名稱(8字節)
11         DW        512                ; 每一個扇區(sector)大小(必須512字節)
12         DB        1                ; 簇(cluster)大小(必須爲1個扇區)
13         DW        1                ; FAT起始位置(通常爲第一個扇區)
14         DB        2                ; FAT個數(必須爲2)
15         DW        224                ; 根目錄大小(通常爲224項)
16         DW        2880            ; 該磁盤大小(必須爲2880扇區1440*1024/51217         DB        0xf0            ; 磁盤類型(必須爲0xf0)
18         DW        9                ; FAT的長度(必??9扇區)
19         DW        18                ; 一個磁道(track)有幾個扇區(必須爲18)
20         DW        2                ; 磁頭數(必??221         DD        0                ; 不使用分區,必須是0
22         DD        2880            ; 重寫一次磁盤大小
23 
24 ;    以上部分就是表格裏描述的
25 ;     下面這部分還沒介紹,不急
26         DB        0,0,0x29        ; 意義不明(固定)
27         DD        0xffffffff        ; (多是)卷標號碼
28         DB        "HELLO-OS   "    ; 磁盤的名稱(必須爲11字?,不足填空格)
29         DB        "FAT12   "        ; 磁盤格式名稱(必??8字?,不足填空格)
30         RESB    18                ; 先空出18字節
31 
32 ; 程序主體
View Code

剩餘部分的詳細說明在FAT32中文版分析+補充(2),固然也能夠看下圖的簡單說明

此圖資料來自:【文件系統】FAT12文件系統簡介

Ps.其實還能夠用c語言來作一個文件系統寫入工具 (用結構體儲存分區信息)

 

最後搜了好久,發現百度百科也有一點記錄:https://baike.baidu.com/item/FAt12#ref_[1]_273750 ,維基百科應該有更詳細,惋惜英文版也被牆了....

經過蒐集資料,咱們如今再也不僅僅只能作FAT12,還能作FAT32的啓動甚至是exfat ext ntfs的

 

到這裏,咱們明白了總體

  第一部分就是啓動區描述和文件系統(書中例子爲fat12)

  第二部分纔是系統和程序(HelloWorld)

 

 

好,讓咱們把精力放在第二部分吧:《30天自制操做系統》筆記4 --- (Day2 下節)瞭解如何寫彙編HelloWorld程序

 

待續更新...

相關文章
相關標籤/搜索