diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9622eef --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +default: + nasm boot.asm -f bin -o bin/boot.bin + nasm extended.asm -f elf64 -o bin/extended.o + gcc -ffreestanding -mno-red-zone -m64 -c kernel.cpp -o bin/kernel.o + ld -Ttext 0x8000 bin/extended.o bin/kernel.o -o bin/kernel.tmp + objcopy -O binary bin/kernel.tmp bin/kernel.bin + copy /b bin\boot.bin+bin\kernel.bin bin\final.bin + qemu-system-x86_64 bin/final.bin \ No newline at end of file diff --git a/bin/boot.bin b/bin/boot.bin new file mode 100644 index 0000000..a228ce2 Binary files /dev/null and b/bin/boot.bin differ diff --git a/bin/extended.o b/bin/extended.o new file mode 100644 index 0000000..765e2f8 Binary files /dev/null and b/bin/extended.o differ diff --git a/bin/final.bin b/bin/final.bin new file mode 100644 index 0000000..9559099 Binary files /dev/null and b/bin/final.bin differ diff --git a/bin/final.tmp b/bin/final.tmp new file mode 100644 index 0000000..f487126 Binary files /dev/null and b/bin/final.tmp differ diff --git a/bin/kernel.bin b/bin/kernel.bin new file mode 100644 index 0000000..e0d9e04 Binary files /dev/null and b/bin/kernel.bin differ diff --git a/bin/kernel.o b/bin/kernel.o new file mode 100644 index 0000000..e86408b Binary files /dev/null and b/bin/kernel.o differ diff --git a/bin/kernel.tmp b/bin/kernel.tmp new file mode 100644 index 0000000..d59648e Binary files /dev/null and b/bin/kernel.tmp differ diff --git a/boot.asm b/boot.asm new file mode 100644 index 0000000..32c7c00 --- /dev/null +++ b/boot.asm @@ -0,0 +1,10 @@ +[org 0x7c00] + +mov [BOOT_DISK], dl +call read_disk + +jmp PROGRAM_SPACE +%include "read_disk.asm" +%include "io.asm" +times 510 - ($ - $$) db 0 +dw 0xaa55 \ No newline at end of file diff --git a/cpuid.asm b/cpuid.asm new file mode 100644 index 0000000..b971375 --- /dev/null +++ b/cpuid.asm @@ -0,0 +1,29 @@ +detect_cpuid: + pushfd + pop eax + mov ecx, eax + xor eax, 1 << 21 + push eax + popfd + + pushfd + pop eax + push ecx + popfd + + xor eax, ecx + jz no_cpuid + ret + +detect_long_mode: + mov eax, 0x80000001 + cpuid + test edx, 1 << 29 + jz no_long_mode + ret + +no_cpuid: + hlt + +no_long_mode: + hlt \ No newline at end of file diff --git a/extended.asm b/extended.asm new file mode 100644 index 0000000..05e8f36 --- /dev/null +++ b/extended.asm @@ -0,0 +1,47 @@ +jmp enter_protected_mode +%include "gdt.asm" + +enter_protected_mode: + call enable_a20 + cli + lgdt [gdt_descriptor] + mov eax, cr0 + or eax, 1 + mov cr0, eax + jmp codeseg:start_protected_mode + +enable_a20: + in al, 0x92 + or al, 2 + out 0x92, al + ret + +[bits 32] +%include "cpuid.asm" +%include "identity_paging.asm" + +start_protected_mode: + mov ax, dataseg + mov ds, ax + mov es, ax + mov ss, ax + mov fs, ax + mov gs, ax + call detect_cpuid + call detect_long_mode + call setup_identity_paging + call edit_gdt + jmp codeseg:start_long_mode + +[bits 64] +[extern _start] + +start_long_mode: + mov edi, 0xb8000 + mov rax, 0x0f200f200f200f20 + mov ecx, 500 + rep stosq + call _start + jmp $ + +times 2048 - ($ - $$) db 0 \ No newline at end of file diff --git a/gdt.asm b/gdt.asm new file mode 100644 index 0000000..501fae8 --- /dev/null +++ b/gdt.asm @@ -0,0 +1,36 @@ +gdt_nulldesc: + dd 0, 0 + +gdt_codedesc: + dw 0xFFFF + dw 0x0000 + db 0x00 + db 10011010b + db 11001111b + db 0x00 + +gdt_datadesc: + dw 0xFFFF + dw 0x0000 + db 0x00 + db 10010010b + db 11001111b + db 0x00 + +gdt_end: + +gdt_descriptor: + gdt_size: + dw gdt_end - gdt_nulldesc - 1 + dd gdt_nulldesc + +codeseg equ gdt_codedesc - gdt_nulldesc +dataseg equ gdt_datadesc - gdt_nulldesc + +[bits 32] +edit_gdt: + mov [gdt_codedesc + 6], byte 10101111b + mov [gdt_datadesc + 6], byte 10101111b + ret + +[bits 16] \ No newline at end of file diff --git a/identity_paging.asm b/identity_paging.asm new file mode 100644 index 0000000..20baac6 --- /dev/null +++ b/identity_paging.asm @@ -0,0 +1,34 @@ +paging_table_entry equ 0x1000 + +setup_identity_paging: + mov edi, paging_table_entry + mov cr3, edi + mov dword [edi], 0x2003 + add edi, 0x1000 + mov dword [edi], 0x3003 + add edi, 0x1000 + mov dword [edi], 0x4003 + add edi, 0x1000 + + mov ebx, 0x00000003 + mov ecx, 512 + + .set_entry: + mov dword [edi], ebx + add ebx, 0x1000 + add edi, 8 + loop .set_entry + + mov eax, cr4 + or eax, 1 << 5 + mov cr4, eax + + mov ecx, 0xC0000080 + rdmsr + or eax, 1 << 8 + wrmsr + + mov eax, cr0 + or eax, 1 << 31 + mov cr0, eax + ret \ No newline at end of file diff --git a/io.asm b/io.asm new file mode 100644 index 0000000..04d906a --- /dev/null +++ b/io.asm @@ -0,0 +1,42 @@ +get_char: + mov ah, 0x0 + int 0x16 + jmp .exit + + .exit: + ret + +print: + mov ah, 0x0e + + .loop: + mov al, [bx] + cmp al, 0x0 + je .exit + int 0x10 + inc bx + jmp .loop + + .exit: + mov al, 0x0 + ret + +println: + call print + call newline + jmp .exit + + .exit: + ret + +newline: + mov ah, 0x0e + mov al, 0x0d + int 0x10 + mov al, 0xa + int 0x10 + jmp .exit + + .exit: + mov al, 0x0 + ret \ No newline at end of file diff --git a/kernel.cpp b/kernel.cpp new file mode 100644 index 0000000..eb4993d --- /dev/null +++ b/kernel.cpp @@ -0,0 +1,62 @@ +#include +#include + +#define VIDEO_MEMORY 0xb8000 +#define ROW_SIZE 80 +#define COL_SIZE 25 + +char* itoa(int value, char* str, int base) { + char *rc, *ptr, *low; + + if (base < 2 || base > 36) { + *str = '\0'; + return str; + } + + rc = ptr = str; + if (value < 0 && base == 10) *ptr++ = '-'; + low = ptr; + + do { + *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + value % base]; + value /= base; + } while (value); + + *ptr-- = '\0'; + + while (low < ptr) { + char tmp = *low; + *low++ = *ptr; + *ptr-- = tmp; + } + + return rc; +} + +uint64_t cursor_position = 0; +void print(const char* message, uint8_t color = 0x00 | 0x0F) { + for (uint64_t i = 0; 1; i++) { + if (message[i] == '\0') return; + else if (message[i] == '\n') { + cursor_position += ROW_SIZE - (cursor_position % ROW_SIZE); + continue; + } + + *(uint8_t*) (VIDEO_MEMORY + cursor_position * 2) = message[i]; + *(uint8_t*) (VIDEO_MEMORY + (cursor_position * 2) + 1) = color; + cursor_position++; + } +} + +void clear(uint8_t color = 0x00 | 0x00) { + for (uint64_t i = 0; i < ROW_SIZE * COL_SIZE; i++) { + *(uint8_t*) (VIDEO_MEMORY + i * 2) = 219; + *(uint8_t*) (VIDEO_MEMORY + (i * 2) + 1) = color; + } +} + +extern "C" void _start() { + print("sgsdg\n"); + print(itoa(199, nullptr, 10)); + return; +} \ No newline at end of file diff --git a/read_disk.asm b/read_disk.asm new file mode 100644 index 0000000..6eb4eb5 --- /dev/null +++ b/read_disk.asm @@ -0,0 +1,24 @@ +PROGRAM_SPACE equ 0x8000 + +read_disk: + mov ah, 0x02 + mov bx, PROGRAM_SPACE + mov al, 32 + mov dl, [BOOT_DISK] + mov ch, 0x00 + mov dh, 0x00 + mov cl, 0x02 + int 0x13 + jc raise_disk_read_error + ret + +raise_disk_read_error: + mov bx, disk_read_error + call print + jmp $ + +disk_read_error: + db "failed to read disk", 0x0d, 0xa, 0x0 + +BOOT_DISK: + db 0 \ No newline at end of file