Improvements and code conveniance : mbr

This commit is contained in:
Adrien Bourmault 2018-12-22 22:45:19 +01:00
parent eac19a8ac7
commit bcff95e6d0
5 changed files with 59 additions and 57 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -8,7 +8,26 @@
; (x86_64 architecture only) ; ; (x86_64 architecture only) ;
;=----------------------------------------------------------------------------=; ;=----------------------------------------------------------------------------=;
%define TRAM 0x0B8000 ; [T]ext[RAM] %define TRAM 0x0B8000 ; [T]ext[RAM]
%define VRAM 0x0A0000 ; [V]ideo[RAM] %define VRAM 0x0A0000 ; [V]ideo[RAM]
%define OEMName bp+0x03 ; Disk label
%define bytesPerSector bp+0x0b ; Bytes per sector
%define sectorsPerCluster bp+0x0d ; Sectors per cluster
%define reservedSectors bp+0x0e ; Reserved sectors
%define fats bp+0x10 ; Number of fats
%define rootDirEntries bp+0x11 ; Number of entries in root dir
%define sectors bp+0x13 ; Logical sectors
%define mediaType bp+0x15 ; Media descriptor byte
%define fatSectors bp+0x16 ; Sectors per FAT
%define sectorsPerTrack bp+0x18 ; Sectors per track
%define heads bp+0x1a ; Number of sides/heads
%define hiddenSectors bp+0x1c ; Hidden sectors
%define hugeSectors bp+0x20 ; LBA sectors
%define biosBootdrvNum bp+0x24 ; Bootdrv number
%define reserved bp+0x25 ; This is not used
%define bootSignature bp+0x26 ; Bootdrv signature
%define volumeId bp+0x27 ; Volume ID
%define volumeLabel bp+0x2b ; Volume Label
%define fatTypeLabel bp+0x36 ; File system type
[BITS 16] [BITS 16]
[ORG 0x1000] [ORG 0x1000]

View File

@ -24,11 +24,11 @@
%define LOAD_SEG 0x0000 ; (LOAD_SEG << 4) + LOAD_OFF = 0x001000 %define LOAD_SEG 0x0000 ; (LOAD_SEG << 4) + LOAD_OFF = 0x001000
%define LOAD_OFF 0x1000 %define LOAD_OFF 0x1000
[BITS 16] ; Ensure 16-bit code (because fuck UEFI) [BITS 16] ; Ensure 16-bit code (because fuck UEFI)
;--------------------------------------------------- ;---------------------------------------------------;
; Disk description table ; Disk description table ;
;--------------------------------------------------- ;---------------------------------------------------;
Intro: Intro:
jmp short _start ; Jump over the BIOS PARAMETER BLOCK jmp short _start ; Jump over the BIOS PARAMETER BLOCK
@ -60,7 +60,7 @@ _start:
jmp BOOT_SEG:$+5 ; Fix the cs:ip registers with a vaudou magical trip jmp BOOT_SEG:$+5 ; Fix the cs:ip registers with a vaudou magical trip
bootstrap: bootstrap:
jmp bootstrapper jmp go
;; LOVELY DATA ;; LOVELY DATA
FileNotFound db "FStage ERR : NO LOADER", 0 ; File was not found FileNotFound db "FStage ERR : NO LOADER", 0 ; File was not found
@ -71,7 +71,7 @@ filename db "LOADER BIN" ; Filename
;; GO ! ;; GO !
bootstrapper: go:
mov ax, BOOT_SEG ; Set segments to the location of the bootloader mov ax, BOOT_SEG ; Set segments to the location of the bootloader
mov ds, ax mov ds, ax
mov es, ax mov es, ax
@ -86,11 +86,11 @@ bootstrapper:
;; INITIALIZE BOOT DISK ;; INITIALIZE BOOT DISK
or dl, dl ; Verifying dl points actually to the boot drive or dl, dl ; Verifying dl points actually to the boot drive
jz loadRoot jz load_root
mov byte [Bootdrv], dl ; Another soul (the disk) saved ! mov byte [Bootdrv], dl ; Another soul (the disk) saved !
mov ah, 0x08 mov ah, 0x08
int 0x13 ; int 0x13 : read drive parameters/geom int 0x13 ; int 0x13 : read drive parameters/geom
jc loadRoot jc load_root
and cx, 0x003f ; Maximum sector number is the high bits 6-7 of cl and cx, 0x003f ; Maximum sector number is the high bits 6-7 of cl
mov word [sectorsPerTrack], cx ; And whose low 8 bits are in ch mov word [sectorsPerTrack], cx ; And whose low 8 bits are in ch
mov dl, dh ; Convert the maximum head number to a word with another vaudou magical trip mov dl, dh ; Convert the maximum head number to a word with another vaudou magical trip
@ -100,7 +100,7 @@ bootstrapper:
;; LOAD THE ROOT DIRECTORY FROM DISK ;; LOAD THE ROOT DIRECTORY FROM DISK
loadRoot: load_root:
xor cx, cx xor cx, cx
mov ax, 32 ; Size of root dir = (rootDirEntries * 32) / bytesPerSector mov ax, 32 ; Size of root dir = (rootDirEntries * 32) / bytesPerSector
mul word [rootDirEntries] ; multiply by the total size of the root directory mul word [rootDirEntries] ; multiply by the total size of the root directory
@ -116,23 +116,23 @@ loadRoot:
mov di, BUFFER_SEG ; Set the extra segment to the disk buffer mov di, BUFFER_SEG ; Set the extra segment to the disk buffer
mov es, di mov es, di
mov di, BUFFER_OFF ; Set es:di and load the root directory into the disk buffer mov di, BUFFER_OFF ; Set es:di and load the root directory into the disk buffer
call readSectors ; Read the sectoooooooors ! call read_sectors ; Read the sectoooooooors !
;; FIND THE SECOND STAGE LOADER ;; FIND THE SECOND STAGE LOADER
mov di, BUFFER_OFF ; Set es:di to the disk buffer mov di, BUFFER_OFF ; Set es:di to the disk buffer
mov cx, word [rootDirEntries] ; Search through all of the root dir entries mov cx, word [rootDirEntries] ; Search through all of the root dir entries
xor ax, ax ; Clear ax for the file entry offset xor ax, ax ; Clear ax for the file entry offset
searchRoot: search_root:
xchg cx, dx ; Save cx because it's a loop counter xchg cx, dx ; Save cx because it's a loop counter
mov si, filename ; Load the filename mov si, filename ; Load the filename
mov cx, 11 ; Compare first 11 bytes mov cx, 11 ; Compare first 11 bytes
rep cmpsb ; Compare si and di cx times rep cmpsb ; Compare si and di cx times
je loadFat ; We found the LOADEEEEEEEER!!! je load_fat ; We found the LOADEEEEEEEER!!!
add ax, 32 ; File entry offset add ax, 32 ; File entry offset
mov di, BUFFER_OFF ; Point back to the start of the entry mov di, BUFFER_OFF ; Point back to the start of the entry
add di, ax ; Add the offset to point to the next entry add di, ax ; Add the offset to point to the next entry
xchg dx, cx xchg dx, cx
loop searchRoot ; Continue to search for the file loop search_root ; Continue to search for the file
;; ERROR... ;; ERROR...
mov si, FileNotFound ; Could not find the file mov si, FileNotFound ; Could not find the file
@ -153,7 +153,7 @@ reboot:
int 0x19 ; Reboot the system int 0x19 ; Reboot the system
;; LOAD THE FAT FROM THE FILE ;; LOAD THE FAT FROM THE FILE
loadFat: load_fat:
mov ax, word [es:di + 15] ; Get the file cluster at offset 26 mov ax, word [es:di + 15] ; Get the file cluster at offset 26
push ax ; Store the FAT cluster push ax ; Store the FAT cluster
xor ax, ax ; Size of fat = (fats * fatSectors) xor ax, ax ; Size of fat = (fats * fatSectors)
@ -162,15 +162,14 @@ loadFat:
mov cx, ax ; Store in cx mov cx, ax ; Store in cx
mov ax, word [reservedSectors] ; Convert the first fat on the disk mov ax, word [reservedSectors] ; Convert the first fat on the disk
mov di, BUFFER_OFF ; Set es:di and load the fat sectors into the disk buffer mov di, BUFFER_OFF ; Set es:di and load the fat sectors into the disk buffer
call readSectors ; Read the sectooooooooooors !!! call read_sectors ; Read the sectooooooooooors !!!
;; LOAD THE CLUSTERS OF THE LOADER AND JUMP ;; LOAD THE CLUSTERS OF THE LOADER AND JUMP
loadFile:
mov di, LOAD_SEG mov di, LOAD_SEG
mov es, di ; Set es:bx to where the file will load mov es, di ; Set es:bx to where the file will load
mov di, LOAD_OFF mov di, LOAD_OFF
pop ax ; File cluster restored pop ax ; File cluster restored
call readClusters ; Read clusters from the file call read_clusters ; Read clusters from the file
mov dl, byte [Bootdrv] ; Pass the boot Bootdrv into dl mov dl, byte [Bootdrv] ; Pass the boot Bootdrv into dl
jmp LOAD_SEG:LOAD_OFF ; Jump to the file loaded! jmp LOAD_SEG:LOAD_OFF ; Jump to the file loaded!
@ -186,7 +185,7 @@ loadFile:
; FUNCTIONS ; ; FUNCTIONS ;
;---------------------------------------------------; ;---------------------------------------------------;
readClusters: read_clusters:
;---------------------------------------------------; ;---------------------------------------------------;
; Read file clusters, starting at the given cluster,; ; Read file clusters, starting at the given cluster,;
; expects FAT to be loaded into the disk buffer. ; ; expects FAT to be loaded into the disk buffer. ;
@ -199,13 +198,9 @@ readClusters:
; Returns: None ; ; Returns: None ;
; ; ; ;
;---------------------------------------------------; ;---------------------------------------------------;
push ax pusha
push bx
push cx
push dx
push di
push es push es
.clusterLoop: .cluster_loop:
xor bh, bh xor bh, bh
xor dx, dx xor dx, dx
push ax ; Get the cluster start = (cluster - 2) * sectorsPerCluster + UserData push ax ; Get the cluster start = (cluster - 2) * sectorsPerCluster + UserData
@ -215,13 +210,13 @@ readClusters:
add ax, word [UserData] ; add the UserData add ax, word [UserData] ; add the UserData
xor ch, ch xor ch, ch
mov cl, byte [sectorsPerCluster] ; Sectors to read mov cl, byte [sectorsPerCluster] ; Sectors to read
call readSectors ; Read the sectors call read_sectors ; Read the sectors
pop ax ; Current cluster number pop ax ; Current cluster number
xor dx, dx xor dx, dx
.calculateNextSector16: ; Get the next sector for FAT16 (cluster * 2) ;; Calculate next sector for FAT16 (cluster * 2)
mov bx, 2 ; Multiply the cluster by two (cluster is in ax) mov bx, 2 ; Multiply the cluster by two (cluster is in ax)
mul bx mul bx
.loadNextSector: ;; Load sector in RAM
push ds push ds
push si push si
mov si, BUFFER_SEG mov si, BUFFER_SEG
@ -231,27 +226,23 @@ readClusters:
mov ax, word [ds:si] ; Load ax to the next cluster in FAT mov ax, word [ds:si] ; Load ax to the next cluster in FAT
pop si pop si
pop ds pop ds
.nextSectorCalculated: ;; Next
cmp ax, 0xfff8 ; Check if we are at the end of the file? cmp ax, 0xfff8 ; Check if we are at the end of the file?
jae .done jae .done
add di, 512 ; Add to the pointer offset add di, 512 ; Add to the pointer offset
jnc .clusterLoop jnc .cluster_loop
.fixBuffer: ; An error will occur if the buffer in memory ;; Correct the buffer because an error will occur if the buffer in memory
mov dx, es ; overlaps a 64k page boundry, when di overflows mov dx, es ; overlaps a 64k page boundry, when di overflows
add dh, 0x10 ; it will trigger the carry flag, so correct add dh, 0x10 ; it will trigger the carry flag, so correct
mov es, dx ; extra segment by 0x1000 mov es, dx ; extra segment by 0x1000
jmp .clusterLoop ; Load the next file cluster jmp .cluster_loop ; Load the next file cluster
.done: .done:
pop es pop es
pop di popa
pop dx
pop cx
pop bx
pop ax
ret ret
readSectors: read_sectors:
;---------------------------------------------------; ;---------------------------------------------------;
; Read sectors starting at a given sector by ; ; Read sectors starting at a given sector by ;
; the given times and load into a buffer. Please ; ; the given times and load into a buffer. Please ;
@ -264,14 +255,10 @@ readSectors:
; Returns: None ; ; Returns: None ;
; ; ; ;
;---------------------------------------------------; ;---------------------------------------------------;
push ax pusha
push bx
push cx
push dx
push di
push es push es
mov bx, di ; Convert es:di to es:bx for int 13h mov bx, di ; Convert es:di to es:bx for int 13h
.sectorLoop: .sector_loop:
push ax push ax
push cx push cx
xor dx, dx xor dx, dx
@ -291,35 +278,31 @@ readSectors:
or cl, ah ; Now cx is set with respective track and sector numbers or cl, ah ; Now cx is set with respective track and sector numbers
mov dl, byte [Bootdrv] ; Set correct Bootdrv for int 13h mov dl, byte [Bootdrv] ; Set correct Bootdrv for int 13h
mov di, 5 ; Try five times to read the sector because i love 5 mov di, 5 ; Try five times to read the sector because i love 5
.attemptRead: .attempt_read:
mov ax, 0x0201 ; Read Sectors func of int 13h, read one sector mov ax, 0x0201 ; Read Sectors func of int 13h, read one sector
int 0x13 ; Call int 13h (BIOS disk I/O) int 0x13 ; Call int 13h (BIOS disk I/O)
jnc .readOk ; If no carry set, the sector has been read jnc .read_ok ; If no carry set, the sector has been read
xor ah, ah ; Reset Bootdrv func of int 13h xor ah, ah ; Reset Bootdrv func of int 13h
int 0x13 ; Call int 13h (BIOS disk I/O) int 0x13 ; Call int 13h (BIOS disk I/O)
dec di ; Decrease read attempt counter dec di ; Decrease read attempt counter
jnz .attemptRead ; Try to read the sector again jnz .attempt_read ; Try to read the sector again
mov si, DiskError ; Error reading the disk :/ mov si, DiskError ; Error reading the disk :/
call print call print
jmp reboot jmp reboot
.readOk: .read_ok:
pop cx pop cx
pop ax pop ax
inc ax ; Increase the next sector to read inc ax ; Increase the next sector to read
add bx, word [bytesPerSector] ; Add to the buffer address for the next sector add bx, word [bytesPerSector] ; Add to the buffer address for the next sector
jnc .nextSector jnc .next_sector
.fixBuffer: ; An error will occur if the buffer in memory ;; Fixing buffer because an error will occur if the buffer in memory
mov dx, es ; overlaps a 64k page boundry, when bx overflows mov dx, es ; overlaps a 64k page boundry, when bx overflows
add dh, 0x10 ; it will trigger the carry flag, so correct add dh, 0x10 ; it will trigger the carry flag, so correct
mov es, dx ; es segment by 0x1000 mov es, dx ; es segment by 0x1000
.nextSector: .next_sector:
loop .sectorLoop loop .sector_loop
pop es pop es
pop di popa
pop dx
pop cx
pop bx
pop ax
ret ret
print: print: