2022-08-22  2024-09-15    1492 字  3 分钟
AOS

初始化寄存器

我将物理地址0x050000-0x070008之间的内存分配给了堆栈。栈顶设置为0x070008的原因是,kernel函数在编译后会在函数开头加上这样一行汇编代码sub $0x8,%rsp,将栈顶设置为0x070008可以保证在经过此操作后,栈顶为0x070000

段寄存器

  • CS: 指向存放程序的内存段,IP用来存放下条待执行的指令在该段的偏移量。CS:IP所指向的指令就是下次要执行的指令。
  • SS: 指向用于堆栈的内存段,SP用来指向该堆栈的栈顶。
  • DS: 指向数据段
  • ES: 指向附加段 (辅助段寄存器)
  • FS: 指向标志段 (辅助段寄存器)
  • GS: 指向全局段 (辅助段寄存器)

缺省段寄存器

  • 当偏移量用到了指针寄存器BP,则其缺省的段寄存器也是SS,并且用BP可访问整个堆栈,不仅仅是只访问栈顶。
  • 通常,缺省的数据段寄存器是DS
  • 在进行串操作时,其目的地址的段寄存器规定为ES

代码

Use this command to check your USB Stick FAT32 Fields

1sudo hexdump -C -n 512 /dev/sdb

Write the bootloader to first 512 bytes of the usb stick

1sudo dd if=boot.bin of=/dev/sdb conv=notrunc

boot.asm

  1[BITS 16]
  2
  3[ORG 0x7c00]
  4
  5;----------------------------------------------- [Jump Instruction; offset: 0x00; length: 3  Bytes]
  6
  7    jmp short Label_Start                           ; 2 Bytes
  8    nop                                             ; 1 Bytes
  9
 10;----------------------------------------------- [FAT32; offset: 0x03; length: 87 Bytes]
 11
 12%include "fat32.asm"
 13
 14;----------------------------------------------- [Bootstrap Code; offset: 0x5A; length: 420 Bytes]
 15
 16Label_Start:
 17    call Print_StartBoot
 18
 19    mov sp, BaseOfStack
 20
 21    push    cs
 22    pop     ds
 23
 24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 25;; Search and Read "loader.bin" ;;
 26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 27
 28    and     byte [BS_RootDirectoryStart+3], 0x0F ; mask cluster value
 29    mov     esi, [BS_RootDirectoryStart]         ; esi=cluster # of root dir
 30
 31RootDirReadContinue:
 32    push    BaseOfLoader
 33    pop     es
 34    xor     bx, bx
 35    call    ReadCluster     ; read one cluster of root dir
 36    push    esi             ; save esi=next cluster # of root dir
 37    pushf                   ; save carry="not last cluster" flag
 38
 39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 40;; Look for the loader file to load and run ;;
 41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 42
 43    push    BaseOfLoader
 44    pop     es
 45    xor     di, di                  ; es:di -> root entries array
 46    mov     si, Filename_Loader     ; ds:si -> program name
 47
 48    mov     al, [BPB_SectorsPerCluster]
 49    cbw
 50    mul     word [BPB_BytesPerSector]   ; ax = bytes per cluster
 51    shr     ax, 5
 52    mov     dx, ax                      ; dx = # of dir entries to search in
 53
 54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 55;; Looks for a file/dir by its name      ;;
 56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 57;; Input:  DS:SI -> file name (11 chars) ;;
 58;;         ES:DI -> root directory array ;;
 59;;         DX = number of root entries   ;;
 60;; Output: ESI = cluster number          ;;
 61;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 62
 63    mov     cx, 11     ; the length of loader filename
 64
 65FindNameCycle:
 66    cmp     byte [es:di], 0xC
 67    jne     FindNameNotEnd
 68    jmp     Print_Error_NoLoader                 ; end of root directory (NULL entry found)
 69FindNameNotEnd:
 70    pusha
 71    repe    cmpsb
 72    popa
 73    je      FindNameFound
 74    add     di, 32
 75    dec     dx
 76    jnz     FindNameCycle           ; next root entry
 77    popf                            ; restore carry="not last cluster" flag
 78    pop     esi                     ; restore esi=next cluster # of root dir
 79    jc      RootDirReadContinue     ; continue to the next root dir cluster
 80    jmp     Print_Error_NoLoader    ; end of root directory (dir end reached)
 81FindNameFound:
 82    push    word [es:di+0x14]
 83    push    word [es:di+0x1A]
 84    pop     esi                     ; si = cluster no.
 85
 86;;;;;;;;;;;;;;;;;;;;;;;;;;
 87;; Load the entire file ;;
 88;;;;;;;;;;;;;;;;;;;;;;;;;;
 89
 90    push    BaseOfLoader
 91    pop     es
 92    xor     bx, bx
 93FileReadContinue:
 94    call    ReadCluster             ; read one cluster of root dir
 95
 96    pushf
 97    pusha
 98    inc byte [CLU]
 99    mov ax, 0xB800
100    mov gs, ax
101    mov ah, 0x0F       ; 0000: 黑底    1111: 白字
102    mov al, [CLU]
103    mov [gs:((80 * 0 + 39) * 2)], ax  ; 屏幕第 0 行, 第 39 列。
104    popa
105    popf
106
107    jc      FileReadContinue
108
109EnterLoader:
110    mov bl, byte [LINE]              ; save line number
111    jmp BaseOfLoader:OffsetOfLoader
112
113;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
114;; Reads a FAT32 cluster        ;;
115;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
116;; Inout:  ES:BX -> buffer      ;;
117;;           ESI = cluster no   ;;
118;; Output:   ESI = next cluster ;;
119;;         ES:BX -> next addr   ;;
120;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
121
122ReadCluster:
123    mov     ax, [BPB_BytesPerSector]
124    shr     ax, 2                           ; ax=# of FAT32 entries per sector
125    cwde
126    mov     ebp, esi                        ; ebp=esi=cluster #
127    xchg    eax, esi
128    cdq
129    div     esi                             ; eax=FAT sector #, edx=entry # in sector
130    movzx   edi, word [BPB_ReservedSectors]
131    add     edi, [BPB_HiddenSectors]
132    add     eax, edi
133
134    push    dx                              ; save dx=entry # in sector on stack
135    mov     cx, 1
136    call    ReadSectorLBA                   ; read 1 FAT32 sector
137
138    pop     si                              ; si=entry # in sector
139    add     si, si
140    add     si, si
141    and     byte [es:si+3], 0x0F            ; mask cluster value
142    mov     esi, [es:si]                    ; esi=next cluster #
143
144    lea     eax, [ebp-2]
145    movzx   ecx, byte [BPB_SectorsPerCluster]
146    mul     ecx
147    mov     ebp, eax
148
149    movzx   eax, byte [BPB_TotalFATs]
150    mul     dword [BS_BigSectorsPerFAT]
151
152    add     eax, ebp
153    add     eax, edi
154
155    call    ReadSectorLBA
156
157    mov     ax, [BPB_BytesPerSector]
158    shr     ax, 4                   ; ax = paragraphs per sector
159    mul     cx                      ; ax = paragraphs read
160
161    mov     cx, es
162    add     cx, ax
163    mov     es, cx                  ; es:bx updated
164
165    cmp     esi, 0x0FFFFFF8         ; carry=0 if last cluster, and carry=1 otherwise
166    ret
167
168;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
169;; Reads a sector using BIOS Int 13h fn 42h ;;
170;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
171;; Input:  EAX = LBA                        ;;
172;;         CX    = sector count             ;;
173;;         ES:BX -> buffer address          ;;
174;; Output: CF = 1 if error                  ;;
175;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
176
177ReadSectorLBA:
178    pushad
179
180ReadSectorLBANext:
181    pusha
182
183    push    byte 0
184    push    byte 0 ; 32-bit LBA only: up to 2TB disks
185    push    eax
186    push    es
187    push    bx
188    push    byte 1 ; sector count word = 1
189    push    byte 16 ; packet size byte = 16, reserved byte = 0
190
191    mov     ah, 42h
192    mov     dl, [BS_DriveNumber]
193    mov     si, sp
194    push    ss
195    pop     ds
196    int     13h
197    push    cs
198    pop     ds
199
200    jc      short Print_Error_Read
201    add     sp, 16 ; the two instructions are swapped so as not to overwrite carry flag
202
203    popa
204    dec     cx
205    jz      ReadSectorLBADone2      ; last sector
206
207    add     bx, [BPB_BytesPerSector] ; adjust offset for next sector
208    add     eax, byte 1             ; adjust LBA for next sector
209    jmp     short ReadSectorLBANext
210
211ReadSectorLBADone2:
212    popad
213    ret
214
215Print_StartBoot:
216    pusha
217    mov cx, 10
218    mov bp, Message_StartBoot
219    mov bx, 0x000f
220    call Message_Print_End
221    popa
222    ret
223
224Print_Error_Read:
225    mov cx, 11
226    mov bp, Message_ReadError
227    mov bx, 0x000f
228    call Message_Print_End
229    jmp $
230
231Print_Error_NoLoader:
232    mov cx, 15
233    mov bp, Message_NoLoader
234    mov bx, 0x000c
235    call Message_Print_End
236    jmp $
237
238Message_Print_End:
239    push es
240    push ds
241    mov ax, 0
242    mov ds, ax
243    mov es, ax
244    mov ax, 0x1301
245    mov dl, 0
246    mov dh, [LINE]
247    inc byte [LINE]
248    int 10h
249    pop ds
250    pop es
251    ret
252
253
254BaseOfLoader:         EQU   0x1000
255OffsetOfLoader:       EQU   0x0000
256BaseOfStack:          EQU   0x7C00
257
258
259Message_StartBoot:    DB    "Start Boot"      ; 10
260Message_ReadError:    DB    "ERROR: Read"     ; 11
261Message_NoLoader:     DB    "No Loader Found" ; 15
262Filename_Loader:      DB    "LOADER  BIN"     ; 11
263
264LINE:                 DB    0x00
265CLU:                  DB    0x41
266
267    TIMES 510 - ($ - $$)  DB  0
268
269;----------------------------------------------- [End of Sector Marker; offset: 0x1FE; length: 2 Bytes]
270
271    DW  0xAA55

除另有声明外本博客文章均采用 知识共享 (Creative Commons) 署名 4.0 国际许可协议 进行许可转载请注明原作者与文章出处