diff --git a/kernel/asm/sector.asm b/kernel/asm/bootsector.asm similarity index 58% rename from kernel/asm/sector.asm rename to kernel/asm/bootsector.asm index f70c145740..3d36bfd938 100644 --- a/kernel/asm/sector.asm +++ b/kernel/asm/bootsector.asm @@ -1,6 +1,6 @@ -use16 - -org 0x7C00 +ORG 0x7C00 +SECTION .text +USE16 boot: ; dl comes with disk ; initialize segment registers @@ -8,6 +8,7 @@ boot: ; dl comes with disk mov ds, ax mov es, ax mov ss, ax + ; initialize stack mov sp, 0x7C00 @@ -22,9 +23,9 @@ boot: ; dl comes with disk call print_num call print_line - mov ax, (fs_header - boot)/512 + mov ax, (fs_header - boot) / 512 mov bx, fs_header - mov cx, (kernel_file.end - fs_header)/512 + mov cx, (startup_end - fs_header) / 512 xor dx, dx call load @@ -34,6 +35,17 @@ boot: ; dl comes with disk jmp startup +; load some sectors from disk to a buffer in memory +; buffer has to be below 1MiB +; IN +; ax: start sector +; bx: offset of buffer +; cx: number of sectors (512 Bytes each) +; dx: segment of buffer +; CLOBBER +; ax, bx, cx, dx, si +; TODO rewrite to (eventually) move larger parts at once +; if that is done increase buffer_size_sectors in startup-common to that (max 0x80000 - startup_end) load: cmp cx, 64 jbe .good_size @@ -43,7 +55,7 @@ load: call load popa add ax, 64 - add dx, 64*512/16 + add dx, 64 * 512 / 16 sub cx, 64 jmp load @@ -86,59 +98,16 @@ load: jc error ret -print_char: - mov ah, 0x0e - int 0x10 - ret - -print_num: - mov cx, 4 -.loop: - mov al, bh - shr al, 4 - and al, 0xF - - cmp al, 0xA - jb .below_a - - add al, 'A' - '0' - 0xA -.below_a: - add al, '0' - - push cx - push bx - call print_char - pop bx - pop cx - - shl bx, 4 - loop .loop - - ret - -print_line: - mov si, line - call print - ret - -print: -.loop: - lodsb - or al, al - jz .done - call print_char - jmp .loop -.done: - ret - error: - mov si, errored - call print - call print_line + mov si, errored + call print + call print_line .halt: - cli - hlt - jmp .halt + cli + hlt + jmp .halt + +%include "asm/print16.asm" name: db "Redox Loader",0 loading: db "Loading",0 @@ -149,13 +118,13 @@ line: db 13,10,0 disk: db 0 DAPACK: - db 0x10 - db 0 -.count: dw 0 ; int 13 resets this to # of blocks actually read/written -.buf: dw 0 ; memory buffer destination address (0:7c00) -.seg: dw 0 ; in memory page zero -.addr: dd 0 ; put the lba to read in this spot - dd 0 ; more storage bytes only for big lba's ( > 4 bytes ) + db 0x10 + db 0 +.count: dw 0 ; int 13 resets this to # of blocks actually read/written +.buf: dw 0 ; memory buffer destination address (0:7c00) +.seg: dw 0 ; in memory page zero +.addr: dd 0 ; put the lba to read in this spot + dd 0 ; more storage bytes only for big lba's ( > 4 bytes ) times 510-($-$$) db 0 db 0x55 diff --git a/kernel/asm/descriptor_flags.inc b/kernel/asm/descriptor_flags.inc new file mode 100644 index 0000000000..210c98d5ef --- /dev/null +++ b/kernel/asm/descriptor_flags.inc @@ -0,0 +1,46 @@ +attrib: + .present equ 1 << 7 + .ring1 equ 1 << 5 + .ring2 equ 1 << 6 + .ring3 equ 1 << 5 | 1 << 6 + .user equ 1 << 4 +;user + .code equ 1 << 3 +; code + .conforming equ 1 << 2 + .readable equ 1 << 1 +; data + .expand_down equ 1 << 2 + .writable equ 1 << 1 + .accessed equ 1 << 0 +;system +; legacy + .tssAvailabe16 equ 0x1 + .ldt equ 0x2 + .tssBusy16 equ 0x3 + .call16 equ 0x4 + .task equ 0x5 + .interrupt16 equ 0x6 + .trap16 equ 0x7 + .tssAvailabe32 equ 0x9 + .tssBusy32 equ 0xB + .call32 equ 0xC + .interrupt32 equ 0xE + .trap32 equ 0xF +; long mode + .ldt32 equ 0x2 + .tssAvailabe64 equ 0x9 + .tssBusy64 equ 0xB + .call64 equ 0xC + .interrupt64 equ 0xE + .trap64 equ 0xF + +flags: + .granularity equ 1 << 7 + .available equ 1 << 4 +;user + .default_operand_size equ 1 << 6 +; code + .long_mode equ 1 << 5 +; data + .reserved equ 1 << 5 diff --git a/kernel/asm/gdt_entry.inc b/kernel/asm/gdt_entry.inc new file mode 100644 index 0000000000..861a78be89 --- /dev/null +++ b/kernel/asm/gdt_entry.inc @@ -0,0 +1,8 @@ +struc GDTEntry + .limitl resw 1 + .basel resw 1 + .basem resb 1 + .attribute resb 1 + .flags__limith resb 1 + .baseh resb 1 +endstruc diff --git a/kernel/asm/initialize.asm b/kernel/asm/initialize.asm index fc7caae186..ffab99b2ec 100644 --- a/kernel/asm/initialize.asm +++ b/kernel/asm/initialize.asm @@ -1,80 +1,81 @@ SECTION .text -[BITS 16] +USE16 + initialize: .fpu: ;enable fpu - mov eax, cr4 - or eax, 0x200 - mov cr4, eax - mov eax, 0xB7F - push eax - fldcw [esp] - pop eax - ret + mov eax, cr4 + or eax, 0x200 + mov cr4, eax + mov eax, 0xB7F + push eax + fldcw [esp] + pop eax + ret .sse: ;enable sse - mov eax, cr0 - and al, 11111011b - or al, 00000010b - mov cr0, eax - mov eax, cr4 - or ax, 0000011000000000b - mov cr4, eax - ret + mov eax, cr0 + and al, 11111011b + or al, 00000010b + mov cr0, eax + mov eax, cr4 + or ax, 0000011000000000b + mov cr4, eax + ret ;PIT Frequency ;If using nanoseconds, to minimize drift, one should find a frequency as close to an integer nanosecond value in wavelength -;Divider Hz Nanoseconds Properties -;2685 444.38795779019242706393 2250286.00003631746492922946 Best For Context Switching -;5370 222.19397889509621353196 4500572.00007263492985856020 -;21029 56.73981961418358774390 17624306.99991199998882825455 -;23714 50.31549576902532962244 19874592.99994831745375667118 -;26399 45.19798729749864262535 22124878.99998463491868476373 -;29084 41.02536331545408701233 24375165.00002095238361424615 -;31769 37.55804925136663623868 26625451.00005726984854313455 -;34454 34.63115071302799868423 28875737.00009358731347639618 -;50113 23.80982313305263437963 41999471.99993295237244784676 -;52798 22.59899364874932131267 44249757.99996926983737931766 -;55483 21.50535599492937776736 46500044.00000558730230583335 Lowest Drift -;58168 20.51268165772704350616 48750330.00004190476724037528 -;60853 19.60760630809765610021 51000616.00007822223218031738 +;Divider Hz Nanoseconds Properties +;2685 444.38795779019242706393 2250286.00003631746492922946 Best For Context Switching +;5370 222.19397889509621353196 4500572.00007263492985856020 +;21029 56.73981961418358774390 17624306.99991199998882825455 +;23714 50.31549576902532962244 19874592.99994831745375667118 +;26399 45.19798729749864262535 22124878.99998463491868476373 +;29084 41.02536331545408701233 24375165.00002095238361424615 +;31769 37.55804925136663623868 26625451.00005726984854313455 +;34454 34.63115071302799868423 28875737.00009358731347639618 +;50113 23.80982313305263437963 41999471.99993295237244784676 +;52798 22.59899364874932131267 44249757.99996926983737931766 +;55483 21.50535599492937776736 46500044.00000558730230583335 Lowest Drift +;58168 20.51268165772704350616 48750330.00004190476724037528 +;60853 19.60760630809765610021 51000616.00007822223218031738 .pit: - ;initialize the PIT - mov ax, 2685 ;this is the divider for the PIT - out 0x40, al - rol ax, 8 - out 0x40, al - ;DISABLED ;enable rtc interrupt - ;mov al, 0xB - ;out 0x70, al - ;rol ax, 8 - ;in al, 0x71 - ;rol ax, 8 - ;out 0x70, al - ;rol ax, 8 - ;or al, 0x40 - ;out 0x71, al - ret + ;initialize the PIT + mov ax, 2685 ;this is the divider for the PIT + out 0x40, al + rol ax, 8 + out 0x40, al + ;DISABLED ;enable rtc interrupt + ;mov al, 0xB + ;out 0x70, al + ;rol ax, 8 + ;in al, 0x71 + ;rol ax, 8 + ;out 0x70, al + ;rol ax, 8 + ;or al, 0x40 + ;out 0x71, al + ret -.pic: ;sets up IRQs at int 20-2F - mov al, 0x11 - out 0x20, al - out 0xA0, al - mov al, 0x20 ;IRQ0 vector - out 0x21, al - mov al, 0x28 ;IRQ8 vector - out 0xA1, al - mov al, 4 - out 0x21, al - mov al, 2 - out 0xA1, al - mov al, 1 - out 0x21, al - out 0xA1, al - xor al, al ;no IRQ masks - out 0x21, al - out 0xA1, al - mov al, 0x20 ;reset PIC's - out 0xA0, al - out 0x20, al - ret +.pic: ;sets up IRQs at int 20-2F + mov al, 0x11 + out 0x20, al + out 0xA0, al + mov al, 0x20 ;IRQ0 vector + out 0x21, al + mov al, 0x28 ;IRQ8 vector + out 0xA1, al + mov al, 4 + out 0x21, al + mov al, 2 + out 0xA1, al + mov al, 1 + out 0x21, al + out 0xA1, al + xor al, al ;no IRQ masks + out 0x21, al + out 0xA1, al + mov al, 0x20 ;reset PIC's + out 0xA0, al + out 0x20, al + ret diff --git a/kernel/asm/interrupts-i386.asm b/kernel/asm/interrupts-i386.asm index 16c4e50720..46b4d01cae 100644 --- a/kernel/asm/interrupts-i386.asm +++ b/kernel/asm/interrupts-i386.asm @@ -3,28 +3,20 @@ struc IDTEntry .selector resw 1 .zero resb 1 .attribute resb 1 - .present equ 1 << 7 - .ring1 equ 1 << 5 - .ring2 equ 1 << 6 - .ring3 equ 1 << 5 | 1 << 6 - .task32 equ 0x5 - .interrupt16 equ 0x6 - .trap16 equ 0x7 - .interrupt32 equ 0xE - .trap32 equ 0xF .offseth resw 1 endstruc -[section .text] -[BITS 32] +SECTION .text +USE32 + interrupts: .first: - mov [0x100000], byte 0 + mov [.entry], byte 0 jmp dword .handle .second: %assign i 1 %rep 255 - mov [0x100000], byte i + mov [.entry], byte i jmp dword .handle %assign i i+1 %endrep @@ -37,7 +29,7 @@ interrupts: push ebx push eax push esp - push dword [0x100000] + push dword [.entry] mov eax, gdt.kernel_data mov ds, eax @@ -66,9 +58,10 @@ interrupts: iretd .handler: dd 0 +.entry: dd 0 idtr: - dw (idt_end - idt) + 1 + dw (idt.end - idt) + 1 dd idt idt: @@ -76,35 +69,35 @@ idt: ;Below system call %rep 128 - istruc IDTEntry - at IDTEntry.offsetl, dw interrupts+(interrupts.second-interrupts.first)*i - at IDTEntry.selector, dw gdt.kernel_code + istruc IDTEntry + at IDTEntry.offsetl, dw interrupts+(interrupts.second-interrupts.first)*i + at IDTEntry.selector, dw gdt.kernel_code at IDTEntry.zero, db 0 - at IDTEntry.attribute, db IDTEntry.present | IDTEntry.interrupt32 + at IDTEntry.attribute, db attrib.present | attrib.interrupt32 at IDTEntry.offseth, dw 0 - iend + iend %assign i i+1 %endrep ;System call istruc IDTEntry - at IDTEntry.offsetl, dw interrupts+(interrupts.second-interrupts.first)*i - at IDTEntry.selector, dw gdt.kernel_code + at IDTEntry.offsetl, dw interrupts+(interrupts.second-interrupts.first)*i + at IDTEntry.selector, dw gdt.kernel_code at IDTEntry.zero, db 0 - at IDTEntry.attribute, db IDTEntry.ring3 | IDTEntry.present | IDTEntry.interrupt32 + at IDTEntry.attribute, db attrib.present | attrib.ring3 | attrib.interrupt32 at IDTEntry.offseth, dw 0 iend %assign i i+1 ;Above system call %rep 127 - istruc IDTEntry - at IDTEntry.offsetl, dw interrupts+(interrupts.second-interrupts.first)*i - at IDTEntry.selector, dw gdt.kernel_code + istruc IDTEntry + at IDTEntry.offsetl, dw interrupts+(interrupts.second-interrupts.first)*i + at IDTEntry.selector, dw gdt.kernel_code at IDTEntry.zero, db 0 - at IDTEntry.attribute, db IDTEntry.present | IDTEntry.interrupt32 + at IDTEntry.attribute, db attrib.present | attrib.interrupt32 at IDTEntry.offseth, dw 0 - iend + iend %assign i i+1 %endrep -idt_end: +.end: diff --git a/kernel/asm/interrupts-x86_64.asm b/kernel/asm/interrupts-x86_64.asm index 9b2655d797..78b6e0ad50 100644 --- a/kernel/asm/interrupts-x86_64.asm +++ b/kernel/asm/interrupts-x86_64.asm @@ -1,32 +1,23 @@ struc IDTEntry .offsetl resw 1 .selector resw 1 - .zero1 resb 1 + .ist resb 1 .attribute resb 1 - .present equ 1 << 7 - .ring1 equ 1 << 5 - .ring2 equ 1 << 6 - .ring3 equ 1 << 5 | 1 << 6 - .task32 equ 0x5 - .interrupt16 equ 0x6 - .trap16 equ 0x7 - .interrupt32 equ 0xE - .trap32 equ 0xF .offsetm resw 1 .offseth resd 1 - .zero2 resd 1 + .reserved resd 1 endstruc -[section .text] -[BITS 64] +SECTION .text +USE64 interrupts: .first: - mov [0x100000], byte 0 + mov [.entry], byte 0 jmp qword .handle .second: %assign i 1 %rep 255 - mov [0x100000], byte i + mov [.entry], byte i jmp qword .handle %assign i i+1 %endrep @@ -53,9 +44,9 @@ interrupts: mov fs, rax mov gs, rax - mov rdi, qword [0x100000] + mov rdi, qword [.entry] mov rsi, rsp - + ;Stack Align mov rbp, rsp and rsp, 0xFFFFFFFFFFFFFFF0 @@ -90,9 +81,10 @@ interrupts: iretq .handler: dq 0 +.entry: dq 0 idtr: - dw (idt_end - idt) + 1 + dw (idt.end - idt) + 1 dq idt idt: @@ -102,12 +94,12 @@ idt: %rep 128 istruc IDTEntry at IDTEntry.offsetl, dw interrupts+(interrupts.second-interrupts.first)*i - at IDTEntry.selector, dw 0x08 - at IDTEntry.zero1, db 0 - at IDTEntry.attribute, db IDTEntry.present | IDTEntry.interrupt32 + at IDTEntry.selector, dw gdt.kernel_code + at IDTEntry.ist, db 0 + at IDTEntry.attribute, db attrib.present | attrib.interrupt64 at IDTEntry.offsetm, dw 0 at IDTEntry.offseth, dd 0 - at IDTEntry.zero2, dd 0 + at IDTEntry.reserved, dd 0 iend %assign i i+1 %endrep @@ -115,12 +107,12 @@ idt: ;Syscall istruc IDTEntry at IDTEntry.offsetl, dw interrupts+(interrupts.second-interrupts.first)*i - at IDTEntry.selector, dw 0x08 - at IDTEntry.zero1, db 0 - at IDTEntry.attribute, db IDTEntry.ring3 | IDTEntry.present | IDTEntry.interrupt32 + at IDTEntry.selector, dw gdt.kernel_code + at IDTEntry.ist, db 0 + at IDTEntry.attribute, db attrib.present | attrib.interrupt64 at IDTEntry.offsetm, dw 0 at IDTEntry.offseth, dd 0 - at IDTEntry.zero2, dd 0 + at IDTEntry.reserved, dd 0 iend %assign i i+1 @@ -128,13 +120,13 @@ iend %rep 127 istruc IDTEntry at IDTEntry.offsetl, dw interrupts+(interrupts.second-interrupts.first)*i - at IDTEntry.selector, dw 0x08 - at IDTEntry.zero1, db 0 - at IDTEntry.attribute, db IDTEntry.present | IDTEntry.interrupt32 + at IDTEntry.selector, dw gdt.kernel_code + at IDTEntry.ist, db 0 + at IDTEntry.attribute, db attrib.present | attrib.interrupt64 at IDTEntry.offsetm, dw 0 at IDTEntry.offseth, dd 0 - at IDTEntry.zero2, dd 0 + at IDTEntry.reserved, dd 0 iend %assign i i+1 %endrep -idt_end: +.end: diff --git a/kernel/asm/memory_map.asm b/kernel/asm/memory_map.asm index 82d751c092..a5cdc70c5f 100644 --- a/kernel/asm/memory_map.asm +++ b/kernel/asm/memory_map.asm @@ -1,28 +1,32 @@ SECTION .text -[BITS 16] +USE16 ;Generate a memory map at 0x500 to 0x5000 (available memory not used for kernel or bootloader) memory_map: - xor eax, eax - mov di, 0x500 - mov ecx, (0x5000 - 0x500) / 4 ; moving 4 Bytes at once - cld - rep stosd +.start equ 0x0500 +.end equ 0x5000 +.length equ .end - .start - mov di, 0x500 - mov edx, 0x534D4150 - xor ebx, ebx + xor eax, eax + mov di, .start + mov ecx, .length / 4 ; moving 4 Bytes at once + cld + rep stosd + + mov di, .start + mov edx, 0x534D4150 + xor ebx, ebx .lp: - mov eax, 0xE820 - mov ecx, 24 + mov eax, 0xE820 + mov ecx, 24 - int 0x15 - jc .done ; Error or finished + int 0x15 + jc .done ; Error or finished - cmp ebx, 0 - je .done ; Finished + cmp ebx, 0 + je .done ; Finished - add di, 24 - cmp di, 0x5000 - jb .lp ; Still have buffer space + add di, 24 + cmp di, .end + jb .lp ; Still have buffer space .done: - ret + ret diff --git a/kernel/asm/print16.asm b/kernel/asm/print16.asm new file mode 100644 index 0000000000..32dc69df8c --- /dev/null +++ b/kernel/asm/print16.asm @@ -0,0 +1,66 @@ +SECTION .text +USE16 +; provide function for printing in x86 real mode + + +; a newline +newline: db 0xD, 0xA, 0 + +; print a string and a newline +; IN +; si: points at zero-terminated String +; CLOBBER +; ax +print_line: + mov si, newline + call print + ret + +; print a string +; IN +; si: points at zero-terminated String +; CLOBBER +; ax +print: + lodsb + test al, al + jz .done + call print_char + jmp print +.done: + ret + +; print a character +; IN +; al: character to print +; CLOBBER +; ah +print_char: + mov ah, 0x0e + int 0x10 + ret + +; print a number in hex +; IN +; bx: the number +; CLOBBER +; cx, ax +print_num: + mov cx, 4 +.lp: + mov al, bh + shr al, 4 + + cmp al, 0xA + jb .below_0xA + + add al, 'A' - 0xA - '0' +.below_0xA: + add al, '0' + + call print_char + + shl bx, 4 + loop .lp + + ret diff --git a/kernel/asm/startup-common.asm b/kernel/asm/startup-common.asm new file mode 100644 index 0000000000..c6237bbad6 --- /dev/null +++ b/kernel/asm/startup-common.asm @@ -0,0 +1,89 @@ +SECTION .text +USE16 + +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 64 +; 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 ax, (kernel_file - boot) / 512 + mov edi, kernel_base + cld +.lp: + ; saving counter + push cx + + ; populating buffer + mov cx, buffer_size_sectors + mov bx, startup_end + mov dx, 0x0 + + push ax + call load + + ; moving buffer + call unreal + pop ax + + mov esi, startup_end + mov ecx, buffer_size_bytes / 4 + a32 rep movsd + + ; preparing next iteration + add ax, 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, startup_end + mov dx, 0x0 + call load + + ; moving remnants of kernel + call unreal + + mov esi, startup_end + mov ecx, (kernel_file.length_sectors % buffer_size_bytes) / 4 + a32 rep movsd +finished_loading: + + + call memory_map + + call vesa + + call initialize.fpu + call initialize.sse + call initialize.pit + call initialize.pic + + jmp startup_arch + +%include "asm/descriptor_flags.inc" +%include "asm/gdt_entry.inc" +%include "asm/unreal.asm" +%include "asm/memory_map.asm" +%include "asm/vesa.asm" +%include "asm/initialize.asm" diff --git a/kernel/asm/startup-i386.asm b/kernel/asm/startup-i386.asm index 6c4cb98ebc..f5cd6b5866 100644 --- a/kernel/asm/startup-i386.asm +++ b/kernel/asm/startup-i386.asm @@ -1,36 +1,20 @@ -startup: - ; a20 - in al, 0x92 - or al, 2 - out 0x92, al - - call memory_map - - call vesa - - call initialize.fpu - call initialize.sse - call initialize.pit - call initialize.pic - - ; load protected mode GDT and IDT - cli - lgdt [gdtr] - lidt [idtr] - ; set protected mode bit of cr0 - mov eax, cr0 - or eax, 1 - mov cr0, eax - - ; far jump to load CS with 32 bit segment - jmp gdt.kernel_code:protected_mode - -%include "asm/memory_map.asm" -%include "asm/vesa.asm" -%include "asm/initialize.asm" - +%include "asm/startup-common.asm" + +startup_arch: + ; load protected mode GDT and IDT + cli + lgdt [gdtr] + lidt [idtr] + ; set protected mode bit of cr0 + mov eax, cr0 + or eax, 1 + mov cr0, eax + + ; far jump to load CS with 32 bit segment + jmp gdt.kernel_code:protected_mode + +USE32 protected_mode: - use32 ; load all the other segments with 32 bit data segments mov eax, gdt.kernel_data @@ -46,9 +30,7 @@ protected_mode: ltr ax ;rust init - xor eax, eax - mov [0x100000], eax - mov eax, [kernel_file + 0x18] + mov eax, [kernel_base + 0x18] mov [interrupts.handler], eax mov eax, tss int 255 @@ -59,52 +41,61 @@ protected_mode: gdtr: dw gdt.end + 1 ; size - dd gdt ; offset + dd gdt ; offset gdt: .null equ $ - gdt dq 0 .kernel_code equ $ - gdt - dw 0xffff ; limit 0:15 - dw 0x0000 ; base 0:15 - db 0x00 ; base 16:23 - db 0b10011010 ; access byte - code - db 0xdf ; flags/(limit 16:19). flag is set to 32 bit protected mode - db 0x00 ; base 24:31 + istruc GDTEntry + at GDTEntry.limitl, dw 0xFFFF + at GDTEntry.basel, dw 0 + at GDTEntry.basem, db 0 + at GDTEntry.attribute, db attrib.present | attrib.user | attrib.code | attrib.readable + at GDTEntry.flags__limith, db 0xFF | flags.granularity | flags.default_operand_size + at GDTEntry.baseh, db 0 + iend .kernel_data equ $ - gdt - dw 0xffff ; limit 0:15 - dw 0x0000 ; base 0:15 - db 0x00 ; base 16:23 - db 0b10010010 ; access byte - data - db 0xdf ; flags/(limit 16:19). flag is set to 32 bit protected mode - db 0x00 ; base 24:31 + istruc GDTEntry + at GDTEntry.limitl, dw 0xFFFF + at GDTEntry.basel, dw 0 + at GDTEntry.basem, db 0 + at GDTEntry.attribute, db attrib.present | attrib.user | attrib.writable + at GDTEntry.flags__limith, db 0xFF | flags.granularity | flags.default_operand_size + at GDTEntry.baseh, db 0 + iend .user_code equ $ - gdt - dw 0xffff ; limit 0:15 - dw 0x0000 ; base 0:15 - db 0x00 ; base 16:23 - db 0b11111010 ; access byte - code - db 0xdf ; flags/(limit 16:19). flag is set to 32 bit protected mode - db 0x00 ; base 24:31 + istruc GDTEntry + at GDTEntry.limitl, dw 0xFFFF + at GDTEntry.basel, dw 0 + at GDTEntry.basem, db 0 + at GDTEntry.attribute, db attrib.present | attrib.ring3 | attrib.user | attrib.code | attrib.readable + at GDTEntry.flags__limith, db 0xFF | flags.granularity | flags.default_operand_size + at GDTEntry.baseh, db 0 + iend .user_data equ $ - gdt - dw 0xffff ; limit 0:15 - dw 0x0000 ; base 0:15 - db 0x00 ; base 16:23 - db 0b11110010 ; access byte - data - db 0xdf ; flags/(limit 16:19). flag is set to 32 bit protected mode - db 0x00 ; base 24:31 + istruc GDTEntry + at GDTEntry.limitl, dw 0xFFFF + at GDTEntry.basel, dw 0 + at GDTEntry.basem, db 0 + at GDTEntry.attribute, db attrib.present | attrib.ring3 | attrib.user | attrib.writable + at GDTEntry.flags__limith, db 0xFF | flags.granularity | flags.default_operand_size + at GDTEntry.baseh, db 0 + iend .tss equ $ - gdt - dw (tss.end-tss) & 0xFFFF ; limit 0:15 - dw (tss-$$+0x7C00) & 0xFFFF ; base 0:15 - db ((tss-$$+0x7C00) >> 16) & 0xFF ; base 16:23 - db 0b11101001 ; access byte - data - db 0x40 | ((tss.end-tss) >> 16) & 0xF ; flags/(limit 16:19). flag is set to 32 bit protected mode - db ((tss-$$+0x7C00) >> 24) & 0xFF ; base 24:31 - + istruc GDTEntry + at GDTEntry.limitl, dw (tss.end - tss) & 0xFFFF + at GDTEntry.basel, dw (tss-$$+0x7C00) & 0xFFFF + at GDTEntry.basem, db ((tss-$$+0x7C00) >> 16) & 0xFF + at GDTEntry.attribute, db attrib.present | attrib.ring3 | attrib.tssAvailabe32 + at GDTEntry.flags__limith, db ((tss.end - tss) >> 16) & 0xF + at GDTEntry.baseh, db ((tss-$$+0x7C00) >> 24) & 0xFF + iend .end equ $ - gdt struc TSS diff --git a/kernel/asm/startup-x86_64.asm b/kernel/asm/startup-x86_64.asm index 10d15a8c9d..73cbdfa18d 100644 --- a/kernel/asm/startup-x86_64.asm +++ b/kernel/asm/startup-x86_64.asm @@ -1,183 +1,178 @@ -startup: - ; a20 - in al, 0x92 - or al, 2 - out 0x92, al - - call memory_map - - call vesa - - call initialize.fpu - call initialize.sse - call initialize.pit - call initialize.pic - - cli - ; setting up Page Tables - ; Identity Mapping first 512GB - mov ax, 0x8000 - mov es, ax - - xor edi, edi - xor eax, eax - mov ecx, 3 * 4096 / 4 ;PML4, PDP, PD / moves 4 Bytes at once - cld - rep stosd - - xor edi, edi - ;Link first PML4 to PDP - mov DWORD [es:edi], 0x81000 | 1 << 1 | 1 - add edi, 0x1000 - ;Link first PDP to PD - mov DWORD [es:edi], 0x82000 | 1 << 1 | 1 - add edi, 0x1000 - ;Link all PD's (512 per PDP) to 1 GB of memory - mov ebx, 1 << 7 | 1 << 1 | 1 - mov ecx, 512 +%include "asm/startup-common.asm" + +startup_arch: + cli + ; setting up Page Tables + ; Identity Mapping first GB + mov ax, 0x7000 + mov es, ax + + xor edi, edi + xor eax, eax + mov ecx, 3 * 4096 / 4 ;PML4, PDP, PD / moves 4 Bytes at once + cld + rep stosd + + xor edi, edi + ;Link first PML4 to PDP + mov DWORD [es:edi], 0x71000 | 1 << 1 | 1 + add edi, 0x1000 + ;Link first PDP to PD + mov DWORD [es:edi], 0x72000 | 1 << 1 | 1 + add edi, 0x1000 + ;Link all PD's (512 per PDP, 2MB each)y + mov ebx, 1 << 7 | 1 << 1 | 1 + mov ecx, 512 .setpd: - mov [es:edi], ebx - add ebx, 0x200000 - add edi, 8 - loop .setpd + mov [es:edi], ebx + add ebx, 0x200000 + add edi, 8 + loop .setpd - xor ax, ax - mov es, ax + xor ax, ax + mov es, ax - ;cr3 holds pointer to PML4 - mov edi, 0x80000 - mov cr3, edi + ;cr3 holds pointer to PML4 + mov edi, 0x70000 + mov cr3, edi - ;enable Page Address Extension and Page Size Extension - mov eax, cr4 - or eax, 1 << 5 | 1 << 4 - mov cr4, eax + ;enable Page Address Extension and Page Size Extension + mov eax, cr4 + or eax, 1 << 5 | 1 << 4 + mov cr4, eax - ; load protected mode GDT and IDT - lgdt [gdtr] - lidt [idtr] + ; load protected mode GDT + lgdt [gdtr] - mov ecx, 0xC0000080 ; Read from the EFER MSR. - rdmsr - or eax, 0x00000100 ; Set the Long-Mode-Enable bit. - wrmsr + mov ecx, 0xC0000080 ; Read from the EFER MSR. + rdmsr + or eax, 0x00000100 ; Set the Long-Mode-Enable bit. + wrmsr - ;enabling paging and protection simultaneously - mov ebx, cr0 - or ebx, 0x80000001 ;Bit 31: Paging, Bit 0: Protected Mode - mov cr0, ebx + ;enabling paging and protection simultaneously + mov ebx, cr0 + or ebx, 0x80000001 ;Bit 31: Paging, Bit 0: Protected Mode + mov cr0, ebx - ; far jump to enable Long Mode and load CS with 32 bit segment - jmp 0x08:long_mode - -%include "asm/memory_map.asm" -%include "asm/vesa.asm" -%include "asm/initialize.asm" + ; far jump to enable Long Mode and load CS with 64 bit segment + jmp gdt.kernel_code:long_mode +USE64 long_mode: - use64 - - ; load all the other segments with 32 bit data segments - mov rax, 0x10 + ; load all the other segments with 64 bit data segments + mov rax, gdt.kernel_data mov ds, rax mov es, rax mov fs, rax mov gs, rax mov ss, rax + ; load long mode IDT + lidt [idtr] + mov rsp, 0x200000 - 128 mov rax, gdt.tss ltr ax ;rust init - xor rax, rax - mov [0x100000], rax - mov eax, [kernel_file + 0x18] + mov eax, [kernel_base + 0x18] mov [interrupts.handler], rax mov rax, tss - int 255 + int 0xFF .lp: sti hlt jmp .lp -gdtr: - dw gdt.end + 1 ; size - dq gdt ; offset - -gdt: -.null equ $ - gdt - dq 0 - -.kernel_code equ $ - gdt - dw 0xffff ; limit 0:15 - dw 0 ; base 0:15 - db 0 ; base 16:23 - db 0b10011010 ; access byte - code - db 0b10101111 ; flags/(limit 16:19) - db 0 ; base 24:31 - -.kernel_data equ $ - gdt - dw 0xffff ; limit 0:15 - dw 0 ; base 0:15 - db 0 ; base 16:23 - db 0b10010010 ; access byte - data - db 0b10101111 ; flags/(limit 16:19) - db 0 ; base 24:31 - -.user_code equ $ - gdt - dw 0xffff ; limit 0:15 - dw 0 ; base 0:15 - db 0 ; base 16:23 - db 0b11111010 ; access byte - code - db 0b10101111 ; flags/(limit 16:19) - db 0 ; base 24:31 - -.user_data equ $ - gdt - dw 0xffff ; limit 0:15 - dw 0 ; base 0:15 - db 0 ; base 16:23 - db 0b11110010 ; access byte - data - db 0b10101111 ; flags/(limit 16:19) - db 0 ; base 24:31 - -.tss equ $ - gdt - dw (tss.end-tss) & 0xFFFF ; limit 0:15 - dw (tss-$$+0x7C00) & 0xFFFF ; base 0:15 - db ((tss-$$+0x7C00) >> 16) & 0xFF ; base 16:23 - db 0b11101001 ; access byte - data - db 0b01100000 | ((tss.end-tss) >> 16) & 0xF ; flags/(limit 16:19). flag is set to 32 bit protected mode - db ((tss-$$+0x7C00) >> 24) & 0xFF ; base 24:31 - dq 0 - -.end equ $ - gdt - -struc TSS - .reserved1 resd 1 ;The previous TSS - if we used hardware task switching this would form a linked list. - .rsp0 resq 1 ;The stack pointer to load when we change to kernel mode. - .rsp1 resq 1 ;everything below here is unusued now.. - .rsp2 resq 1 - .reserved2 resd 1 - .reserved3 resd 1 - .ist1 resq 1 - .ist2 resq 1 - .ist3 resq 1 - .ist4 resq 1 - .ist5 resq 1 - .ist6 resq 1 - .ist7 resq 1 - .reserved4 resd 1 - .reserved5 resd 1 - .reserved6 resw 1 - .iomap_base resw 1 -endstruc - -tss: - istruc TSS - at TSS.rsp0, dd 0x200000 - 128 - at TSS.iomap_base, dw 0xFFFF + gdtr: + dw gdt.end + 1 ; size + dq gdt ; offset + + gdt: + .null equ $ - gdt + dq 0 + + .kernel_code equ $ - gdt + istruc GDTEntry + at GDTEntry.limitl, dw 0 + at GDTEntry.basel, dw 0 + at GDTEntry.basem, db 0 + at GDTEntry.attribute, db attrib.present | attrib.user | attrib.code + at GDTEntry.flags__limith, db flags.long_mode + at GDTEntry.baseh, db 0 + iend + + .kernel_data equ $ - gdt + istruc GDTEntry + at GDTEntry.limitl, dw 0 + at GDTEntry.basel, dw 0 + at GDTEntry.basem, db 0 + ; AMD System Programming Manual states that the writeable bit is ignored in long mode, but ss can not be set to this descriptor without it + at GDTEntry.attribute, db attrib.present | attrib.user | attrib.writable + at GDTEntry.flags__limith, db 0 + at GDTEntry.baseh, db 0 iend -.end: -%include "asm/interrupts-x86_64.asm" + .user_code equ $ - gdt + istruc GDTEntry + at GDTEntry.limitl, dw 0 + at GDTEntry.basel, dw 0 + at GDTEntry.basem, db 0 + at GDTEntry.attribute, db attrib.present | attrib.ring3 | attrib.user | attrib.code + at GDTEntry.flags__limith, db flags.long_mode + at GDTEntry.baseh, db 0 + iend + + .user_data equ $ - gdt + istruc GDTEntry + at GDTEntry.limitl, dw 0 + at GDTEntry.basel, dw 0 + at GDTEntry.basem, db 0 + ; AMD System Programming Manual states that the writeable bit is ignored in long mode, but ss can not be set to this descriptor without it + at GDTEntry.attribute, db attrib.present | attrib.ring3 | attrib.user | attrib.writable + at GDTEntry.flags__limith, db 0 + at GDTEntry.baseh, db 0 + iend + + .tss equ $ - gdt + istruc GDTEntry + at GDTEntry.limitl, dw (tss.end - tss) & 0xFFFF + at GDTEntry.basel, dw (tss-$$+0x7C00) & 0xFFFF + at GDTEntry.basem, db ((tss-$$+0x7C00) >> 16) & 0xFF + at GDTEntry.attribute, db attrib.present | attrib.ring3 | attrib.tssAvailabe64 + at GDTEntry.flags__limith, db ((tss.end - tss) >> 16) & 0xF + at GDTEntry.baseh, db ((tss-$$+0x7C00) >> 24) & 0xFF + iend + dq 0 ;tss descriptors are extended to 16 Bytes + + .end equ $ - gdt + + struc TSS + .reserved1 resd 1 ;The previous TSS - if we used hardware task switching this would form a linked list. + .rsp0 resq 1 ;The stack pointer to load when we change to kernel mode. + .rsp1 resq 1 ;everything below here is unusued now.. + .rsp2 resq 1 + .reserved2 resd 1 + .reserved3 resd 1 + .ist1 resq 1 + .ist2 resq 1 + .ist3 resq 1 + .ist4 resq 1 + .ist5 resq 1 + .ist6 resq 1 + .ist7 resq 1 + .reserved4 resd 1 + .reserved5 resd 1 + .reserved6 resw 1 + .iomap_base resw 1 + endstruc + + tss: + istruc TSS + at TSS.rsp0, dd 0x200000 - 128 + at TSS.iomap_base, dw 0xFFFF + iend + .end: + + %include "asm/interrupts-x86_64.asm" diff --git a/kernel/asm/unreal.asm b/kernel/asm/unreal.asm new file mode 100644 index 0000000000..691a8920f0 --- /dev/null +++ b/kernel/asm/unreal.asm @@ -0,0 +1,54 @@ +SECTION .text +USE16 + +; switch to unreal mode; ds and es can address up to 4GiB +unreal: + cli + + lgdt [unreal_gdtr] + + push es + push ds + + mov eax, cr0 ; switch to pmode by + or al,1 ; set pmode bit + mov cr0, eax + + jmp $+2 + +; http://wiki.osdev.org/Babystep7 +; When this register given a "selector", a "segment descriptor cache register" +; is filled with the descriptor values, including the size (or limit). After +; the switch back to real mode, these values are not modified, regardless of +; what value is in the 16-bit segment register. So the 64k limit is no longer +; valid and 32-bit offsets can be used with the real-mode addressing rules + mov bx, unreal_gdt.data + mov es, bx + mov ds, bx + + and al,0xFE ; back to realmode + mov cr0, eax ; by toggling bit again + + pop ds + pop es + sti + ret + + +unreal_gdtr: + dw unreal_gdt.end + 1 ; size + dd unreal_gdt ; offset + +unreal_gdt: +.null equ $ - unreal_gdt + dq 0 +.data equ $ - unreal_gdt + istruc GDTEntry + at GDTEntry.limitl, dw 0xFFFF + at GDTEntry.basel, dw 0x0 + at GDTEntry.basem, db 0x0 + at GDTEntry.attribute, db attrib.present | attrib.user | attrib.writable + at GDTEntry.flags__limith, db 0xFF | flags.granularity | flags.default_operand_size + at GDTEntry.baseh, db 0x0 + iend +.end equ $ - unreal_gdt diff --git a/kernel/asm/vesa.asm b/kernel/asm/vesa.asm index d8521d0f3c..e8daf05ca1 100644 --- a/kernel/asm/vesa.asm +++ b/kernel/asm/vesa.asm @@ -1,194 +1,194 @@ %include "asm/vesa.inc" -[section .text] -[BITS 16] +SECTION .text +USE16 vesa: .getcardinfo: - mov ax, 0x4F00 - mov di, VBECardInfo - int 0x10 - cmp ax, 0x4F - je .edid - mov eax, 1 - ret + mov ax, 0x4F00 + mov di, VBECardInfo + int 0x10 + cmp ax, 0x4F + je .edid + mov eax, 1 + ret .edid: - cmp dword [.required], 0 ;if both required x and required y are set, forget this - jne near .findmode - mov ax, 0x4F15 - mov bx, 1 - xor cx, cx - xor dx, dx - mov di, VBEEDID - int 0x10 - cmp ax, 0x4F - jne near .noedid - xor di, di + cmp dword [.required], 0 ;if both required x and required y are set, forget this + jne near .findmode + mov ax, 0x4F15 + mov bx, 1 + xor cx, cx + xor dx, dx + mov di, VBEEDID + int 0x10 + cmp ax, 0x4F + jne near .noedid + xor di, di .lp: - xor cx, cx - mov cl, [di+VBEEDID.standardtiming] - shl cx, 3 - add cx, 248 - push ecx - call decshowrm - mov al, 'x' - call charrm - pop ecx - mov bx, cx - inc di - mov al, [di+VBEEDID.standardtiming] - and al, 11000000b - cmp al, VBEEDID.aspect.4.3 - jne .not43 - mov ax, 3 - mul cx - mov cx, ax - shr cx, 2 - jmp .gotres + xor cx, cx + mov cl, [di+VBEEDID.standardtiming] + shl cx, 3 + add cx, 248 + push ecx + call decshowrm + mov al, 'x' + call charrm + pop ecx + mov bx, cx + inc di + mov al, [di+VBEEDID.standardtiming] + and al, 11000000b + cmp al, VBEEDID.aspect.4.3 + jne .not43 + mov ax, 3 + mul cx + mov cx, ax + shr cx, 2 + jmp .gotres .not43: - cmp al, VBEEDID.aspect.5.4 - jne .not54 - shl cx, 2 - mov ax, cx - mov cx, 5 - xor dx, dx - div cx - mov cx, ax - jmp .gotres + cmp al, VBEEDID.aspect.5.4 + jne .not54 + shl cx, 2 + mov ax, cx + mov cx, 5 + xor dx, dx + div cx + mov cx, ax + jmp .gotres .not54: - cmp al, VBEEDID.aspect.16.10 - jne .not1610 - mov ax, 10 - mul cx - mov cx, ax - shr cx, 4 - jmp .gotres + cmp al, VBEEDID.aspect.16.10 + jne .not1610 + mov ax, 10 + mul cx + mov cx, ax + shr cx, 4 + jmp .gotres .not1610: - mov ax, 9 - mul cx - mov cx, ax - shr cx, 4 + mov ax, 9 + mul cx + mov cx, ax + shr cx, 4 .gotres: - call decshowrm - mov si, .edidmsg - call printrm - inc di - cmp di, 8 - jb .lp - jmp .findmode + call decshowrm + mov si, .edidmsg + call printrm + inc di + cmp di, 8 + jb .lp + jmp .findmode .noedid: - mov si, .noedidmsg - call printrm - jmp .findmode + mov si, .noedidmsg + call printrm + jmp .findmode .resetlist: - ;if needed, reset mins/maxes/stuff - xor cx, cx - mov [.minx], cx - mov [.miny], cx - mov [.requiredx], cx - mov [.requiredy], cx - mov [.requiredmode], cx + ;if needed, reset mins/maxes/stuff + xor cx, cx + mov [.minx], cx + mov [.miny], cx + mov [.requiredx], cx + mov [.requiredy], cx + mov [.requiredmode], cx .findmode: - mov si, [VBECardInfo.videomodeptr] - mov ax, [VBECardInfo.videomodeptr+2] - mov fs, ax - sub si, 2 - mov cx, [.requiredmode] - test cx, cx - jnz .getmodeinfo + mov si, [VBECardInfo.videomodeptr] + mov ax, [VBECardInfo.videomodeptr+2] + mov fs, ax + sub si, 2 + mov cx, [.requiredmode] + test cx, cx + jnz .getmodeinfo .searchmodes: - add si, 2 - mov cx, [fs:si] - cmp cx, 0xFFFF - jne .getmodeinfo - cmp word [.goodmode], 0 - je .resetlist - jmp .findmode + add si, 2 + mov cx, [fs:si] + cmp cx, 0xFFFF + jne .getmodeinfo + cmp word [.goodmode], 0 + je .resetlist + jmp .findmode .getmodeinfo: - push esi - mov [.currentmode], cx - mov ax, 0x4F01 - mov di, VBEModeInfo - int 0x10 - pop esi - cmp ax, 0x4F - je .foundmode - mov eax, 1 - ret + push esi + mov [.currentmode], cx + mov ax, 0x4F01 + mov di, VBEModeInfo + int 0x10 + pop esi + cmp ax, 0x4F + je .foundmode + mov eax, 1 + ret .foundmode: - ;check minimum values, really not minimums from an OS perspective but ugly for users - cmp byte [VBEModeInfo.bitsperpixel], 32 - jb .searchmodes + ;check minimum values, really not minimums from an OS perspective but ugly for users + cmp byte [VBEModeInfo.bitsperpixel], 32 + jb .searchmodes .testx: - mov cx, [VBEModeInfo.xresolution] - cmp word [.requiredx], 0 - je .notrequiredx - cmp cx, [.requiredx] - je .testy - jmp .searchmodes + mov cx, [VBEModeInfo.xresolution] + cmp word [.requiredx], 0 + je .notrequiredx + cmp cx, [.requiredx] + je .testy + jmp .searchmodes .notrequiredx: - cmp cx, [.minx] - jb .searchmodes + cmp cx, [.minx] + jb .searchmodes .testy: - mov cx, [VBEModeInfo.yresolution] - cmp word [.requiredy], 0 - je .notrequiredy - cmp cx, [.requiredy] - jne .searchmodes ;as if there weren't enough warnings, USE WITH CAUTION - cmp word [.requiredx], 0 - jnz .setmode - jmp .testgood + mov cx, [VBEModeInfo.yresolution] + cmp word [.requiredy], 0 + je .notrequiredy + cmp cx, [.requiredy] + jne .searchmodes ;as if there weren't enough warnings, USE WITH CAUTION + cmp word [.requiredx], 0 + jnz .setmode + jmp .testgood .notrequiredy: - cmp cx, [.miny] - jb .searchmodes + cmp cx, [.miny] + jb .searchmodes .testgood: - mov cx, [.currentmode] - mov [.goodmode], cx - push esi - call decshowrm - mov al, ':' - call charrm - mov cx, [VBEModeInfo.xresolution] - call decshowrm - mov al, 'x' - call charrm - mov cx, [VBEModeInfo.yresolution] - call decshowrm - mov al, '@' - call charrm - xor ch, ch - mov cl, [VBEModeInfo.bitsperpixel] - call decshowrm - mov si, .modeok - call printrm - xor ax, ax - int 0x16 - pop esi - cmp al, 'y' - jne .searchmodes + mov cx, [.currentmode] + mov [.goodmode], cx + push esi + call decshowrm + mov al, ':' + call charrm + mov cx, [VBEModeInfo.xresolution] + call decshowrm + mov al, 'x' + call charrm + mov cx, [VBEModeInfo.yresolution] + call decshowrm + mov al, '@' + call charrm + xor ch, ch + mov cl, [VBEModeInfo.bitsperpixel] + call decshowrm + mov si, .modeok + call printrm + xor ax, ax + int 0x16 + pop esi + cmp al, 'y' + jne .searchmodes .setmode: - mov bx, [.currentmode] - cmp bx, 0 - je .nomode - or bx, 0x4000 - mov ax, 0x4F02 - int 0x10 + mov bx, [.currentmode] + cmp bx, 0 + je .nomode + or bx, 0x4000 + mov ax, 0x4F02 + int 0x10 .nomode: - cmp ax, 0x4F - je .returngood - mov eax, 1 - ret + cmp ax, 0x4F + je .returngood + mov eax, 1 + ret .returngood: - xor eax, eax - ret + xor eax, eax + ret .minx dw 640 .miny dw 480 .required: -.requiredx dw 800 ;USE THESE WITH CAUTION +.requiredx dw 800 ;USE THESE WITH CAUTION .requiredy dw 600 .requiredmode dw 0 .noedidmsg db "EDID not supported.",10,13,0 -.edidmsg db " is supported.",10,13,0 +.edidmsg db " is supported.",10,13,0 .modeok db 10,13,"Is this OK?(y/n)",10,13,0 .goodmode dw 0 @@ -196,107 +196,107 @@ vesa: ;useful functions decshowrm: - mov si, .number + mov si, .number .clear: - mov al, "0" - mov [si], al - inc si - cmp si, .numberend - jb .clear - dec si - call convertrm - mov si, .number + mov al, "0" + mov [si], al + inc si + cmp si, .numberend + jb .clear + dec si + call convertrm + mov si, .number .lp: - lodsb - cmp si, .numberend - jae .end - cmp al, "0" - jbe .lp + lodsb + cmp si, .numberend + jae .end + cmp al, "0" + jbe .lp .end: - dec si - call printrm - ret + dec si + call printrm + ret .number times 7 db 0 .numberend db 0 convertrm: - dec si - mov bx, si ;place to convert into must be in si, number to convert must be in cx + dec si + mov bx, si ;place to convert into must be in si, number to convert must be in cx .cnvrt: - mov si, bx - sub si, 4 -.ten4: inc si - cmp cx, 10000 - jb .ten3 - sub cx, 10000 - inc byte [si] - jmp .cnvrt -.ten3: inc si - cmp cx, 1000 - jb .ten2 - sub cx, 1000 - inc byte [si] - jmp .cnvrt -.ten2: inc si - cmp cx, 100 - jb .ten1 - sub cx, 100 - inc byte [si] - jmp .cnvrt -.ten1: inc si - cmp cx, 10 - jb .ten0 - sub cx, 10 - inc byte [si] - jmp .cnvrt -.ten0: inc si - cmp cx, 1 - jb .return - sub cx, 1 - inc byte [si] - jmp .cnvrt + mov si, bx + sub si, 4 +.ten4: inc si + cmp cx, 10000 + jb .ten3 + sub cx, 10000 + inc byte [si] + jmp .cnvrt +.ten3: inc si + cmp cx, 1000 + jb .ten2 + sub cx, 1000 + inc byte [si] + jmp .cnvrt +.ten2: inc si + cmp cx, 100 + jb .ten1 + sub cx, 100 + inc byte [si] + jmp .cnvrt +.ten1: inc si + cmp cx, 10 + jb .ten0 + sub cx, 10 + inc byte [si] + jmp .cnvrt +.ten0: inc si + cmp cx, 1 + jb .return + sub cx, 1 + inc byte [si] + jmp .cnvrt .return: - ret + ret printrm: - mov al, [si] - test al, al - jz .return - call charrm - inc si - jmp printrm + mov al, [si] + test al, al + jz .return + call charrm + inc si + jmp printrm .return: - ret + ret -charrm: ;char must be in al - mov bx, 7 - mov ah, 0xE - int 10h - ret +charrm: ;char must be in al + mov bx, 7 + mov ah, 0xE + int 10h + ret -; .bestmode: ;preference is width > height > color - ; mov bx, [VBEModeInfo.xresolution] - ; cmp bx, [.width] - ; ja .switchmode - ; jb .searchmodes - ; mov bx, [VBEModeInfo.yresolution] - ; cmp bx, [.height] - ; ja .switchmode - ; jb .searchmodes - ; mov bl, [VBEModeInfo.bitsperpixel] - ; cmp bl, [.color] - ; jb .searchmodes +; .bestmode: ;preference is width > height > color + ; mov bx, [VBEModeInfo.xresolution] + ; cmp bx, [.width] + ; ja .switchmode + ; jb .searchmodes + ; mov bx, [VBEModeInfo.yresolution] + ; cmp bx, [.height] + ; ja .switchmode + ; jb .searchmodes + ; mov bl, [VBEModeInfo.bitsperpixel] + ; cmp bl, [.color] + ; jb .searchmodes ; .switchmode: - ; mov cx, [.currentmode] - ; mov [.mode], cx - ; mov bx, [VBEModeInfo.xresolution] - ; mov [.width], bx - ; mov bx, [VBEModeInfo.yresolution] - ; mov [.height], bx - ; mov bl, [VBEModeInfo.bitsperpixel] - ; mov [.color], bl - ; jmp .searchmodes + ; mov cx, [.currentmode] + ; mov [.mode], cx + ; mov bx, [VBEModeInfo.xresolution] + ; mov [.width], bx + ; mov bx, [VBEModeInfo.yresolution] + ; mov [.height], bx + ; mov bl, [VBEModeInfo.bitsperpixel] + ; mov [.color], bl + ; jmp .searchmodes ; .mode dw 0 ; .color db 0 diff --git a/kernel/harddrive.asm b/kernel/harddrive.asm index 70f94b03cf..a9f9ad248f 100644 --- a/kernel/harddrive.asm +++ b/kernel/harddrive.asm @@ -1,4 +1,4 @@ -%include "asm/sector.asm" +%include "asm/bootsector.asm" fs_header: .signature: @@ -6,12 +6,12 @@ fs_header: .version: dq 1 .free_space: - dq (fs_free_space - boot)/512 + dq (fs_free_space - boot) / 512 dq (fs_free_space.end - fs_free_space) .padding: align 256, db 0 .extents: - dq (fs_root_node_list - boot)/512 + dq (fs_root_node_list - boot) / 512 dq (fs_root_node_list.end - fs_root_node_list) align 512, db 0 @@ -24,13 +24,17 @@ fs_header: %ifdef ARCH_x86_64 %include "asm/startup-x86_64.asm" %endif +align 512, db 0 +startup_end: -times (0xC000-0x1000)-0x7C00-($-$$) db 0 +;times (0xC000-0x1000)-0x7C00-($-$$) db 0 kernel_file: incbin "kernel.bin" align 512, db 0 .end: +.length equ kernel_file.end - kernel_file +.length_sectors equ .length / 512 fs_root_node_list: %macro file 2+ @@ -41,7 +45,7 @@ fs_root_node_list: align 256, db 0 .extents: - dq (fs_data.%1 - boot)/512 + dq (fs_data.%1 - boot) / 512 dq (fs_data.%1.end - fs_data.%1) align 512, db 0 diff --git a/kernel/kernel.ld b/kernel/kernel.ld index 8c6c00a6cb..31473e49fd 100644 --- a/kernel/kernel.ld +++ b/kernel/kernel.ld @@ -1,24 +1,25 @@ ENTRY(kernel) SECTIONS { - . = 0xC000; + kernel_base = 0x101000; + . = kernel_base; - .text : AT(ADDR(.text) - 0xC000) { + .text : AT(ADDR(.text) - kernel_base) { *(.text*) . = ALIGN(4096); } - .rodata : AT(ADDR(.rodata) - 0xC000) { + .rodata : AT(ADDR(.rodata) - kernel_base) { *(.rodata*) . = ALIGN(4096); } - .data : AT(ADDR(.data) - 0xC000) { + .data : AT(ADDR(.data) - kernel_base) { *(.data*) . = ALIGN(4096); } - .bss : AT(ADDR(.bss) - 0xC000) { + .bss : AT(ADDR(.bss) - kernel_base) { __bss_start = .; *(.bss*) . = ALIGN(4096);