Improvements and code conveniance : mbr
This commit is contained in:
parent
eac19a8ac7
commit
bcff95e6d0
BIN
bin/disk.img
BIN
bin/disk.img
Binary file not shown.
BIN
bin/mbr.bin
BIN
bin/mbr.bin
Binary file not shown.
BIN
obj/boot/mbr.bin
BIN
obj/boot/mbr.bin
Binary file not shown.
|
@ -9,6 +9,25 @@
|
||||||
;=----------------------------------------------------------------------------=;
|
;=----------------------------------------------------------------------------=;
|
||||||
%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]
|
||||||
|
|
|
@ -26,9 +26,9 @@
|
||||||
|
|
||||||
[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:
|
||||||
|
|
Loading…
Reference in New Issue