diff --git a/.gitignore b/.gitignore index b793d89..af758fc 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ *.bin *.iso *~ +\#*\# *.elf *.a @@ -11,3 +12,5 @@ vmstupid /sysroot + +log.txt diff --git a/README.md b/README.md index 607fc70..4205278 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [Website](https://stupidos.d0p1.eu) ![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 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) diff --git a/kernel/head.s b/kernel/head.s index 3bac1bb..5895d82 100644 --- a/kernel/head.s +++ b/kernel/head.s @@ -68,6 +68,7 @@ entry: jmp hang .mem_ok: + LOG msg_pmm_initialized extern 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_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_cannot_map_memory db "[ERROR] Can't map memory", 0 diff --git a/kernel/idt.s b/kernel/idt.s index a19760c..a1ec1d0 100644 --- a/kernel/idt.s +++ b/kernel/idt.s @@ -4,6 +4,7 @@ global setup_idt setup_idt: %assign i 0 %rep 32 + ;; TODO: refactor extern isr %+ i mov eax, isr %+ i ; offset (low) diff --git a/kernel/linker.ld b/kernel/linker.ld index 3f7c437..b1e5e42 100644 --- a/kernel/linker.ld +++ b/kernel/linker.ld @@ -26,3 +26,5 @@ SECTIONS kernel_end = .; } + +kernel_size = kernel_end - kernel_start; diff --git a/kernel/pmm.s b/kernel/pmm.s index b0ea087..98c6920 100644 --- a/kernel/pmm.s +++ b/kernel/pmm.s @@ -1,9 +1,280 @@ [BITS 32] + ;; XXX: align address to page %include "base.inc" %include "multiboot.inc" +extern kernel_size +extern kernel_end + +struc bitmap + .length: resd 1 + .addr: resd 1 +endstruc + 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 setup_pmm: push ebp @@ -15,22 +286,13 @@ setup_pmm: mov edi, [ebp + 8] mov eax, [edi] - and eax, 0x40 ; (1 << 6) + and eax, 0x40 ; (1 << 6) jz .no_mmap - mov esi, [edi + mb_info.mmap_length] - mov ebx, [edi + mb_info.mmap_addr] -.loop: - mov eax, ebx - LOG msg_mmap_entry, dword [eax + mb_mmap.addr + 4], \ - 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 + + push dword [edi + mb_info.mmap_length] + push dword [edi + mb_info.mmap_addr] + call setup_pmm_mmap + add esp, 8 jmp .end_mem_detection @@ -40,16 +302,30 @@ setup_pmm: and eax, 0x1 jz .err - xor eax, eax - mov ecx, [edi + mb_info.mem_lower] - shl ecx, 0xA ; ecx * 1KiB - LOG msg_mem_block, eax, ecx - mov eax, 0x100000 - mov ecx, [edi + mb_info.mem_upper] - shl ecx, 0xA - LOG msg_mem_block, eax, ecx + push dword [edi + mb_info.mem_upper] + push dword [edi + mb_info.mem_lower] + call setup_pmm_legacy + add esp, 8 .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 jmp .end @@ -62,6 +338,27 @@ setup_pmm: leave 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 warn_no_mmap db "[WARN] mmap flag not set", 0 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 db 0x9, "Address: %x", 0xA 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 diff --git a/kernel/syscall.s b/kernel/syscall.s new file mode 100644 index 0000000..8039951 --- /dev/null +++ b/kernel/syscall.s @@ -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: