From: Elias Fleckenstein Date: Fri, 26 Aug 2022 21:00:19 +0000 (+0200) Subject: Finish paging driver X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=e1470b27ae9e9e18e89cfa6908936667b4cc2b4d;p=nyax.git Finish paging driver --- diff --git a/stage2/main.asm b/stage2/main.asm index 1e3ab94..50fee42 100644 --- a/stage2/main.asm +++ b/stage2/main.asm @@ -5,7 +5,7 @@ %define VESAMODE VESAINFO+512 %define OWNMODE VESAMODE+256 %define GFXINFO PAGETABLE-10 -%define MEMMAPCNT GFXINFO-2 +;%define MEMMAPCNT GFXINFO-2 %define MEMMAP 0x500 setup: @@ -14,7 +14,7 @@ setup: call print_str ; setup VESA - ; call vesa + call vesa ; get extended memory map call mmap diff --git a/stage2/mmap.asm b/stage2/mmap.asm index 15c81f8..b5cbe79 100644 --- a/stage2/mmap.asm +++ b/stage2/mmap.asm @@ -17,36 +17,32 @@ mmap: cmp eax, MAPMAGIC ; detect failure jne .fail - mov eax, [di+16] - cmp eax, 2 - ja .next + cmp dword[di+16], 1 + jne .next - mov eax, [di+4] - cmp eax, 0 + cmp dword[di+4], 0 jne .keep - mov eax, [di+0] - cmp eax, 0x100000 + cmp dword[di+0], 0x100000 jb .next .keep: + mov dword[di+20], 0 add di, 24 .next: cmp ebx, 0 jne .loop - mov ax, di - sub ax, MEMMAP - xor dx, dx - mov bx, 24 - div bx - mov [MEMMAPCNT], ax - - mov eax, MEMMAPCNT - call print_dec - call newline - ;jmp $ + mov dword[di+0], 0 + mov dword[di+4], 0 + + ;mov ax, di + ;sub ax, MEMMAP + ;xor dx, dx + ;mov bx, 24 + ;div bx + ;mov [MEMMAPCNT], ax ret diff --git a/stage2/paging.asm b/stage2/paging.asm index 9254d86..91ed0ac 100644 --- a/stage2/paging.asm +++ b/stage2/paging.asm @@ -21,10 +21,11 @@ paging: mov di, PAGETABLE+0x3000 .build_pt: mov [di], eax - add eax, 0x1000 add di, 8 + add eax, 0x1000 cmp eax, 0x100000 jb .build_pt + ; enable paging and long mode mov di, PAGETABLE diff --git a/stage2/vesa.asm b/stage2/vesa.asm index 5335896..da7eb81 100644 --- a/stage2/vesa.asm +++ b/stage2/vesa.asm @@ -151,6 +151,8 @@ vesa: ;mov eax, edi ;jmp $ + ;ret + ; set mode mov bx, [eax+10] ; video mode in bx (first 13 bits) or bx, 1 << 14 ; set bit 14: enable linear frame buffer diff --git a/stage3/main.asm b/stage3/main.asm index 7e1ecbd..2be97ff 100644 --- a/stage3/main.asm +++ b/stage3/main.asm @@ -1,36 +1,60 @@ global _start -extern print_str, print_dec, print_chr, clear_screen, paging +extern print_str, print_dec, print_hex, print_chr, clear_screen, page_map, page_region + +%define GFXINFO 0x1000-10 section .data headline: db "nyax stage3", 10, 10, 0 -disclaimer: db \ - "NyaX", 10, \ - "(C) 2022 Flecken-chan", 10, \ - "Dis progwam comes with ABSOLUTELY NO WAWWANTY", 10, \ - "Dis iz fwee software, and your'e welcome to redistwibute it", 10, " under certain conditions", 10, 0 +gfxregion: + .start: dq 0 + .size: dq 0 + .type: dw 2 + dw 0 section .text _start: call clear_screen - call paging - mov rdi, headline call print_str - mov rdi, disclaimer - call print_str + call page_map + + ;mov qword[rbx], -1 + + ;jmp $ + + movzx rax, word[GFXINFO+0] + movzx rbx, word[GFXINFO+4] + mov rcx, 4 + + xor rdx, rdx + mul rbx + + xor rdx, rdx + mul rcx + + xor rbx, rbx + mov ebx, [GFXINFO+6] + + mov [gfxregion.start], rbx + mov [gfxregion.size], rax + + mov r9, gfxregion + call page_region + + mov rbx, [gfxregion.start] + mov rax, [gfxregion.size] + + add rax, rbx + +.clear: + mov qword[rbx], -1 + add rbx, 8 + cmp rbx, rax + jb .clear - xor rdi, rdi -.loop: - push rdi - mov dil, 13 - call print_chr - mov rdi, [rsp] - call print_dec - pop rdi - inc rdi - jmp .loop + jmp $ diff --git a/stage3/paging.asm b/stage3/paging.asm index 3b4d364..2b7aa45 100644 --- a/stage3/paging.asm +++ b/stage3/paging.asm @@ -1,106 +1,167 @@ -global paging +global page_map, page_region extern print_hex, print_chr, newline, print_dec, print_str -global paging section .data -pagebuf: - .ptr: dq 0x5000 - .size: dq 0x3000 +dd 0 + +pagebuf_init: + .start: dq 0x5000 + .size: dq 0x2000 .used: dq 0 +pagebuf: dq pagebuf_init + +next_page: dq 0 + section .text + +; allocate new page table buffer alloc: - mov rdi, .msg - call print_str - jmp $ -.msg: db "cock", 10, 0 + ; rsi = buffer (result) + ; rdi = next_page + ; r8 = pagebuf + ; rbx = upper + ; rax = tmp; used_next -tables: -; level 4 + mov r8, [pagebuf] ; *pagebuf + mov rsi, [r8] ; start = pagebuf->start + + mov rbx, [r8+8] ; size = pagebuf->size + add rbx, rsi ; upper_have = start + size + + ; round *up* to 0x1000 align mov rax, 0xfff - not rax ; offset mask + add rsi, rax + not rax + and rsi, rax ; aligned_start = (start + 0xfff) & (~0xfff) - mov rbx, -1 ; low bits mask - shl rbx, 3 ; + mov rax, [r8+16] ; used = pagebuf->used + add rax, 0x1000 + add rsi, rax ; upper_need = aligned_start + used + 0x1000 - xor rcx, rcx + cmp rsi, rbx ; if upper_need > upper_have + ja .newbuf ; current region is full, get new - mov r14, r10 - mov r13, r10 - mov r12, r10 - mov r11, r10 + cmp rsi, r10 ; if upper_need >= next_page + jae .oom ; out of memory (target buffer isn't paged yet) - not rcx ; negate remainder mask - and r14, rcx ; apply remainder mask - mov rcx, -1 ; reset remainder mask - shl rcx, 12+9+9+9 ; update remainder mask + mov [r8+16], rax ; pagebuf->used = used + 0x1000 - shr r14, 12+9+9+9-3 ; divide - and r14, rbx ; clear lower bits + ; clear out buffer - mov rdx, 0x1000 ; offset - and rdx, rax ; offset mask - add r14, rdx ; add offset + mov rbx, rsi + sub rsi, 0x1000 - not rcx ; negate remainder mask - and r13, rcx ; apply remainder mask - mov rcx, -1 ; reset remainder mask - shl rcx, 12+9+9 ; update remainder mask +.clear: + sub rbx, 8 + mov qword[rbx], 0 + cmp rbx, rsi + jne .clear - shr r13, 12+9+9-3 ; divide - and r13, rbx ; clear lower bits + ret - mov rdx, [r14] ; offset - jnz .exist3 - call alloc -.exist3: - and rdx, rax ; offset mask - add r13, rdx ; add offset +; select next page buffer +.newbuf: + cmp r8, pagebuf_init + jne .nextbuf + mov r8, 0x500 + jmp .trybuf - not rcx ; negate remainder mask - and r12, rcx ; apply remainder mask - mov rcx, -1 ; reset remainder mask - shl rcx, 12+9 ; update remainder mask +.nextbuf: + add r8, 24 - shr r12, 12+9-3 ; divide - and r12, rbx ; clear lower bits +.trybuf: + cmp qword[r8], 0 + je .oom ; last region reached - mov rdx, [r13] ; offset - jnz .exist2 - call alloc -.exist2: - and rdx, rax ; offset mask - add r12, rdx ; add offset + mov rax, [r8+16] + + cmp rax, -1 + je .nextbuf ; region is reserved + + cmp rax, 0 + jne .oom ; region has not been paged yet + + mov [pagebuf], r8 + jmp alloc + +.oom: + push rdi + + mov rdi, .oom_msg + call print_str + + pop rdi + + call print_hex + call newline + + jmp $ + +.oom_msg: db "out of memory for page table", 10, "next_page = ", 0 + +; get/create page tables +get_tables: +; level 4 + + ; rdi = address (arg, persist) + ; rax = tmp + ; rbx = mask + ; rcx = bits (persist) + ; rdx = level (persist) + ; r8 = table address + ; rsi = next offset (persist) + + mov cl, 12+9*4 + mov dl, 4 + mov rsi, 0x1000 + +; level 4 +.level: + dec dl + mov r8, rdi + mov rbx, -1 ; reset remainder mask + shl rbx, cl ; update remainder mask + not rbx ; negate remainder mask + and r8, rbx ; apply remainder mask - not rcx ; negate remainder mask - and r11, rcx ; apply remainder mask + mov al, 9 + mul dl + add al, 12 + mov cl, al - mov rcx, -1 ; reset remainder mask - shl rcx, 12 ; update remainder mask + shr r8, cl ; divide + shl r8, 3 ; multiply by 8 - shr r11, 12-3 ; divide - and r11, rbx ; clear lower bits + mov rbx, 0xfff ; 0x1000 alignment + not rbx ; offset mask + + and rsi, rbx ; apply offset mask + add r8, rsi ; add offset + push r8 ; store + + cmp dl, 0 + je .done + + mov rsi, [r8] ; next offset + cmp rsi, 0 + jne .level - mov rdx, [r12] ; offset - jnz .exist1 call alloc -.exist1: - and rdx, rax ; offset mask - add r11, rdx ; add offset + or rsi, 3 + mov r8, [rsp] + mov [r8], rsi - ret + jmp .level -; level1 - mov rax, r11 - xor rdx, rdx - mov rbx, 8 - mul rbx - mov r11, rax - add r11, [r12] - sub r11, 3 +.done: + pop r11 + pop r12 + pop r13 + pop r14 ret @@ -108,92 +169,157 @@ space: mov dil, ' ' jmp print_chr -paging: - mov r8, 0x0500 ; start of extended memory map - movzx r9, word[0x1000-10-2] ; number of map entries - - mov r15, pagebuf +page_region: + mov rdi, [r9] ; ptr = mmap_entry->ptr + mov r10, [next_page] -.loop: - ;mov r10, [r8] - ;call tables + push rdi - mov r10, 0xfffff - call tables + mov rax, 1 << 63 - mov rdi, r14 + or rdi, rax call print_hex call space - mov rdi, r13 - call print_hex - call space + mov rdi, [r9+8] + add rdi, [rsp] + or rdi, rax - mov rdi, r12 call print_hex - call space + call newline - mov rdi, r11 - call print_hex - call space + pop rdi - mov rdi, [r11] - call print_hex + ; for usable region (type = 1), set mmap_entry->used = 0 + ; for reserved region (type = 2), set mmap_entry->used = -1 + xor rax, rax + xor rbx, rbx + mov eax, dword[r9+16] + cmp rax, 1 + je .set_used + dec rbx +.set_used: + mov [r9+16], rbx - jmp $ + mov r10, rdi + mov r15, rdi ; r15 = end of region + add r15, [r9+8] - mov rdi, r12 - call print_hex - call space + mov rax, 0xfff + not rax + and rdi, rax ; round down to 0x1000 aligned - mov rdi, r11 - call print_hex - call space + cmp rdi, r10 + jb .get_tables - mov rdi, r10 - call print_hex - call space + mov r10, rdi +.get_tables: + call get_tables ; page tables into r11-r14 + ; start filling L1 map +.l1: + mov rax, rdi + or rax, 3 + mov [r11], rax - call newline + add rdi, 0x1000 - jmp $ + cmp rdi, r10 + jb .next - ;jmp $ + mov r10, rdi - ;mov rcx, 1 << 63 - ;or rdi, rcx - ;call print_hex +.next: + cmp rdi, r15 ; if next >= end + jae .done - ;mov dil, ' ' - ;call print_chr + ; prepare rcx mask for later + mov rcx, -1 + shl rcx, 3 - ;mov rax, [rsp] - ;mov rdi, [rax+8] + ; bump L1 - ;mov rcx, 1 << 63 - ;or rdi, rcx - ;call print_hex + add r11, 8 + mov rax, r11 + and rax, 0xfff + jnz .l1 - ;mov dil, ' ' - ;call print_chr + ; bump L2 - ; mov rax, [rsp] - ;xor rdi, rdi - ;mov edi, [rax+16] - ;call print_dec + add r12, 8 + mov rax, r12 + and rax, 0xfff + jnz .l2 - ;call newline + ; bump L3 - ;pop rax - add r8, 24 + add r13, 8 + mov rax, r13 + and rax, 0xfff + jnz .l3 + + ; bump L4 + + add r14, 8 + mov rax, r14 + and rax, 0xfff + jnz .l4 - ;pop rbx + ; machine has more than 256TB of RAM, tell user to fuck off + jmp .bruh - dec r9 - jnz .loop +.l4: + mov r13, [r14] + and r13, rcx + jnz .l3 + call alloc + mov r13, rsi + or rsi, 3 + mov [r14], rsi + +.l3: + mov r12, [r13] + and r12, rcx + jnz .l2 + + call alloc + mov r12, rsi + or rsi, 3 + mov [r13], rsi + +.l2: + mov r11, [r12] + and r11, rcx + jnz .l2 + + call alloc + mov r11, rsi + or rsi, 3 + mov [r12], rsi + + jmp .l1 + +.done: + mov [next_page], r10 + ret + +.bruh: + mov rdi, .bruh_msg + call print_str jmp $ +.bruh_msg: db "bruh why do you have more than 256TB of RAM (you fucking glow)", 10, 0 + +; identity map available memory +page_map: + mov r9, 0x0500 ; mmap_entry +.entry: + cmp qword[r9], 0 + je .done + call page_region + add r9, 24 + jmp .entry +.done: ret