Change bootsector to not load the whole kernel ELF file into a buffer
This commit is contained in:
parent
82f3185f9c
commit
026406c355
147
boot/boot.68k
147
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 */
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user