Made it possible to load 8 sectors into ram

This commit is contained in:
Eric-Paul Ickhorn 2023-05-02 08:48:47 +02:00
parent 49230d4c72
commit f5fe3a2172
6 changed files with 219 additions and 381 deletions

View File

@ -8,4 +8,5 @@ cd stage_2
./build.sh ./build.sh
cd ../ cd ../
cat stage_1/stage_1.bin > nightloader.bin
# cat stage_2/stage_2.bin >> nightloader.bin

2
run.sh Normal file → Executable file
View File

@ -1,3 +1,3 @@
#!/bin/env bash #!/bin/env bash
qemu-system-x86_64 nightloader.bin

4
stage_1/fat32.asm Normal file
View File

@ -0,0 +1,4 @@
; TODO: Read FAT32 filesystem and load raw binary frompath nightloader/stage_2.bin

124
stage_1/partition_table.asm Normal file
View File

@ -0,0 +1,124 @@
times 442 - ($-$$) db 0
db "####"
times 446 - ($-$$) db 0
mbr_table:
.part_1:
db 0x80 ; bootable flag
db 0, 2, 0 ; CHS - start-address (ordering: cylinder, sector, header)
db 0x9d
db 0, 16, 0 ; CHS - end-address (ordering: cylinder, sector, header)
dd 2
dd 16
.part_2:
db 0x00 ; bootable flag
db 0, 0, 0 ; CHS - start-address (ordering: cylinder, sector, header)
db 0x0
db 0, 0, 0 ; CHS - end-address (ordering: cylinder, sector, header)
dd 0
dd 0
.part_3:
db 0x00 ; bootable flag
db 0, 0, 0 ; CHS - start-address (ordering: cylinder, sector, header)
db 0x00
db 0, 0, 0 ; CHS - end-address (ordering: cylinder, sector, header)
dd 0
dd 0
.part_4:
db 0x00 ; bootable flag
db 0, 0, 0 ; CHS - start-address (ordering: cylinder, sector, header)
db 0x00
db 0, 0, 0 ; CHS - end-address (ordering: cylinder, sector, header)
dd 0
dd 0
.signature:
db 0x55, 0xaa
second_stage:
;mov si, finish_text
;mov dl, 36
;mov dh, 12
;mov cx, 8
; set the video mode correctly
xor ah, ah ; bios-function (set video mode)
mov al, 3 ; video mode with 80x25 characters
int 0x10
.happiness:
mov ah, 0x02 ; action: move cursor
mov bh, 0 ; page
mov dh, 1 ; row
mov dl, 1 ; column
int 0x10
mov ah, 0x0a ; action: write character
mov al, '$' ; character
mov bh, 0 ; page
mov cx, 13 ; count
int 10h
jmp .happiness
.prolog:
push di
push cx
push bx
push ax
xor di, di ; character index
.printing_loop:
.set_cursor_position:
.write_character:
push cx ; save len_buffer
; get the current character
mov bx, si
add bx, di
mov al, [bx]
; al now contains the current character
; set the other needed interrupt values
mov ah, 0x0a ; wanted function (write character at cursor position)
mov bh, 0 ; page number
mov cx, 1 ; repetitions of character
int 0x10 ; call bios basic draw functions
pop cx ; restore len_buffer
inc dl ; go to next column
; go to a new line if needed
cmp dl, 80
jb .no_new_line_needed
xor dl, dl
inc dh ; increase column
.no_new_line_needed:
inc di ; go to next character
; go further if the string-printing hasn't been finished
cmp di, cx
jb .printing_loop
.epilog:
jmp .epilog
finish_text:
db "-FINISH-"

View File

@ -1,210 +1,123 @@
section .text
org 0x7c00
start: STAGE_1_CODE_MEMORY_ADDRESS equ 0x7c00
STAGE_1_STACK_MEMORY_ADDRESS equ 0x07e0
NIGHTLOADER_PARTITION_TYPE equ 0x9d
ORIGINAL_PARTITION_TABLE_OFFSET equ 446
ORIGINAL_NUM_PARTITIONS_IN_TABLE equ 4
ORIGINAL_PARTITION_ENTRY_SIZE equ 16
BOOTABLE_BYTE_OFFSET equ 0
CHS_START_SECTOR_ADDRESS_OFFSET equ 1
PARTITION_TYPE_OFFSET equ 4
CHS_END_SECTOR_ADDRESS equ 5
FIRST_LBA_SECTOR_ADDR_OFFSET equ 8
LAST_LBA_SECTOR_ADDR_OFFSET equ 12
org STAGE_1_CODE_MEMORY_ADDRESS
bits 16
stage_0:
mov ax, 0 mov bx, STAGE_1_STACK_MEMORY_ADDRESS
mov ds, ax mov ss, bx
mov es, ax mov bx, 0x0800
mov gs, ax
mov fs, ax
mov ax, 0x7e00
mov ss, ax
mov sp, 256
mov bp, 256 mov bp, 256
mov sp, 256
mov si, dx ; save the origin disk number mov bx, 0x0000
mov ds, bx
mov es, bx
mov ax, 0x7c00 mov di, dx
add ax, 446
; ax now points to the start of the partition table ; set the video mode correctly
xor ah, ah ; bios-function (set video mode)
mov al, 3 ; video mode with 80x25 characters
int 0x10
xor di, di
call initialize_video_mode
.search_partition: .search_partition:
mov bx, ax ; get the offset of the current entry mov si, STAGE_1_CODE_MEMORY_ADDRESS
add bx, 4 ; go to the offset of the partition type add si, ORIGINAL_PARTITION_TABLE_OFFSET
mov cl, [bx] mov cx, 0 ; offset of the current entry from the partition table start
cmp cl, 0x9d
je .load_partition
inc di
; leave and print debug message if the last partition entry
; did not provide the wanted bootloader - partition
cmp di, 4
je .no_boot_partition
add ax, 16 .search_loop:
jmp .search_partition
mov bx, si
add bx, cx
add bx, PARTITION_TYPE_OFFSET
mov al, [bx]
cmp al, NIGHTLOADER_PARTITION_TYPE
je .load_partition;
; go to the next entry
add cx, ORIGINAL_PARTITION_ENTRY_SIZE
; check if there are more entries
cmp dx, ORIGINAL_NUM_PARTITIONS_IN_TABLE * ORIGINAL_PARTITION_ENTRY_SIZE
jb .search_loop
jmp .no_boot_partition
.load_partition: .load_partition:
; ax is the start of the bootloader's partition entry in the mbr
; read the chs-entry and push it onto the stack mov si, cx ; address of the partition table entry of the nightloader-partition
; head ; TODO: Make this more flexible; that's urgent.
xor dx, dx mov ah, 0x02 ; action (read from disk)
mov bx, ax mov al, 8 ; num_sectors
add bx, 1 mov ch, 0 ; cylinder
mov dl, [bx] mov cl, 2 ; sector (starts at 1, max.: 63)
push dx mov dx, di ; storage device id
mov dh, 0 ; head
mov bx, 0x0800
mov es, bx ; read destination segment
mov bx, 0x0000 ; read destination address
int 0x13
; cylinder
xor dx, dx
mov bx, ax
add bx, 3
mov dh, [bx]
mov bx, ax
add bx, 2
mov dl, [bx]
shr dx, 6
push dx
; sector
xor dx, dx
mov bx, ax
add bx, 2
mov dl, [bx]
and dl, 0b00111111
push dx
; push the partition's length
mov bx, ax
add bx, 12
mov dx, [bx]
push dx ; lower part
mov bx, ax
add bx, 14
mov dx, [bx]
push dx ; higher part
; load it all and read from disk
mov bx, sp
add bx, 4
mov al, [bx] ; sector-count
add bx, 2
mov cl, [bx] ; start-sector
add bx, 2
mov ch, [bx] ; start-cylinder
mov dx, si ; drive
mov bx, 0x0800
mov es, bx ; output segment
mov bx, sp
add bx, 8
mov dh, [bx] ; start-head
call .write_hex
mov cl, 2
mov ah, 0x02
mov al, 1
mov bx, 0x0000 ; output address in es - segment
int 13h
mov cx, 8
mov si, 0x8000 mov si, 0x8000
mov cx, 8
mov dh, 12 mov dh, 12
mov dl, 32 mov dl, 36
call print_string call print_string
jmp .keepalive ; jmp .wait
jmp 0x0800:0x0000
.no_boot_partition: .no_boot_partition:
mov cx, LEN_TEXT_NO_BOOT_PARTITION mov si, errors.no_boot_partition
mov si, error_texts.no_boot_partition mov cx, 30
mov dl, 25
mov dh, 12 mov dh, 12
mov dl, 32
call print_string call print_string
.keepalive: .wait:
jmp .keepalive cli
hlt
.write_hex:
push bx
push cx
mov bx, error_texts.hextab
and cx, 0x0f
add bx, cx
mov cl, [bx]
mov bx, error_texts.hexbuf
inc bx
mov [bx], cl
mov bx, error_texts.hextab
and cx, 0xf0
shr cx, 4
add bx, cx
mov cl, [bx]
mov bx, error_texts.hexbuf
mov [bx], cl
mov cx, 2
mov si, error_texts.hexbuf
mov dh, 12
mov dl, 32
call print_string
pop cx
pop bx
ret
; %include "exfat.asm"
%include "gdt.asm"
%include "utility.asm"
LEN_TEXT_NO_BOOT_PARTITION equ 17 MESSAGE_LENGTH_NO_BOOT_PARTITION equ 30
error_texts: errors:
.no_boot_partition: .no_boot_partition:
;db "NO_BOOT_PARTITION" db "NO NIGHTLOADER-PARTITION FOUND"
.hex:
.hextab:
db "0123456789abcdef" db "0123456789abcdef"
.hexbuf: %include "utility.asm"
resb 4 %include "fat32.asm"
%include "partition_table.asm"
times 446 - ($-$$) db 0
db 0x80
db 0, 2, 0
db 0x9d
db 0, 3, 0
dd 1
dd 1
times 510 - ($-$$) db 0
db 0x55
db 0xAA
db "################"

View File

@ -1,22 +1,4 @@
section .text
initialize_video_mode:
.prolog:
push ax
; set the video mode correctly
xor ah, ah ; bios-function (set video mode)
mov al, 3 ; video mode with 80x25 characters
int 0x10
.epilog:
pop ax
ret
; cx: len_buffer ; cx: len_buffer
; si: buffer ; si: buffer
; dl: start_x NOTE: Will contain the end of the text on-screen ; dl: start_x NOTE: Will contain the end of the text on-screen
@ -82,189 +64,3 @@ print_string:
pop di pop di
ret ret
; ds: source
; es: destination
; dx: len_to_copy
mem_copy:
push ax
push bx
push cx
push dx
xor cx, cx
mov di, dx
; ax: first region's value
; bx: address at index
; cx: byte_index
; dx: second region's value
.loop:
; retrieve the source byte at the current index
mov bx, cx
mov dx, [bx]
; swap the two segments
; here, ax and bx are used differently.
mov ax, es
mov bx, ds
mov ds, ax
mov es, bx
mov [bx], cx
; swap the two segments back
mov ax, es
mov bx, ds
mov ds, ax
mov es, bx
inc cx
; if the end has NOT been reached
cmp cx, di
jb .loop ; => continue
ret
; ds: region_1
; es: region_2
; dx: len_regions
; ax: result
mem_equals:
push bx
push cx
push dx
push di
xor cx, cx
mov di, dx
; ax: first region's value
; bx: address at index
; cx: byte_index
; dx: second region's value
.loop:
mov bx, cx
mov dx, [bx]
; swap the two segments
; here, ax and bx are used differently.
mov ax, es
mov bx, ds
mov ds, ax
mov es, bx
mov bx, cx
mov ax, [bx]
cmp ax, dx
; swap the two segments back
mov ax, es
mov bx, ds
mov ds, ax
mov es, bx
; jump accordingly to the comparison above
jne .not_equal
inc cx
cmp cx, di ; if the loop needs to continue
jb .loop ; (if the end is NOT reached yet)
; it goes here if the two regions are completely equal
pop di
pop dx
pop cx
pop bx
mov ax, 1
ret
.not_equal:
pop di
pop dx
pop cx
pop bx
mov ax, 0
ret
; ax: start_sector (upper)
; bl: start_sector (lower)
; cx: wanted_sector_count
; dh: drive
; si: buffer_address (upper)
; di: buffer_address (lower)
load_sectors:
; INNER WORKING:
;
; This function first checks if it needs to load sectors going over
; a cylinder boundary and loads to that cylinder boundary first continuing
; in 63-sector - parts after that until the last, < 63-sectors part is read.
;
; This is done because some systems don't like reading over the boundaries
; between the cylinders.
;
; The actual part loading the data is in .read_from_disk, it's no different
; from the first read to the other reads. It just gets different arguments
; from 1).load_first_sectors, and 2) .load_further_sectors
;
.prolog:
push ax
push bx
push cx
push dx
push si
xor si, si ; current sector index
.load_first_sectors:
; ah: EMPTY
; al: num_sectors_to_read
; bx: EMPTY
; ch: cylinder
; cl: sector
; dh: head
; dl: drive
.read_from_disk:
; set es:bx to the address in bytes to which the output should be written.
mov bx, si
shr bx, 9
mov ah, 0x02
int 0x13
.load_further_sectors:
.epilog: