diff --git a/lboot.S b/lboot.S index 7d984cd..ce723ce 100644 --- a/lboot.S +++ b/lboot.S @@ -29,6 +29,10 @@ _start: cli call print call getmap + mov $msg_mkheap, %si + call print + call makeheap + mov $msg_paging, %si call print call paging @@ -130,6 +134,51 @@ _pgnext: mov %ecx, %eax ret + // makeheap: find a memory range suitable for heap usage +makeheap: mov $memmap-24, %si +_mhnext: add $24, %si + cmp memmap_end, %si + jae _mhdone + + cmpl $1, 16(%si) + jne _mhnext + + cmpl $0, 4(%si) + ja _mhnext + + mov 0(%si), %ebx + mov 8(%si), %ecx + + // find end of range, clip to 4Gb + add %ebx, %ecx + jnc 1f + mov $0xFFFFFFFF, %ecx + + // handle wraparound if length > 4Gb +1: cmpl $0, 12(%si) + je 1f + mov $0xFFFFFFFF, %ecx + + // adjust base to above 1Mb, above the bootloader +1: cmp $0x10000, %ebx + jae 1f + mov $0x10000, %ebx + + // align to 4Kb boundaries +1: add $0xFFF, %ebx + and $0xFFFFF000, %ebx + and $0xFFFFF000, %ecx + + sub %ebx, %ecx + cmp heap_size, %ecx + jbe _mhnext + + mov %ebx, heap_start + mov %ecx, heap_size + jmp _mhnext + +_mhdone: ret + // alloc: take ECX bytes from usable space in memmap // No realignment is performed, so only alloc aligned sizes. alloc: mov $memmap-24, %si @@ -203,10 +252,14 @@ msg_start: .asciz "Netboot via fernlader v1 ...\r\n" msg_a20: .asciz " * Enabling A20\r\n" msg_unreal: .asciz " * Unreal Mode\r\n" msg_getmap: .asciz " * Memory Map\r\n" +msg_mkheap: .asciz " * Making Space\r\n" msg_paging: .asciz " * Paging\r\n" msg_fin: .asciz "Finished.\r\n" msg_aerr: .asciz "panic: Unable to allocate memory.\r\n" +heap_start: .long 0 +heap_size: .long 0 + // Long mode initial page tables pd_ptr: .long 0 pdp_ptr: .long 0