diff options
author | Marvin Borner | 2020-06-20 19:26:17 +0200 |
---|---|---|
committer | Marvin Borner | 2020-06-20 19:26:17 +0200 |
commit | e2a264fa749bcf7a332b0d474eb527d988531472 (patch) | |
tree | ae38a384cda40451d6919f3d1a09efa1fda85e9c | |
parent | cdea72777ae088e865b1100436a7ece7d5877347 (diff) |
Added static binary kernel loading
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rwxr-xr-x | run | 11 | ||||
-rw-r--r-- | src/entry.asm | 112 | ||||
-rw-r--r-- | src/main.c | 32 |
4 files changed, 150 insertions, 7 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 3dac915..f56ef51 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,7 +33,7 @@ file(GLOB_RECURSE apps_sources apps/*.c) # MELVIX add_executable(melvix ${sources}) set_target_properties(melvix PROPERTIES OUTPUT_NAME "${CMAKE_CURRENT_SOURCE_DIR}/build/melvix.bin") -target_link_libraries(melvix PRIVATE "-T ${CMAKE_CURRENT_SOURCE_DIR}/src/link.ld") +target_link_libraries(melvix PRIVATE "-Ttext 0x0050000") # APPS foreach(loop_file ${apps_sources}) @@ -89,6 +89,7 @@ make_cross() { } make_build() { + rm -rf ./disk/bin/ ./disk/boot/ mkdir -p build/ disk/bin/ disk/boot echo "Building..." @@ -97,12 +98,13 @@ make_build() { make cd .. - # Create disk image - make_genext2fs - /usr/local/bin/genext2fs -B 4096 -d disk/ -U -N 4096 -b 65536 build/disk.img - + # Copy files nasm src/entry.asm -f bin -o disk/boot/boot.bin cp build/melvix.bin disk/boot/ + + # Create disk image + make_genext2fs + /usr/local/bin/genext2fs -B 1024 -d disk/ -U -N 1024 -b 65536 build/disk.img dd if=disk/boot/boot.bin of=build/disk.img conv=notrunc printf "Build finshed successfully!\n\n" @@ -147,7 +149,6 @@ elif [ "${mode}" = "clean" ]; then make_clean elif [ "${mode}" = "test" ]; then make_cross - make_clean make_build make_sync & make_test diff --git a/src/entry.asm b/src/entry.asm index 0567f61..65ce0fc 100644 --- a/src/entry.asm +++ b/src/entry.asm @@ -98,8 +98,118 @@ stage_two: mov si, disk_success_msg call print - jmp $ + mov ax, [superblock + 1024 + 8] ; Inode table + mov cx, 2 + mul cx ; ax = cx * ax + + mov [lba], ax ; Sector + + mov ax, 2 + mov [count], ax ; Read 1024 bytes + + mov bx, 0x1000 ; Copy data to 0x1000 + mov [dest], bx + + call disk_read + + ; TODO: File crawling instead of fixed inode + xor bx, bx + mov bx, 0x1200 ; First block (4 * 128) + mov cx, [bx + 28] ; Number of sectors for inode + lea di, [bx + 40] ; Address of first block pointer + + mov bx, 0x5000 + mov [dest + 2], bx + mov bx, 0 ; Inode location = 0xF0000 + mov [dest], bx + call stage_three_load + jmp protected_mode_enter + +stage_three_load: + xor ax, ax ; Clear ax + mov dx, ax ; Clear dx + mov ax, [di] ; Set ax = block pointer + mov dx, 2 ; Mul 2 for sectors + mul dx ; ax = dx * ax + + mov [lba], ax + mov [dest], bx + + call disk_read + + add bx, 0x400 ; 1kb increase + add di, 0x4 ; Move to next block pointer + sub cx, 0x2 ; Read 2 blocks + jnz stage_three_load + ret + + nop + hlt + +protected_mode_enter: + cli ; Turn off interrupts + + in al, 0x92 ; Enable A20 + or al, 2 + out 0x92, al + + ; Clear registers + xor ax, ax + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + lgdt [gdt_desc] ; Load GDT + + mov eax, cr0 + or eax, 1 ; Set bit 0 + mov cr0, eax + + jmp 08h:protected_mode ; JUMP! + +bits 32 ; Woah! +protected_mode: + xor eax, eax + + mov ax, 10h ; Set data segement indentifier + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov ss, ax ; Stack segment + mov esp, 0x00900000 ; Move stack pointer + + mov edx, 0x00050000 + lea eax, [edx] + call eax + +; GDT +align 32 +gdt: +gdt_null: + dd 0 + dd 0 +gdt_code: + dw 0xFFFF + dw 0 + db 0 + db 0x9A + db 0xCF + db 0 +gdt_data: + dw 0xFFFF + dw 0 + db 0 + db 0x92 + db 0xcF + db 0 +gdt_end: +gdt_desc: + dw gdt_end - gdt - 1 + dd gdt times 1024 - ($ - $$) db 0 + superblock: @@ -1,5 +1,37 @@ +unsigned char inb(unsigned short port) +{ + unsigned char value; + __asm__ volatile("inb %1, %0" : "=a"(value) : "Nd"(port)); + return value; +} + +void outb(unsigned short port, unsigned char data) +{ + __asm__ volatile("outb %0, %1" ::"a"(data), "Nd"(port)); +} + +int is_transmit_empty() +{ + return inb(0x3f8 + 5) & 0x20; +} + +void serial_put(char ch) +{ + while (is_transmit_empty() == 0) + ; + outb(0x3f8, (unsigned char)ch); +} + int main(int argc, char *argv[]) { + outb(0x3f8 + 1, 0x00); + outb(0x3f8 + 3, 0x80); + outb(0x3f8 + 0, 0x03); + outb(0x3f8 + 1, 0x00); + outb(0x3f8 + 3, 0x03); + outb(0x3f8 + 2, 0xC7); + outb(0x3f8 + 4, 0x0B); + serial_put('a'); while (1) { }; return 0; |