1. 程式人生 > >linux學習(一)--啟動檔案bootsect.s

linux學習(一)--啟動檔案bootsect.s

 這是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:

  啟動程式碼短小精悍,卻又十分高效,利用效率讓人驚歎!

  多處借鑑,重在學習

   如有錯誤,歡迎指正