linux學習(一)--啟動檔案bootsect.s
阿新 • • 發佈:2018-11-25
這是linux由BIOS載入後執行的第一段的啟動程式程式碼,即檔案 boot/bootsect.s
1 .globl begtext, begdata, begbss, endtext, enddata, endbss
2 .text
3 begtext:
4 .data
5 begdata:
6 .bss
7 begbss:
8 .text
9
10 //規劃記憶體,由BIOS執行
11 SETUPLEN = 4 ! nr of setup-sectors
12 BOOTSEG = 0x07c0 ! original address of boot-sector
13 INITSEG = 0x9000 ! we move boot here - out of the way
14 SETUPSEG = 0x9020 ! setup starts here
15 SYSSEG = 0x1000 ! system loaded at 0x10000 (65536).
16 ENDSEG = SYSSEG + SYSSIZE ! where to stop loading
17
18 ! ROOT_DEV: 0x000 - same type of floppy as boot.
19 ! 0x301 - first partition on first drive etc
20 ROOT_DEV = 0x306
21
22 //複製自身到指定地址
23 entry _start
24 _start:
25 mov ax,#BOOTSEG ;0x07c0,啟動程式碼所在位置放入ax
26 mov ds,ax ;將啟動程式碼與ds暫存器關聯
27 mov ax,#INITSEG ;啟動程式碼要被複制到的目的地址
28 mov es,ax ;將目的地址與es暫存器關聯
29 mov cx,#256 ;迴圈控制位元組,512位元組
30 sub si,si ;si清零,ds:si即0x07c00
31 sub di,di ;di清零,es:si即0x90000
32 rep ;迴圈直到cx==0
33 movw ;將ds:si複製到es:di
34 jmpi go,INITSEG;跳轉到go標誌處
35
36 //由於啟動程式碼複製到了新位置,需要更改相應暫存器的值
37 go: mov ax,cs ;將當前的cs值賦值給各暫存器,方便接下來程式繼續執行
38 mov ds,ax
39 mov es,ax
40 ! put stack at 0x9ff00.
41 mov ss,ax ;開始引入棧
42 mov sp,#0xFF00 ;棧空間的起始地址為0x9ff00
43
44 //開始載入setup塊
45 load_setup:
46 mov dx,#0x0000 ;為後面進入中斷處理傳入相應資訊
47 mov cx,#0x0002
48 mov bx,#0x0200
49 mov ax,#0x0200+SETUPLEN
50 int 0x13 ;進入中斷服務程式,將setup.s對應的程式載入至記憶體指定地址
51 jnc ok_load_setup;cf標誌暫存器為0就跳轉至ok_load_setup塊
52 mov dx,#0x0000
53 mov ax,#0x0000 ;cf!=0則重新設定傳入資訊,進入中斷
54 int 0x13
55 j load_setup
56
57 //取磁碟驅動器引數
58 ok_load_setup:
59 mov dl,#0x00
60 mov ax,#0x0800 ;磁碟引數
61 int 0x13
62 mov ch,#0x00
63 seg cs ;下一條語句的運算元在cs所指段中
64 mov sectors,cx ;儲存每磁軌扇區數
65 mov ax,#INITSEG
66 mov es,ax
67
68 //由於載入程式碼量龐大,這時在螢幕上輸出 "Loding system..."
69 mov ah,#0x03 ;讀游標位置
70 xor bh,bh
71 int 0x10
72
73 mov cx,#24 ;共24個字元
74 mov bx,#0x0007 ;! page 0, attribute 7 (normal)
75 mov bp,#msg1 ;指向要顯示字串的地址
76 mov ax,#0x1301 ;! write string, move cursor
77 int 0x10
78
79 //載入第三批程式碼,即剩餘核心程式碼,時間較長
80 mov ax,#SYSSEG ;核心程式碼被載入到的地址
81 mov es,ax ;! segment of 0x010000
82 call read_it ;讀取磁碟上的system模組
83 call kill_motor;關閉驅動器
84
85 //確定使用哪個根檔案系統裝置,若指定了裝置(開始的ax!=0),就直接用給定的裝置
86 seg cs
87 mov ax,root_dev
88 cmp ax,#0 ;比較ax是否為0
89 jne root_defined ;ax!=0跳轉
90 seg cs
91 mov bx,sectors ;取磁軌扇區數,如果sectors==15,則說明是1.2Mb驅動器
92 ;如果sectors==18,則說明是1.44Mb驅動器
93 mov ax,#0x0208 ;! /dev/ps0 - 1.2Mb
94 cmp bx,#15 ;判斷磁軌扇區數是否為15
95 je root_defined
96 mov ax,#0x021c ;! /dev/PS0 - 1.44Mb
97 cmp bx,#18
98 je root_defined
99 undef_root: ;如果都不是,死迴圈
100 jmp undef_root
101 root_defined:
102 seg cs
103 mov root_dev,ax ;儲存裝置號到資料區
104
105 //本程式執行完畢,跳轉到已經載入在記憶體的setup處繼續執行
106 jmpi 0,SETUPSEG
107
108 //以下是被呼叫的塊的詳細程式碼,以及顯示在螢幕的文字資訊的資料安排
109 sread: .word 1+SETUPLEN ! sectors read of current track
110 head: .word 0 ! current head
111 track: .word 0 ! current track
112
113 read_it:
114 mov ax,es
115 test ax,#0x0fff
116 die: jne die ! es must be at 64kB boundary
117 xor bx,bx ! bx is starting address within segment
118 rp_read:
119 mov ax,es
120 cmp ax,#ENDSEG ! have we loaded all yet?
121 jb ok1_read
122 ret
123 ok1_read:
124 seg cs
125 mov ax,sectors
126 sub ax,sread
127 mov cx,ax
128 shl cx,#9
129 add cx,bx
130 jnc ok2_read
131 je ok2_read
132 xor ax,ax
133 sub ax,bx
134 shr ax,#9
135 ok2_read:
136 call read_track
137 mov cx,ax
138 add ax,sread
139 seg cs
140 cmp ax,sectors
141 jne ok3_read
142 mov ax,#1
143 sub ax,head
144 jne ok4_read
145 inc track
146 ok4_read:
147 mov head,ax
148 xor ax,ax
149 ok3_read:
150 mov sread,ax
151 shl cx,#9
152 add bx,cx
153 jnc rp_read
154 mov ax,es
155 add ax,#0x1000
156 mov es,ax
157 xor bx,bx
158 jmp rp_read
159
160 read_track:
161 push ax
162 push bx
163 push cx
164 push dx
165 mov dx,track
166 mov cx,sread
167 inc cx
168 mov ch,dl
169 mov dx,head
170 mov dh,dl
171 mov dl,#0
172 and dx,#0x0100
173 mov ah,#2
174 int 0x13
175 jc bad_rt
176 pop dx
177 pop cx
178 pop bx
179 pop ax
180 ret
181 bad_rt: mov ax,#0
182 mov dx,#0
183 int 0x13
184 pop dx
185 pop cx
186 pop bx
187 pop ax
188 jmp read_track
189
190 !/*
191 ! * This procedure turns off the floppy drive motor, so
192 ! * that we enter the kernel in a known state, and
193 ! * don't have to worry about it later.
194 ! */
195 kill_motor:
196 push dx
197 mov dx,#0x3f2
198 mov al,#0
199 outb
200 pop dx
201 ret
202
203 sectors:
204 .word 0
205
206 msg1:
207 .byte 13,10
208 .ascii "Loading system ..."
209 .byte 13,10,13,10
210
211 .org 508
212 root_dev:
213 .word ROOT_DEV
214 boot_flag:
215 .word 0xAA55
216
217 .text
218 endtext:
219 .data
220 enddata:
221 .bss
222 endbss:
啟動程式碼短小精悍,卻又十分高效,利用效率讓人驚歎!
多處借鑑,重在學習
如有錯誤,歡迎指正