From 026406c3552583a018313e2432c2762c198f14bc Mon Sep 17 00:00:00 2001 From: pjht Date: Thu, 9 Feb 2023 12:08:36 -0600 Subject: [PATCH] Change bootsector to not load the whole kernel ELF file into a buffer --- boot/boot.68k | 147 +++++++++++++++++++++++++++++++++++++----------- config.toml | 5 ++ initrd_maker.rs | 6 +- rom.bin | Bin 172 -> 172 bytes 4 files changed, 122 insertions(+), 36 deletions(-) diff --git a/boot/boot.68k b/boot/boot.68k index b2f664f..3ef42d1 100644 --- a/boot/boot.68k +++ b/boot/boot.68k @@ -1,49 +1,52 @@ +.equ SEC_BUF_START, 0x400 +.equ PHDR_BUF_START, 0x600 +.equ PHDR_BUF_SEC_SIZE, 5 +.equ STORAGE_SEC, 0x0 +.equ STORAGE_CNT, 0x4 +.equ STORAGE_CMD, 0x8 +.equ STORAGE_DMADR, 0xC + .global _start _start: move.w #0x4, d0 | Find a storage card bsr.w find_first_card -| Load the header sector for the kernel binary -move.l #0x200, a1 | Set the destination address to 0x200 -move.l #0x1, d0 | Set the starting sector number to 1 -move.l #0x1, d1 | Set the sector count to 1 -bsr.w read_sectors -| load the ELF kernel binary off the disk -move.l #0xA000, a1 | Set the destination address to 0xA000 +| load the first PHDR_BUF_SEC_SIZE sectors of the ELF kernel binary off the disk +move.l #PHDR_BUF_START, a1 | Set the destination address to PHDR_BUF_START move.l #0x2, d0 | Set the starting sector number to 2 -clr.l d1 -move.w (0x202), d1 | Set the sector count +move.l #PHDR_BUF_SEC_SIZE, d1 | Set the sector count bsr.b read_sectors -move.l (0xA01C), d0 | Load the offset of the program headers in the file -move.l #0xA000, a0 | Put the address of the program headers in a0 -adda.w d0, a0 -move.w (0xA02C), d0 | Put the number of program headers - 1 in d0 +move.l (PHDR_BUF_START + 0x1C), d0 | Load the offset of the program headers in the file +move.l #PHDR_BUF_START, a1 | Put the address of the program headers in a1 +adda.w d0, a1 +move.w (PHDR_BUF_START + 0x2C), d0 | Put the number of program headers - 1 in d0 subq.w #0x1, d0 phead_loop: -move.l (a0), d1 | If the type of the program header isn't 1 (LOAD), skip the header +move.l (a1), d1 | If the type of the program header isn't 1 (LOAD), skip the header cmpi.l #0x1, d1 bne.b next_seg | Zero the destination memory -move.l (20, a0), d1 | Put the memory size - 1 in d1 +move.l (20, a1), d1 | Put the memory size - 1 in d1 subq.l #0x1, d1 -move.l (8, a0), a1 | Put the starting memory address in a1 +move.l (8, a1), a2 | Put the starting memory address in a2 zero_loop: -move.b #0, (a1)+ | Zero a byte of the destination memory +move.b #0, (a2)+ | Zero a byte of the destination memory dbra d1, zero_loop | Loop back if there is more to zero -| Copy the data from the loaded file into position -move.l (16, a0), d1 | Put the file size - 1 in d1 +| Load the segment data off disk +move.l (16, a1), d1 | Put the file size in d1 beq.b next_seg | If the file size is 0, skip the copy (ex, .bss section) -subq.l #0x1, d1 -move.l (4, a0), a1 | Put the address of the loaded data in a1 -adda.l #0xA000, a1 -move.l (8, a0), a2 | Put the starting memory address in a2 -load_loop: -move.b (a1)+, (a2)+ | Copy a byte of data into position -dbra d1, load_loop | Loop back if there is more to copy +move.l a1,a6 | Save a1 in a6 +move.l d0,d4 | Save d0 in d4 +move.l (4, a1), d0 | Put the starting byte number in d0 +addi.l #0x400, d0 | Add the 2 sector offset in the disk for the kernel file +move.l (8, a1), a1 | Put the destination memory address in a1 +bsr.b read_bytes +move.l a6,a1 | Restore a1 from a6 +move.l d4,d0 | Restore d0 from d4 next_seg: -lea (0x20, a0), a0 | Advance a0 to point to the next program header +lea (0x20, a1), a1 | Advance a1 to point to the next program header dbra d0, phead_loop | If there are more program headers, loop back -move.l (0xA018), a0 | Load the entry point of the program into a0 -jmp (a0) | Jump to the entry point of the program +move.l (PHDR_BUF_START + 0x18), a1 | Load the entry point of the program into a1 +jmp (a1) | Jump to the entry point of the program @@ -68,10 +71,66 @@ ffc_done: | Start sector in d0.l | Sector count in d1.l read_sectors: -move.l d0, (a0) | Set the sector number -move.l d1, (4, a0) | Set the sector count -move.l a1, (0xC, a0) | Set the destination address -move.w #0x1, (8, a0) | Issue a DMA read command +move.l d0, (STORAGE_SEC, a0) | Set the sector number +move.l d1, (STORAGE_CNT, a0) | Set the sector count +move.l a1, (STORAGE_DMADR, a0) | Set the destination address +move.w #0x1, (STORAGE_CMD, a0) | Issue a DMA read command +read_sectors_done: +rts + +| Reads bytes off a storage card +| Card base in a0 +| Destination in a1 +| Start byte in d0.l +| Byte count in d1.l +read_bytes: +move.l d0, d6 | Save start byte in d6 +move.l d1, d7 | Save byte count in d7 +move.l a1, a6 | Save destination in a6 +lsr.l #8, d0 | Divide start byte by 512 to compute starting sector +lsr.l #1, d0 +move.l d0, d5 | Save the starting sector in d5 +move.l #1, d1 | Read the starting sector into the sector buffer +move.l #SEC_BUF_START, a1 +bsr.b read_sectors +move.l a6, a2 | Load the destination into a2 +move.l d6, d0 | Load the start byte into d0 +andi.l #0x1FF, d0 | Modulus start byte by 512 to compute sector data offset +move.l #0x1FF, d1 | Compute the number of bytes to transfer by subtracting the offset from 512 +sub.l d0, d1 +cmp d7, d1 | Compare the number of bytes to transfer with the byte count +ble.b count_ok | If it wass less than the byte count, do not adjust the bytes to transfer +move.l d7, d1 | Otherwis:e, cap the transfer count to the total byte count +count_ok: +move.l d1, d6 | Save the number of bytes in d6 +subi.l #1, d1 | Subtract 1 from the number of bytes to account for the extra loop done by dbra +start_sec_loop: | Transfer the required bytes from the start sector to the destination buffer +move.b (a1)+, (a2)+ +dbra d1, start_sec_loop +move.l d5, d0 | Load the starting sector into d0 +addi #1, d0 | Compute the start of the middle sectors by adding 1 to the starting sector +move.l d6, d2 | Load the number of bytes transferred into d2 +move.l d7, d1 | Load the byte count into d1 +sub.l d2, d1 | Compute the number of remaining bytes by subtracting the number of transferred bytes from the byte count +move.l d1, d6 | Save the number of remaining bytes in d6 +lsr.l #8, d1 | Divide remaining bytes by 512 to compute the number of middle sectors +lsr.l #1, d1 +move.l a2, a1 | Transfer the sector data to the end of the start sector bytes +bsr.b read_sectors | Read the middle sectors +move.l d1, d5 | Save the number of middle sectors in d5 +lsl.l #8, d1 | Multiply the number of middle sectors by 512 to compute the number of bytes transferred +lsl.l #1, d1 +adda.l d1, a2 | Add the number of bytes transferred to a2 +add.l d5, d0 | Compute the end sector number by adding the start and count of the middle sectors +move.l #1, d1 | Set the number of sectors to read to 1 +move.l #SEC_BUF_START, a1 | Set the read address of the sector to the sector buffer +bsr.b read_sectors | Read the end sector +move.l d6, d1 | Load the number of remaining bytes into d1 +andi #0x1FF, d1 | Modulus the number of remaining bytes by 512 to compute the number of bytes to copy from the end sector +end_sec_loop: | Transfer the required bytes from the start sector to the destination buffer +move.b (a1)+, (a2)+ +dbra d1, end_sec_loop +read_bytes_done: rts .if . != 512 @@ -79,4 +138,26 @@ rts .byte 0 .endif +/* read_bytes theory: */ +/* Start sector: Start byte / 512 */ +/* Offset in start sector: Start byte % 512 */ +/* Rem bytes: Byte count - (512 - Offset in start sector) */ +/* Middle sectors start: start sector + 1 */ +/* Middle sectors count: Rem bytes / 512 */ +/* End sector: Middle sectors start + Middle sectors count */ +/* End sector copy length: Rem bytes % 512 */ + + +/* 0 1 2 3 4 5 6 7 8 9 A B C D E F * / +/* dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd */ +/* 0------------------------------------------------------------------------------------------S--------------------------------------------------------------------------------------E */ +/* 91 bytes . 88 bytes */ + +/* Start sector: 91 / 16 = 5 */ +/* Offset in start sector: 91 % 16 = 11 */ +/* Rem bytes: 88 - (16 - 11) = 83 */ +/* Middle sectors start: 5 + 1 = 6 */ +/* Middle sectors count: 83 / 16 = 5 */ +/* End sector: 6 + 5 = B */ +/* End sector copy length: 83 % 16 = 3 */ diff --git a/config.toml b/config.toml index bb6d480..d5347dd 100644 --- a/config.toml +++ b/config.toml @@ -1,3 +1,5 @@ +symbol_tables = ["boot/boot.elf"] + [[cards]] type = "rom" image = "rom.bin" @@ -12,3 +14,6 @@ size = 65536 [[cards]] type = "storage" image = "os.dsk" + +# [[cards]] +# type = "mmu" diff --git a/initrd_maker.rs b/initrd_maker.rs index 458e59d..7d55aed 100644 --- a/initrd_maker.rs +++ b/initrd_maker.rs @@ -40,9 +40,9 @@ fn main() { .expect("Could not read from file/write to initrd") as u16; if (bytes_written % BLOCK_SIZE) != 0 { let bytes_padding = (BLOCK_SIZE) - (bytes_written % BLOCK_SIZE); - for _ in 0..bytes_padding { - archive.write_all(&[0]).expect("Could not write to initrd"); - } + archive + .write_all(&vec![0; bytes_padding as usize]) + .expect("Could not write to initrd"); } } archive diff --git a/rom.bin b/rom.bin index f268c43dcff5428832c7291c8ced5b38ee285233..db8ba000a004b6cfc62f45bec4f473c829630b36 100644 GIT binary patch delta 11 ScmZ3(xQ20pCFAFbRz(0AJp@$% delta 11 ScmZ3(xQ20pCF7@wRz(0AIRsPy