feat: setup bitmap for physical allocator

This commit is contained in:
d0p1 🏳️‍⚧️ 2023-01-24 15:57:14 +01:00
parent da0a8f4e1b
commit 459a4b0b2a
7 changed files with 342 additions and 24 deletions

3
.gitignore vendored
View file

@ -3,6 +3,7 @@
*.bin *.bin
*.iso *.iso
*~ *~
\#*\#
*.elf *.elf
*.a *.a
@ -11,3 +12,5 @@ vmstupid
/sysroot /sysroot
log.txt

View file

@ -5,7 +5,7 @@
[Website](https://stupidos.d0p1.eu) [Website](https://stupidos.d0p1.eu)
![GitHub](https://img.shields.io/github/license/d0p1s4m4/stupidos?logoColor=white&style=flat-square) ![GitHub](https://img.shields.io/github/license/d0p1s4m4/stupidos?logoColor=white&style=flat-square)
![GitHub issues](https://img.shields.io/github/issues/d0p1s4m4/stupidos?style=flat-square) ![GitHub issues](https://img.shields.io/github/issues/d0p1s4m4/stupidos?style=flat-square)
[![GitHub Sponsors](https://img.shields.io/github/sponsors/d0p1s4m4)](https://github.com/sponsors/d0p1s4m4?style=flat-square) [![GitHub Sponsors](https://img.shields.io/github/sponsors/d0p1s4m4?style=flat-square)](https://github.com/sponsors/d0p1s4m4)
</div> </div>

View file

@ -68,6 +68,7 @@ entry:
jmp hang jmp hang
.mem_ok: .mem_ok:
LOG msg_pmm_initialized
extern setup_paging extern setup_paging
call setup_paging call setup_paging
@ -81,6 +82,7 @@ section .rodata
msg_hello_world db "StupidOS v", STUPID_VERSION, " (built with ", NASM_VERSION, " on ", BUILD_DATE, ")", 0 msg_hello_world db "StupidOS v", STUPID_VERSION, " (built with ", NASM_VERSION, " on ", BUILD_DATE, ")", 0
msg_boot_info db "Bootloader: %s", 0 msg_boot_info db "Bootloader: %s", 0
msg_pmm_initialized db "PMM initialized", 0
err_invalid_boot_magic db "[ERROR] Invalid boot magic (got: %x, expected: 0x2BADB002)", 0 err_invalid_boot_magic db "[ERROR] Invalid boot magic (got: %x, expected: 0x2BADB002)", 0
err_cannot_map_memory db "[ERROR] Can't map memory", 0 err_cannot_map_memory db "[ERROR] Can't map memory", 0

View file

@ -4,6 +4,7 @@ global setup_idt
setup_idt: setup_idt:
%assign i 0 %assign i 0
%rep 32 %rep 32
;; TODO: refactor
extern isr %+ i extern isr %+ i
mov eax, isr %+ i mov eax, isr %+ i
; offset (low) ; offset (low)

View file

@ -26,3 +26,5 @@ SECTIONS
kernel_end = .; kernel_end = .;
} }
kernel_size = kernel_end - kernel_start;

View file

@ -1,9 +1,280 @@
[BITS 32] [BITS 32]
;; XXX: align address to page
%include "base.inc" %include "base.inc"
%include "multiboot.inc" %include "multiboot.inc"
extern kernel_size
extern kernel_end
struc bitmap
.length: resd 1
.addr: resd 1
endstruc
section .text section .text
bitmap_count_free_page:
push ebp
mov ebp, esp
push edi
push esi
push ebx
mov edi, [bitmap_info + bitmap.addr]
xor ebx, ebx
.loop:
inc edi
inc ebx
cmp ebx, [bitmap_info]
jb .loop
.end:
pop ebx
pop esi
pop edi
leave
ret
bitmap_mark:
push ebp
mov ebp, esp
push edi
push esi
mov edi, 1
mov eax, [ebp + 8]
and eax, 0x7 ; eax % 8
mov ecx, eax
shl edi, cl
mov eax, [ebp + 8]
shr eax, 0x3 ; eax / 8
mov esi, [bitmap_info + bitmap.addr]
add esi, eax
mov dl, byte [esi]
mov ecx, [ebp + 12]
test ecx, ecx
jz .clear
or edx, edi ; set bit
jmp .end
.clear:
not edi
and edx, edi ; clear bit
.end:
mov byte [esi], dl
pop esi
pop edi
leave
ret
init_bitmap:
push ebp
mov ebp, esp
push edi
mov ecx, [bitmap_info]
mov al, 0xFF
mov edi, [bitmap_info + bitmap.addr]
rep stosb
pop edi
leave
ret
bitmap_mark_range_free:
push ebp
mov ebp, esp
push edi
push esi
push ebx
mov edi, [ebp + 8] ; start address
mov esi, [ebp + 12] ; length
xor ebx, ebx ; counter (I know I SHOUD use 'ecx' as counter
; but since the ABI state it's not preserved
; accross function call)
push dword 0 ; bitmap_mark(addr, 0) == clear
.loop:
cmp ebx, esi
jnb .end_loop
add edi, ebx
jc .end_loop ; exit on overflow
push edi
call bitmap_mark
add esp, 4
add ebx, 0x1000 ; add page size
jmp .loop
.end_loop:
add esp, 4
pop ebx
pop esi
pop edi
leave
ret
setup_pmm_mmap:
push ebp
mov ebp, esp
sub esp, 4
push edi
push esi
push ebx
mov edi, [ebp + 8] ; mb_mmap struct addr
mov esi, [ebp + 12] ; mmap length
xor ebx, ebx ; pass
mov [ebp - 4], ebx ; set max addr to 0
.loop:
;; TODO: PAE stuff
;; skip address > 32bit
mov eax, [edi + mb_mmap.addr + 4]
and eax, eax
jnz .next
mov eax, [edi + mb_mmap.length + 4]
and eax, eax
jnz .next
;; check if first pass
and ebx, ebx
jz .first_pass
mov eax, [edi + mb_mmap.type]
and eax, 0x1 ; check if free
jz .next
;;
mov eax, [bitmap_info]
mov ecx, [mb_mmap.length]
cmp eax, ecx
ja .next
cmp ebx, 0x1
jne .third_pass
mov eax, [edi + mb_mmap.addr]
mov [bitmap_info + bitmap.addr], eax
LOG msg_bitmap_stored_at, eax
call init_bitmap ; mark all memory as used
jmp .bitmap_size_already_set
;; TODO: mark as free in bitmap
.third_pass:
push dword [edi + mb_mmap.addr]
push dword [edi + mb_mmap.length]
call bitmap_mark_range_free
add esp, 8
jmp .next
;; first pass then calculate higher address
.first_pass:
LOG msg_mmap_entry, dword [edi + mb_mmap.addr + 4], \
dword [edi + mb_mmap.addr], \
dword [edi + mb_mmap.length + 4], \
dword [edi + mb_mmap.length], \
dword [edi + mb_mmap.type]
mov eax, [edi + mb_mmap.length]
add eax, [edi + mb_mmap.addr]
jnc .no_overflow
mov eax, -1 ; if overflow set eax to (uint32_t)-1
.no_overflow:
mov edx, [ebp - 4]
cmp edx, eax
ja .next
mov [ebp - 4], eax
.next:
mov eax, [edi + mb_mmap.size]
add eax, 0x4
add edi, eax ; jump to next entry
sub esi, eax
jnz .loop
and ebx, ebx
jnz .bitmap_size_already_set
LOG msg_max_mem, dword [ebp - 4]
mov eax, [ebp - 4]
shr eax, 15 ; eax / (4096*8)
mov [bitmap_info], eax
.bitmap_size_already_set:
inc ebx
cmp ebx, 2
jbe .loop
pop ebx
pop esi
pop edi
leave
ret
setup_pmm_legacy:
push ebp
mov ebp, esp
push edi
push esi
push ebx
xor eax, eax
mov ecx, [ebp + 8]
shl ecx, 0xA ; ecx * 1KiB
mov esi, ecx
LOG msg_mem_block, eax, ecx
mov eax, 0x100000
mov ecx, [ebp + 12]
shl ecx, 0xA ; ecx * 1KiB
mov ebx, ecx
mov edi, eax
add edi, ecx
LOG msg_mem_block, eax, ecx
LOG msg_max_mem, edi
shr edi, 15 ; (edi / (4046*8))
mov dword [bitmap_info], edi
cmp edi, esi
ja .try_high
mov dword [bitmap_info + bitmap.addr], 0
jmp .initialize_bitmap
.try_high:
mov eax, ebx
sub ebx, kernel_size
cmp edi, ebx
ja .err_no_mem
mov dword [bitmap_info + bitmap.addr], kernel_end
.initialize_bitmap:
call init_bitmap
push esi
push dword 0
call bitmap_mark_range_free
push ebx
push dword 0x100000
call bitmap_mark_range_free
xor eax, eax
jmp .end
.err_no_mem:
mov eax, 1
.end:
pop ebx
pop esi
pop edi
leave
ret
global setup_pmm global setup_pmm
setup_pmm: setup_pmm:
push ebp push ebp
@ -17,20 +288,11 @@ setup_pmm:
mov eax, [edi] mov eax, [edi]
and eax, 0x40 ; (1 << 6) and eax, 0x40 ; (1 << 6)
jz .no_mmap jz .no_mmap
mov esi, [edi + mb_info.mmap_length]
mov ebx, [edi + mb_info.mmap_addr] push dword [edi + mb_info.mmap_length]
.loop: push dword [edi + mb_info.mmap_addr]
mov eax, ebx call setup_pmm_mmap
LOG msg_mmap_entry, dword [eax + mb_mmap.addr + 4], \ add esp, 8
dword [eax + mb_mmap.addr], \
dword [eax + mb_mmap.length + 4], \
dword [eax + mb_mmap.length], \
dword [eax + mb_mmap.type]
mov eax, [ebx + mb_mmap.size]
add eax, 0x4
add ebx, eax
sub esi, eax
jnz .loop
jmp .end_mem_detection jmp .end_mem_detection
@ -40,16 +302,30 @@ setup_pmm:
and eax, 0x1 and eax, 0x1
jz .err jz .err
xor eax, eax push dword [edi + mb_info.mem_upper]
mov ecx, [edi + mb_info.mem_lower] push dword [edi + mb_info.mem_lower]
shl ecx, 0xA ; ecx * 1KiB call setup_pmm_legacy
LOG msg_mem_block, eax, ecx add esp, 8
mov eax, 0x100000
mov ecx, [edi + mb_info.mem_upper]
shl ecx, 0xA
LOG msg_mem_block, eax, ecx
.end_mem_detection: .end_mem_detection:
;; mark bitmap as used
xor ebx, ebx
mov edi, [bitmap_info + bitmap.addr]
mov esi, [bitmap_info]
push dword 1 ; bitmap_mark(addr, 1) == set
.loop:
cmp ebx, edi
jnb .end_loop
add edi, ebx
push edi
call bitmap_mark
add esp, 4
add ebx, 0x1000
jmp .loop
.end_loop:
add esp, 4 ; previous "push dword 0"
xor eax, eax xor eax, eax
jmp .end jmp .end
@ -62,6 +338,27 @@ setup_pmm:
leave leave
ret ret
global alloc_frame
alloc_frame:
push esp
mov ebp, esp
leave
ret
global free_frame
free_frame:
push esp
mov ebp, esp
leave
ret
section .data
bitmap_info:
dd 0 ; size
dd 0 ; ptr
section .rodata section .rodata
warn_no_mmap db "[WARN] mmap flag not set", 0 warn_no_mmap db "[WARN] mmap flag not set", 0
msg_mmap_entry db "Memory Map Entry:", 0xA msg_mmap_entry db "Memory Map Entry:", 0xA
@ -71,4 +368,6 @@ msg_mmap_entry db "Memory Map Entry:", 0xA
msg_mem_block db "Free Memory:", 0xA msg_mem_block db "Free Memory:", 0xA
db 0x9, "Address: %x", 0xA db 0x9, "Address: %x", 0xA
db 0x9, "Length: %x", 0 db 0x9, "Length: %x", 0
msg_max_mem db "Max memory: %x", 0
msg_bitmap_stored_at db "Bitmap stored at: %x", 0
file db __FILE__, 0 file db __FILE__, 0

11
kernel/syscall.s Normal file
View file

@ -0,0 +1,11 @@
[BITS 32]
global syscall_table
syscall_table:
dd 0 ; sys_exit
dd 0 ; sys_fork
dd 0 ; sys_read
dd 0 ; sys_write
dd 0 ; sys_open
dd 0 ; sys_close
.end: