diff --git a/Makefile b/Makefile index 5635782..d0bec82 100644 --- a/Makefile +++ b/Makefile @@ -84,6 +84,14 @@ make_disk: @echo ${CL2}[make_disk]${CL} OK${CL3} testloader: loader + @qemu-system-x86_64 -hda build/bin/disk.img -d cpu_reset,guest_errors,pcall,int -enable-kvm 2> qemu.log & + @ndisasm $(OBJDIR)/boot/loader.bin -b 32 > loader_dism.asm + +testloader32: loader + @qemu-system-i386 -hda build/bin/disk.img -d cpu_reset,guest_errors,pcall,int -enable-kvm 2> qemu.log & + @ndisasm $(OBJDIR)/boot/loader.bin -b 32 > loader_dism.asm + +debugloader: loader @qemu-system-x86_64 -hda build/bin/disk.img -d cpu_reset,guest_errors,pcall,int -s -S -enable-kvm 2> qemu.log & @ndisasm $(OBJDIR)/boot/loader.bin -b 32 > loader_dism.asm diff --git a/boot/loader/cpu/cpu.asm b/boot/loader/cpu/cpu.asm deleted file mode 100644 index b875758..0000000 --- a/boot/loader/cpu/cpu.asm +++ /dev/null @@ -1,46 +0,0 @@ -;=----------------------------------------------------------------------------=; -; GNU GPL OS/K ; -; ; -; Desc: Basic longmode CPU functions ; -; (x86_64 architecture only) ; -; ; -; ; -; Copyright © 2018-2019 The OS/K Team ; -; ; -; This file is part of OS/K. ; -; ; -; OS/K is free software: you can redistribute it and/or modify ; -; it under the terms of the GNU General Public License as published by ; -; the Free Software Foundation, either version 3 of the License, or ; -; (at your option) any later version. ; -; ; -; OS/K is distributed in the hope that it will be useful, ; -; but WITHOUT ANY WARRANTY; without even the implied warranty of ; -; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; -; GNU General Public License for more details. ; -; ; -; You should have received a copy of the GNU General Public License ; -; along with OS/K. If not, see . ; -;=----------------------------------------------------------------------------=; - -[BITS 64] - -temporize: - push rcx - mov rcx, 2000 -.looping: - nop - nop - nop - loop .looping - pop rcx - ret - -bitemporize: - push rcx - mov rcx, 2000 -.looping: - call temporize - loop .looping - pop rcx - ret diff --git a/boot/loader/cpu/cpuid.inc b/boot/loader/cpu/cpuid.inc index 44e19e7..7dabd42 100644 --- a/boot/loader/cpu/cpuid.inc +++ b/boot/loader/cpu/cpuid.inc @@ -44,7 +44,7 @@ Is64Bits: jz .no_64 ; If it's not set, there is no long mode ret .no_64: - mov al, "2" ; ERROR 1 : 64bits unsupported + mov ax, "01" ; ERROR 01 : 64bits unsupported jmp Error ; ---------------------------------------------------------------------------- ; @@ -66,5 +66,5 @@ Check_cpuid: je .no_cpuid ret .no_cpuid: - mov al, "1" ; ERROR 1 : CPUID UNSUPPORTED + mov ax, "02" ; ERROR 02 : CPUID UNSUPPORTED jmp Error diff --git a/boot/loader/io/ata.asm b/boot/loader/io/ata.asm deleted file mode 100644 index c37cfc6..0000000 --- a/boot/loader/io/ata.asm +++ /dev/null @@ -1,159 +0,0 @@ -;=----------------------------------------------------------------------------=; -; GNU GPL OS/K ; -; ; -; Desc: Basic Read Only ATA Long mode Driver ; -; (x86_64 architecture only) ; -; ; -; ; -; Copyright © 2018-2019 The OS/K Team ; -; ; -; This file is part of OS/K. ; -; ; -; OS/K is free software: you can redistribute it and/or modify ; -; it under the terms of the GNU General Public License as published by ; -; the Free Software Foundation, either version 3 of the License, or ; -; (at your option) any later version. ; -; ; -; OS/K is distributed in the hope that it will be useful, ; -; but WITHOUT ANY WARRANTY; without even the implied warranty of ; -; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; -; GNU General Public License for more details. ; -; ; -; You should have received a copy of the GNU General Public License ; -; along with OS/K. If not, see . ; -;=----------------------------------------------------------------------------=; - -[BITS 64] - -;; BPB -%define OEMName bp+0x03 ; Disk label -%define bytesPerSector bp+0x0b ; Bytes per sector -%define sectorsPerCluster bp+0x0d ; Sectors per cluster -%define reservedSectors bp+0x0e ; Reserved sectors -%define fats bp+0x10 ; Number of fats -%define rootDirEntries bp+0x11 ; Number of entries in root dir -%define sectors bp+0x13 ; Logical sectors -%define mediaType bp+0x15 ; Media descriptor byte -%define fatSectors bp+0x16 ; Sectors per FAT -%define sectorsPerTrack bp+0x18 ; Sectors per track -%define heads bp+0x1a ; Number of sides/heads -%define hiddenSectors bp+0x1c ; Hidden sectors -%define hugeSectors bp+0x20 ; LBA sectors -%define biosBootdrvNum bp+0x24 ; Bootdrv number -%define reserved bp+0x25 ; This is not used -%define bootSignature bp+0x26 ; Bootdrv signature -%define volumeId bp+0x27 ; Volume ID -%define volumeLabel bp+0x2b ; Volume Label -%define fatTypeLabel bp+0x36 ; File system type - -;; GLOBAL DATA - -Bootdrv db 0 -ended db "[End of Sector]", 0x0A, 0x0A, 0x0D, 0x0 -buffer: times 513 db "_" - -;; TEXT - -ata_read: -;-----------------------------------------------------------------------; -; x64/LM ATA Reading function ; -; bl : number of sectors to read XXX ; -; bh : the first sector to read ; -;-----------------------------------------------------------------------; - -; Technical infos about the ports (Intel Doc): -; -; Port Access Mode Misc -; -; 1f0 r/w Data register, the bytes of the disk itself -; 1f1 r Error register that can be handled -; 1f2 r/w Sector count, how many sectors to read -; 1f3 r/w Sector number, the actual sector wanted -; 1f4 r/w Cylinder low, cylinders is 0-1024 -; 1f5 r/w Cylinder high, this makes up the rest of the 1024 -; 1f6 r/w Drive/head -; bit 7 = 1 -; bit 6 = 0 -; bit 5 = 1 -; bit 4 = 0 drive 0 select -; = 1 drive 1 select -; bit 3-0 head select bits -; 1f7 r Status register -; bit 7 = 1 controller is executing a command -; bit 6 = 1 drive is ready -; bit 5 = 1 write fault -; bit 4 = 1 seek complete -; bit 3 = 1 sector buffer requires servicing -; bit 2 = 1 disk data read corrected -; bit 1 = 1 index - set to 1 each revolution -; bit 0 = 1 previous command ended in an error -; 1f7 w Command register -; commands: -; 50h format track -; 20h read sectors with retry -; 21h read sectors without retry -; 22h read long with retry -; 23h read long without retry -; 30h write sectors with retry -; 31h write sectors without retry -; 32h write long with retry -; 33h write long without retry -; - push rax - push rbx - push rcx - push rdx - push rdi - mov dx, 0x1f6 ; Drive and head port - mov al, 0x0a0 ; Drive 0, head 0 - out dx,al - - mov dx, 0x1f2 ; Sector count port - mov al, bl ; Read bl(s) sector - out dx, al - - mov dx, 0x1f3 ; Sector number port - mov al, bh ; Read from sector n°bh - out dx, al - - mov dx, 0x1f4 ; Cylinder low port - mov al, 0 ; Cylinder 0 - out dx, al - - mov dx, 0x1f5 ; Cylinder high port - mov al, 0 ; The rest of the cylinder 0 - out dx, al - - mov dx, 0x1f7 ; Command port - mov al, 0x20 ; Read with retry. - out dx, al -still_going: - in al, dx - test al, 8 ; This means the sector buffer requires - ;servicing. - jz still_going ; Don't continue until the sector buffer - ;is ready. - - mov cx, 512/2 ; One sector /2 because it copies words - mov rdi, QWORD buffer - mov dx, 0x1f0 ; Data port - data comes in and out of here. - rep insw - pop rdi -%ifdef DEBUG - mov bl, 0x0F - mov esi, buffer - call dump - mov bl, 0x0A - mov esi, ended - call write - add qword [NextTRAM], 120 ; Cursor moving : 1120 = 80 * 2 * 7 lignes -%else - mov bl, 0x0A - mov esi, Pass - call write -%endif - pop rdx - pop rcx - pop rbx - pop rax - ret diff --git a/boot/loader/io/lmmem.asm b/boot/loader/io/lmmem.asm deleted file mode 100644 index e77e4c2..0000000 --- a/boot/loader/io/lmmem.asm +++ /dev/null @@ -1,43 +0,0 @@ -;=----------------------------------------------------------------------------=; -; GNU GPL OS/K ; -; ; -; Desc: Basic Memory Long mode Functions ; -; (x86_64 architecture only) ; -; ; -; ; -; Copyright © 2018-2019 The OS/K Team ; -; ; -; This file is part of OS/K. ; -; ; -; OS/K is free software: you can redistribute it and/or modify ; -; it under the terms of the GNU General Public License as published by ; -; the Free Software Foundation, either version 3 of the License, or ; -; (at your option) any later version. ; -; ; -; OS/K is distributed in the hope that it will be useful, ; -; but WITHOUT ANY WARRANTY; without even the implied warranty of ; -; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; -; GNU General Public License for more details. ; -; ; -; You should have received a copy of the GNU General Public License ; -; along with OS/K. If not, see . ; -;=----------------------------------------------------------------------------=; -[BITS 64] - -;; GLOBAL DATA -A20_OK db 0 - -;; TEXT - -check_a20: - cmp BYTE [A20_OK], 1 - je .A20Success - mov bl, 0x0C - mov esi, Fail - call write - jmp Die -.A20Success: - mov bl, 0x0A - mov esi, Pass - call write - ret diff --git a/boot/loader/io/lmterm.asm b/boot/loader/io/lmterm.asm deleted file mode 100644 index c5805d8..0000000 --- a/boot/loader/io/lmterm.asm +++ /dev/null @@ -1,131 +0,0 @@ -;=----------------------------------------------------------------------------=; -; GNU GPL OS/K ; -; ; -; Desc: Basic Colored VGA Terminal Long mode Driver ; -; (x86_64 architecture only) ; -; ; -; ; -; Copyright © 2018-2019 The OS/K Team ; -; ; -; This file is part of OS/K. ; -; ; -; OS/K is free software: you can redistribute it and/or modify ; -; it under the terms of the GNU General Public License as published by ; -; the Free Software Foundation, either version 3 of the License, or ; -; (at your option) any later version. ; -; ; -; OS/K is distributed in the hope that it will be useful, ; -; but WITHOUT ANY WARRANTY; without even the implied warranty of ; -; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; -; GNU General Public License for more details. ; -; ; -; You should have received a copy of the GNU General Public License ; -; along with OS/K. If not, see . ; -;=----------------------------------------------------------------------------=; - - -;;VIDEO -%define TRAM 0x0B8000 ; [T]ext[RAM] -%define VRAM 0x0A0000 ; [V]ideo[RAM] - -;; GLOBAL DATA - -VGA_HEIGHT dq 0 -VIDEO_MODE dw 0 -VIDEO_MODE32 dw 0 -VGA_HEIGHT32 dw 0 -NextTRAM dq 0x0B8000 ; Last position of cursor -VIDEO_MODE64 dq 0 -VGA_HEIGHT64 dq 0 -VGA_X dq 0 - -;; TEXT - -[BITS 64] - -clear: -;-----------------------------------------------------------------------; -; x64/LM Clear Text Screen Function ; -;-----------------------------------------------------------------------; - mov qword [NextTRAM], TRAM - mov edi, TRAM - push rsi - push rdi - push rcx - mov ah, 0 - mov al, 0 - mov rcx, 0x4000 ; traditionnal value - rep stosw ; fill screen with al while cx > 0 - pop rcx - pop rsi - pop rdi - ret - -write: -;-----------------------------------------------------------------------; -; x64/LM Text Printing Functions ; -; bl : color code ; -; esi : string address ; -;-----------------------------------------------------------------------; - mov edi, [NextTRAM] ; TRAM ADDRESS - push rsi - push rdi -.pLoop: - lodsb - cmp al, 0 ; while @al, i.e. while we're not hitting '\0' - je .pEnd - cmp al, 0x0A ; LF - je .lf - cmp al, 0x0D ; CR - je .cr - stosb ; text subpixel - mov al, bl - stosb ; color subpixel - add qword [NextTRAM], 0x2 ; Cursor moving - add qword [VGA_X], 0x2 ; coord + 2 because 2 subpixels - jmp .pLoop -.pEnd: - pop rdi - pop rsi - ret -.lf: - mov rax, [VGA_HEIGHT64] - add [NextTRAM], rax ; Cursor moving - add [NextTRAM], rax - add edi, eax ; Address moving - add edi, eax - jmp .pLoop -.cr: - push rax - mov rax, qword [VGA_X] - sub qword [NextTRAM], rax ; pos = X + Y * VGA_HEIGHT64. Donc pos - X = début de ligne - sub edi, edx - mov qword [VGA_X], 0 - pop rax - jmp .pLoop -.scroll: - ; XXX I don't think I'll implement this, but never know...; - jmp .pLoop - -dump: -;-----------------------------------------------------------------------; -; x64/LM Dump 512 bytes of a buffer ; -; bl : color code ; -; esi : buffer address ; -;-----------------------------------------------------------------------; - mov edi, [NextTRAM] ; TRAM ADDRESS - push rsi - push rdi - push rcx - mov rcx, 512 -.pLoop: - lodsb - stosb ; text subpixel - mov al, bl - stosb ; color subpixel - loop .pLoop - pop rcx - pop rdi - pop rsi - add qword [NextTRAM], 1000 ; Cursor moving : 1120 = 80 * 2 * 7 lignes - ret diff --git a/boot/loader/loader.asm b/boot/loader/loader.asm index 2040668..d421bd0 100644 --- a/boot/loader/loader.asm +++ b/boot/loader/loader.asm @@ -31,7 +31,7 @@ %include "boot/loader/multiboot/header.inc" -;; Normal entry point, but a little bit unused since we never use it because... +;; NORMAL ENTRY POINT, BUT A LITTLE BIT UNUSED SINCE WE NEVER USE IT BECAUSE... _start: mov ax, cs ; correcting cs after the horrible far jump mov ds, ax ; hm... And ds too @@ -40,7 +40,7 @@ _start: xor dl, dl jmp 0x0000:_loader ; pas sûr -;; Magnificent multiboot header for GRUB ------------------------------------ ;; +;; MAGNIFICENT MULTIBOOT HEADER FOR GRUB ------------------------------------ ;; MB_header: align 4 dd MB_HEADER_MAGIC @@ -52,7 +52,7 @@ MB_header: dd 00 ; (bss) not necessary dd MB_start ; entry address GRUB will start at -;; Multiboot entry point for Grub ------------------------------------------- ;; +;; MULTIBOOT POINT ENTRY FOR GRUB ------------------------------------------- ;; MB_start: mov esp, KERNEL_STACK ; Setup the stack push 0 ; Reset EFLAGS @@ -65,13 +65,22 @@ MB_start: jmp Die ; Aufwiedersehen ;; THE HOLES ---------------------------------------------------------------- ;; + +; ---------------------------------------------------------------------------- ; +; Prints 'ERR:XX' where 'XX' is the str in AX ; +; ---------------------------------------------------------------------------- ; Error: mov dword [0xb8000], 0x4f524f45 mov dword [0xb8004], 0x4f3a4f52 mov dword [0xb8008], 0x4f204f20 mov byte [0xb800a], al + mov byte [0xb800c], ah + mov byte [0xb800d], 0x4f jmp Die +; ---------------------------------------------------------------------------- ; +; Kills the mind of your computer to get it prostrated ; +; ---------------------------------------------------------------------------- ; Die: cli hlt ; die nooooow @@ -95,24 +104,57 @@ _loader: jmp lbegin %include "boot/loader/multiboot/check.inc" -lbegin: - call MB_check - jmp lnext - %include "boot/loader/cpu/cpuid.inc" -lnext: - call Check_cpuid - call Is64Bits - jmp lnext2 - %include "boot/loader/mem/structures.inc" -lnext2: - call Setup_paging - call Go64 - jmp lnext3 %include "boot/loader/mem/management.inc" -lnext3: - mov dword [0xb8000], 0x2f4b2f4f - ret +lbegin: + call MB_check + call Check_cpuid + call Is64Bits + call CheckA20 + + call Setup_paging + call Go64 + + lgdt [GDT64.pointer] + jmp GDT64.code:l64 + +[BITS 64] +%include "boot/loader/io/terminal.inc" +%include "boot/loader/io/ata.inc" +%include "boot/loader/cpu/cpu.inc" + +Salut db 0x09, " Booting OS/K ", 0x09, 0x0A, 0x0D, 0x0 +ReadAttempt db 0x09, " Attempt to read a sector with ATA commands...", 0 + +l64: + ;; Some cleanup + mov ax, 0 + mov ss, ax + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + ;; Hello world + mov bl, 0x0A + mov esi, Salut + call write + + ;; Read ATA + mov bl, 0x0F + mov esi, ReadAttempt + call write + + call temporize + + + + ;; Reading a sector of the disk + mov bl, 1 + mov bh, 1 + call ata_read + + jmp Die diff --git a/boot/loader/mem/management.inc b/boot/loader/mem/management.inc index 48ff4cc..57f86d7 100644 --- a/boot/loader/mem/management.inc +++ b/boot/loader/mem/management.inc @@ -87,3 +87,22 @@ Go64: popa ret + +; ---------------------------------------------------------------------------- ; +; Checks if Grub has enabled A20 line ; +; ---------------------------------------------------------------------------- ; +CheckA20: + pushad + mov edi,0x112345 ;odd megabyte address. + mov esi,0x012345 ;even megabyte address. + mov [esi],esi ;making sure that both addresses contain diffrent values. + mov [edi],edi ;(if A20 line is cleared the two pointers would point to the address 0x012345 that would contain 0x112345 (edi)) + cmpsd ;compare addresses to see if the're equivalent. + popad + jne .A20_on ;if not equivalent , A20 line is set. + jmp .A20_err +.A20_on: + ret +.A20_err: + mov ax, "03" ; ERROR 03 : A20 line failed + jmp Error diff --git a/boot/loader/mem/structures.inc b/boot/loader/mem/structures.inc index 4947b9d..e1be0bd 100644 --- a/boot/loader/mem/structures.inc +++ b/boot/loader/mem/structures.inc @@ -28,80 +28,20 @@ ;; GDT WITH DOC ALIGN 4096 GDT64: - NULL_SELECTOR: ;; null selector within 64 bits - dw GDT_LENGTH ; limit of GDT - dw GDT64 ; linear address of GDT - dd 0x0 ; - - CODE_SELECTOR: ;; 32-bit code selector (ring 0) - dw 0x0000FFFF ; Segment Limit - db 0x0, 0x0, 0x0 ; Base Address - db 10011010b ; |7|6|5|4|3|2|1|0| - ; | | | | | | | `----- 1 when segment used. - ; | | | | | | `------ 1 when writable. - ; | | | | | `------- 1 if "conformant". Don't know what is it... spectral ? xD - ; | | | | `-------- 1 always - ; | | | `--------- 1 for segment descriptor, 0 for system descriptor - ; | | `---------- DPL !!! 0 for ring 0 - ; | `----------- DPL (2/2) - ; `------------ 1 if in physical memory, 0 if page fault - db 11001111b ; |7|6|5|4|3|2|1|0| - ; | | | | | | | `----- Limit 16 - ; | | | | | | `------ Limit 17 - ; | | | | | `------- Limit 18 - ; | | | | `-------- Limit 19 - ; | | | `--------- available for use - ; | | `---------- 0 always - ; | `----------- size of data. 1 for 32bits - ; `------------ 0 if limit is in Bytes, 1 if it's in pages (4ko) - db 0x0 ; Base Address - - DATA_SELECTOR: ;; flat data selector (ring 0) - dw 0x0000FFFF ; Segment Limit - db 0x0, 0x0, 0x0 ; Base Address - db 10010010b ; |7|6|5|4|3|2|1|0| - ; | | | | | | | `----- 1 when segment used. - ; | | | | | | `------ 1 when writable. - ; | | | | | `------- expansion direction. 1 for a LIFO - ; | | | | `-------- 1 always - ; | | | `--------- 1 for segment descriptor, 0 for system descriptor - ; | | `---------- DPL !!! 0 for ring 0 - ; | `----------- DPL (2/2) - ; `------------ 1 if in physical memory, 0 if page fault - db 10001111b ; |7|6|5|4|3|2|1|0| - ; | | | | | | | `----- Limit 16 - ; | | | | | | `------ Limit 17 - ; | | | | | `------- Limit 18 - ; | | | | `-------- Limit 19 - ; | | | `--------- available for use - ; | | `---------- 0 always - ; | `----------- size of data. 1 for 32bits - ; `------------ 0 if limit is in Bytes, 1 if it's in pages (4ko) - db 0x0 ; Base Address - - LONG_SELECTOR: ;; 64-bit code selector (ring 0) - dw 0x0000FFFF ; Segment Limit - db 0x0, 0x0, 0x0 ; Base Address - db 10011010b ; |7|6|5|4|3|2|1|0| - ; | | | | | | | `----- 1 when segment used. - ; | | | | | | `------ 1 when writable. - ; | | | | | `------- 1 if "conformant". Don't know what is it... spectral ? xD - ; | | | | `-------- 1 always - ; | | | `--------- 1 for segment descriptor, 0 for system descriptor - ; | | `---------- DPL !!! 0 for ring 0 - ; | `----------- DPL (2/2) - ; `------------ 1 if in physical memory, 0 if page fault - db 10101111b ; |7|6|5|4|3|2|1|0| - ; | | | | | | | `----- Limit 16 - ; | | | | | | `------ Limit 17 - ; | | | | | `------- Limit 18 - ; | | | | `-------- Limit 19 - ; | | | `--------- available for use - ; | | `---------- 0 always - ; | `----------- size of data. 1 for 32bits - ; `------------ 0 if limit is in Bytes, 1 if it's in pages (4ko) - db 0x0 ; Base Address - GDT_LENGTH: + ;; Null selector within 64 bits + .null: + dq 0x0 ; Zero entry + ;; 64-bit code selector (ring 0) + .code: equ $ - GDT64 + dq (1<<43) | (1<<44) | (1<<47) | (1<<53) + ; | | | | + ; | | | `------ 64-bit selector + ; | | `---------------- Present selector + ; | `-------------------------- Descriptor type + ; `------------------------------------ Executable segment + .pointer: + dw $ - GDT64 - 1 + dq GDT64 ;; EMPTY PAGE TABLES (identity of the first 1GiB) ALIGN 4096 diff --git a/boot/loader/multiboot/check.inc b/boot/loader/multiboot/check.inc index e1b42e3..c045e64 100644 --- a/boot/loader/multiboot/check.inc +++ b/boot/loader/multiboot/check.inc @@ -31,5 +31,5 @@ MB_check: jne .no_MB ret .no_MB: - mov al, "0" ; ERROR 0 : No multiboot + mov ax, "01" ; ERROR 01 : No multiboot jmp Error diff --git a/build/obj/boot/loader.bin b/build/obj/boot/loader.bin index 1b1f118..aa06194 100644 Binary files a/build/obj/boot/loader.bin and b/build/obj/boot/loader.bin differ