diff --git a/x86_64/bootsector.asm b/x86_64/bootsector.asm index b6ef71938f..f1b463ef56 100644 --- a/x86_64/bootsector.asm +++ b/x86_64/bootsector.asm @@ -66,7 +66,7 @@ load: mov cx, 127 call load popa - add ax, 127 + add eax, 127 add dx, 127 * 512 / 16 sub cx, 127 diff --git a/x86_64/disk.asm b/x86_64/disk.asm index 1ad1923eae..6376521ed2 100644 --- a/x86_64/disk.asm +++ b/x86_64/disk.asm @@ -11,15 +11,7 @@ startup_start: align 512, db 0 startup_end: -kernel_file: - %defstr KERNEL_STR %[KERNEL] - incbin KERNEL_STR - align 512, db 0 -.end: -.length equ kernel_file.end - kernel_file -.length_sectors equ .length / 512 - -%ifdef FILESYSTEM +filesystem: %defstr FILESYSTEM_STR %[FILESYSTEM] incbin FILESYSTEM_STR -%endif + align 512, db 0 diff --git a/x86_64/redoxfs.asm b/x86_64/redoxfs.asm new file mode 100644 index 0000000000..a36ea20ceb --- /dev/null +++ b/x86_64/redoxfs.asm @@ -0,0 +1,267 @@ +struc Extent + .block: resq 1, + .length: resq 1 +endstruc + +struc Node + .mode: resw 1 + .uid: resd 1 + .gid: resd 1 + .name: resb 246 + .parent: resq 1 + .next: resq 1 + .extents: resb Extent_size * 15 +endstruc + +struc Header + ; Signature, should be b"RedoxFS\0" + .signature: resb 8 + ; Version, should be 1 + .version: resq 1, + ; Disk ID, a 128-bit unique identifier + .uuid: resb 16, + ; Disk size, in 512-byte sectors + .size: resq 1, + ; Block of root node + .root: resq 1, + ; Block of free space node + .free: resq 1 + ; Padding + .padding: resb 456 +endstruc + +redoxfs: + call redoxfs.open + test eax, eax + jz .good_header + ret + + .good_header: + mov eax, [.header + Header.root] + mov bx, .dir + call .node + + jmp redoxfs.root + + ; node in eax, buffer in bx + .node: + add eax, (filesystem - boot) / 512 + mov cx, 1 + mov dx, 0 + call load + call print_line + ret + + align 512, db 0 + + .header: + times 512 db 0 + + .dir: + times 512 db 0 + + .file: + times 512 db 0 + +redoxfs.open: + mov eax, 0 + mov bx, redoxfs.header + call redoxfs.node + + mov bx, 0 + .sig: + mov al, [redoxfs.header + Header.signature + bx] + mov ah, [.signature + bx] + cmp al, ah + jne .sig_err + inc bx + cmp bx, 8 + jl .sig + + mov bx, 0 + .ver: + mov al, [redoxfs.header + Header.version + bx] + mov ah, [.version + bx] + cmp al, ah + jne .ver_err + inc bx + jl .ver + + lea si, [redoxfs.header + Header.signature] + call printrm + call print_line + + xor ax, ax + ret + + .err_msg: db "Failed to open RedoxFS: ",0 + .sig_err_msg: db "Signature error",13,10,0 + .ver_err_msg: db "Version error",13,10,0 + + .sig_err: + mov si, .err_msg + call printrm + + mov si, .sig_err_msg + call printrm + + mov ax, 1 + ret + + .ver_err: + mov si, .err_msg + call printrm + + mov si, .ver_err_msg + call printrm + + mov ax, 1 + ret + + .signature: db "RedoxFS",0 + .version: dq 1 + + +redoxfs.root: + lea si, [redoxfs.dir + Node.name] + call printrm + call print_line + + .lp: + mov bx, 0 + .ext: + mov eax, [redoxfs.dir + Node.extents + bx + Extent.block] + test eax, eax + jz .next + + mov ecx, [redoxfs.dir + Node.extents + bx + Extent.length] + test ecx, ecx + jz .next + + add ecx, 511 + shr ecx, 9 + + push bx + + .ext_sec: + push eax + push ecx + + mov bx, redoxfs.file + call redoxfs.node + + mov bx, 0 + .ext_sec_kernel: + mov al, [redoxfs.file + Node.name + bx] + mov ah, [.kernel_name + bx] + + cmp al, ah + jne .ext_sec_kernel_break + + inc bx + + test ah, ah + jnz .ext_sec_kernel + + pop ecx + pop eax + pop bx + jmp redoxfs.kernel + + .ext_sec_kernel_break: + pop ecx + pop eax + + inc eax + dec ecx + jnz .ext_sec + + pop bx + + add bx, Extent_size + cmp bx, Extent_size * 16 + jb .ext + + .next: + mov eax, [redoxfs.dir + Node.next] + test eax, eax + jz .no_kernel + + mov bx, redoxfs.dir + call redoxfs.node + jmp .lp + + .no_kernel: + mov si, .no_kernel_msg + call printrm + + mov si, .kernel_name + call printrm + + call print_line + + mov eax, 1 + ret + + .kernel_name: db "kernel",0 + .no_kernel_msg: db "Did not find: ",0 + +redoxfs.kernel: + lea si, [redoxfs.file + Node.name] + call printrm + call print_line + + mov edi, [kernel_base] + .lp: + mov bx, 0 + .ext: + mov eax, [redoxfs.file + Node.extents + bx + Extent.block] + test eax, eax + jz .next + + mov ecx, [redoxfs.file + Node.extents + bx + Extent.length] + test ecx, ecx + jz .next + + push bx + + push eax + push ecx + push edi + + add eax, (filesystem - boot)/512 + add ecx, 511 + shr ecx, 9 + call load_extent + + pop edi + pop ecx + pop eax + + add edi, ecx + + pop bx + + add bx, Extent_size + cmp bx, Extent_size * 16 + jb .ext + + .next: + mov eax, [redoxfs.file + Node.next] + test eax, eax + jz .done + + push edi + + mov bx, redoxfs.file + call redoxfs.node + + pop edi + jmp .lp + + .done: + sub edi, [kernel_base] + mov [kernel_size], edi + + xor eax, eax + ret diff --git a/x86_64/startup-common.asm b/x86_64/startup-common.asm index ab6b77b0e0..2b9bd923d0 100644 --- a/x86_64/startup-common.asm +++ b/x86_64/startup-common.asm @@ -1,76 +1,16 @@ SECTION .text USE16 +kernel_base dq 0x100000 +kernel_size dq 0 + startup: ; enable A20-Line via IO-Port 92, might not work on all motherboards in al, 0x92 or al, 2 out 0x92, al -; loading kernel to 1MiB -; move part of kernel to startup_end via bootsector#load and then copy it up -; repeat until all of the kernel is loaded - -; buffersize in multiple of sectors (512 Bytes) -; min 1 -; max (0x70000 - startup_end) / 512 -buffer_size_sectors equ 127 -; buffer size in Bytes -buffer_size_bytes equ buffer_size_sectors * 512 - -kernel_base equ 0x100000 - - ; how often do we need to call load and move memory - mov ecx, kernel_file.length_sectors / buffer_size_sectors - - mov eax, (kernel_file - boot) / 512 - mov edi, kernel_base - cld -.lp: - ; saving counter - push cx - - ; populating buffer - mov cx, buffer_size_sectors - mov bx, kernel_file - mov dx, 0x0 - - push edi - push eax - call load - - ; moving buffer - call unreal - pop eax - pop edi - - mov esi, kernel_file - mov ecx, buffer_size_bytes / 4 - a32 rep movsd - - ; preparing next iteration - add eax, buffer_size_sectors - - pop cx - loop .lp - - ; load the part of the kernel that does not fill the buffer completely - mov cx, kernel_file.length_sectors % buffer_size_sectors - test cx, cx - jz finished_loading ; if cx = 0 => skip - - mov bx, kernel_file - mov dx, 0x0 - call load - - ; moving remnants of kernel - call unreal - - mov esi, kernel_file - mov ecx, (kernel_file.length_sectors % buffer_size_bytes) / 4 - a32 rep movsd -finished_loading: - call print_line + call redoxfs call memory_map @@ -93,6 +33,79 @@ finished_loading: jmp startup_arch +# load a disk extent into high memory +# eax - sector address +# ecx - sector count +# edi - destination +load_extent: + ; loading kernel to 1MiB + ; move part of kernel to startup_end via bootsector#load and then copy it up + ; repeat until all of the kernel is loaded + buffer_size_sectors equ 127 + +.lp: + cmp ecx, buffer_size_sectors + jb .break + + ; saving counter + push eax + push ecx + + push edi + + ; populating buffer + mov ecx, buffer_size_sectors + mov bx, startup_end + mov dx, 0x0 + + ; load sectors + call load + + ; set up unreal mode + call unreal + + pop edi + + ; move data + mov esi, startup_end + mov ecx, buffer_size_sectors * 512 / 4 + cld + a32 rep movsd + + pop ecx + pop eax + + add eax, buffer_size_sectors + sub ecx, buffer_size_sectors + jmp .lp + +.break: + ; load the part of the kernel that does not fill the buffer completely + test ecx, ecx + jz .finish ; if cx = 0 => skip + + push ecx + push edi + + mov bx, startup_end + mov dx, 0x0 + call load + + ; moving remnants of kernel + call unreal + + pop edi + pop ecx + + mov esi, startup_end + shl ecx, 7 ; * 512 / 4 + cld + a32 rep movsd + +.finish: + call print_line + ret + %include "config.asm" %include "descriptor_flags.inc" %include "gdt_entry.inc" @@ -100,6 +113,7 @@ finished_loading: %include "memory_map.asm" %include "vesa.asm" %include "initialize.asm" +%include "redoxfs.asm" init_fpu_msg: db "Init FPU",13,10,0 init_sse_msg: db "Init SSE",13,10,0 diff --git a/x86_64/startup-x86_64.asm b/x86_64/startup-x86_64.asm index 963d72b930..17883cd20c 100644 --- a/x86_64/startup-x86_64.asm +++ b/x86_64/startup-x86_64.asm @@ -123,9 +123,9 @@ long_mode: mov ss, rax ; kernel_base - mov rdi, kernel_base + mov rdi, [kernel_base] ; kernel_size - mov rsi, kernel_file.length + mov rsi, [kernel_size] ; stack_base mov rdx, 0xFFFFFF0000080000 ; stack_size @@ -137,7 +137,7 @@ long_mode: sub rsp, 256 ; entry point - mov rax, [kernel_base + 0x18] + mov rax, [rdi + 0x18] jmp rax long_mode_ap: