From 955a1b508ed9d18156518549e24e8f71ab84c8a3 Mon Sep 17 00:00:00 2001 From: Adrien Bourmault Date: Mon, 4 Mar 2019 22:34:07 +0100 Subject: [PATCH 01/11] Stuff --- Makefile | 13 ++- boot/loader/loader.asm | 191 ++------------------------------------ boot/loader/multiboot.inc | 14 +-- build/obj/boot/loader.bin | Bin 2053 -> 74 bytes 4 files changed, 22 insertions(+), 196 deletions(-) diff --git a/Makefile b/Makefile index d58bb68..e25d76a 100644 --- a/Makefile +++ b/Makefile @@ -59,7 +59,7 @@ NC='\033[1;37m' boot.mbr: $(BINDIR)/disk.img $(MBRDIR)/grub.cfg @mkdir -p $(BINDIR)/disk - @echo ${CL2}[boot.mbr]${NC} Installing bootloader on image...${CL3} + @echo ${CL2}[boot.mbr]${NC} Installing MBR on image...${CL3} @$(MBRDIR)/grub-install.sh $(BINDIR)/disk.img $(BINDIR)/disk $(MBRDIR)/grub.cfg @echo ${CL2}[boot.mbr]${CL} OK${CL3} @rmdir $(BINDIR)/disk @@ -69,13 +69,13 @@ boot.loader.asm: $(LOADERDIR)/loader.asm @$(ASM) $(BOOTFLAGS) $(LOADERDIR)/loader.asm -o $(OBJDIR)/boot/loader.bin > /dev/null @echo ${CL2}[boot.loader.asm]${CL} OK${CL3} -bootloader: boot.mbr boot.loader.asm +loader: boot.loader.asm @mkdir -p $(BINDIR)/disk - @echo ${CL2}[bootloader]${NC} Constructing bootloader...${CL3} + @echo ${CL2}[loader]${NC} Constructing kernel loader...${CL3} @$(MBRDIR)/mount.sh $(BINDIR)/disk.img $(BINDIR)/disk @cp $(OBJDIR)/boot/loader.bin $(BINDIR)/disk/boot/loader.bin @$(MBRDIR)/umount.sh $(BINDIR)/disk - @echo ${CL2}[bootloader]${CL} OK${CL3} + @echo ${CL2}[loader]${CL} OK${CL3} @rmdir $(BINDIR)/disk make_disk: @@ -83,8 +83,11 @@ make_disk: @$(MBRDIR)/create_disk.sh $(BINDIR)/disk.img @echo ${CL2}[make_disk]${CL} OK${CL3} -boot: make_disk bootloader +boot: make_disk boot.mbr loader @echo ${CL2}[[boot]]${CL} Terminated without error.${CL3} all: boot kernel @echo ${CL2}[[all]]${CL} Terminated without error.${CL3} + +# TEST + diff --git a/boot/loader/loader.asm b/boot/loader/loader.asm index 807ed10..44315fa 100644 --- a/boot/loader/loader.asm +++ b/boot/loader/loader.asm @@ -35,17 +35,16 @@ _start: mov ax, cs ; correcting cs after the horrible far jump mov ds, ax ; hm... And ds too mov es, ax ; And es because it is jealous - - mov [Bootdrv], dl + ;mov [Bootdrv], dl xor dl, dl jmp 0x0000:main ; pas sûr -multiboot_header: +MB_header: align 4 dd MB_HEADER_MAGIC dd MB_HEADER_FLAGS dd CHECKSUM - dd multiboot_header ; Header address + dd MB_header ; Header address dd _start ; Address of code entry point dd 00 ; (end of code) not necessary dd 00 ; (bss) not necessary @@ -61,189 +60,13 @@ MB_start: add esp, 8 ; Cleanup 8 bytes pushed as arguments jmp Die -%include "boot/loader/cpu/cpuid.asm" -%include "boot/loader/io/rmterm.asm" -%include "boot/loader/io/rmmem.asm" - -main: - - ;;GO GDT64 - cli ; disable interrupts - lgdt [GDT64] - ;; ACTIVATE PROTECTED MODE - mov eax, cr0 - or al, 1b ; PE = 1 - mov cr0, eax - ;; DISABLE PAGING - mov eax, cr0 - and eax, 0x7FFFFFFF ; PG = 0 - ; |0|111111111111111111111111111111 - ; | - ; `------ Paging bit - mov cr0, eax - - push dword [VIDEO_MODE] - push dword [VGA_HEIGHT] - jmp (CODE_SELECTOR-GDT64):main32 - +;; BEGIN OF THE HOLE -------------------------------------------------------- ;; Die: cli hlt ; die nooooow - jmp 0xF000:0xFFF0 + ;jmp 0xF000:0xFFF0 + jmp $ ;; END OF THE HOLE ---------------------------------------------------------- ;; -[BITS 32] -main32: - pop dword [VGA_HEIGHT32] - pop dword [VIDEO_MODE32] - - ;; VERIFY A20 - 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. - mov WORD [A20_OK], 0 - jmp .A20_end -.A20_on: - mov BYTE [A20_OK], 1 -.A20_end: - - ;; INITIALIZE PROTECTED MODE SEGMENT REGISTERS - mov ax, DATA_SELECTOR-GDT64 - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - mov ss, ax - - ;; ACTIVATE PHYSICAL ADRESS EXTENSION - mov eax, cr4 - or eax, 100000b ; PAE = 1 = 4 Mo / page. 0 = 4 Ko - mov cr4, eax - - ;;cleanup - mov edi, 0x70000 - mov ecx, 0x10000 - xor eax, eax - rep stosd - ;;formatting - mov dword [0x70000], 0x71000 + 7 ; first PDP table - mov dword [0x71000], 0x72000 + 7 ; first page directory - mov dword [0x72000], 0x73000 + 7 ; first page table - mov edi, 0x73000 ; address of first page table - mov eax, 7 - mov ecx, 256 ; number of pages to map (1 MB) -.make_page_entries: - stosd - add edi, 4 - add eax, 0x1000 - loop .make_page_entries - ;; pointing pml4 - mov eax, 0x70000 ; Bass address of PML4 - mov cr3, eax ; load page-map level-4 base - - ;; ACTIVATE LONG MODE - mov ecx, 0xC0000080 ; address of MSR - rdmsr ; read MSR - or eax, 100000000b ; LME = 1. (Long Mode Enable) - wrmsr ; write MSR - - ;; ACTIVATE PAGING - mov eax, cr0 - or eax, 0x80000000 ; make bit 31 (PG = Paging) to 1 : - ; |1|000000000000000000000000000000 - ; | - ; `------ Paging bit - mov cr0, eax - push dword 0 - push dword [VIDEO_MODE] - push dword 0 - push dword [VGA_HEIGHT] - jmp (LONG_SELECTOR-GDT64):main64 - -[BITS 64] - -;; DATA - Init db "Booting OS/K !", 0x0D, 0x0A, 0x0D, 0x0A, 0x09, " Checking CPUID...",0 - CPUIDD db 0x09, " Checking CPUID...", 0 - EnA20 db 0x09, " Enabling A20 line...", 0 -%ifdef DEBUG - ReadAttempt db 0x09, " Attempt to read a sector with ATA commands...", 0x0A, 0x0D, 0x0A, 0x0D, 0 -%else - ReadAttempt db 0x09, " Attempt to read a sector with ATA commands...", 0 -%endif - txt db 0x09, " Switching to Long Mode... ", 0 - EndOfLoader db "End of loader.bin. System will halt !", 0x0A, 0x0D, 0 - Reinit db "Booting OS/K !", 0x0D, 0x0A, 0x0D, 0x0A, 0 - Pass db " OK", 0x0A, 0x0D, 0 - Fail db " FAIL!", 0x0A, 0x0D, 0 - msg db "The system is now in x64 mode. Is this not beautiful ?", 0x0A, 0x0D, 0 - FileNotFound db "Second Stage Error : The Kernel was not found.", 0x0A, 0x0D, 0 - DiskError db "Second Stage Error : The Disk has crashed.", 0x0A, 0x0D, 0 - filename db "KERNEL BIN" - -%include "boot/loader/io/lmmem.asm" -%include "boot/loader/io/lmterm.asm" -%include "boot/loader/io/ata.asm" -%include "boot/loader/cpu/cpu.asm" -%include "boot/loader/fs/fat.asm" - -main64: - pop qword [VGA_HEIGHT64] - pop qword [VIDEO_MODE64] - ;; INITIALIZE STACK - mov rsp, 0x9F000 - - call clear - - ;; Printing - mov bl, 0x0B - mov esi, Reinit - call write - - mov bl, 0x0F - mov esi, CPUIDD - call write - - mov bl, 0x0A - mov esi, Pass - call write - - mov bl, 0x0F - mov esi, EnA20 - call write - - call check_a20 - - mov bl, 0x0F - mov esi, txt - call write - - mov bl, 0x0A - mov esi, Pass - call write - - mov bl, 0x0D - mov esi, msg - call write - - mov bl, 0x0F - mov esi, ReadAttempt - call write - - call temporize ; Temporized because the ATA drive must be ready - - mov bl, 1 - mov bh, 1 - call ata_read - - mov bl, 0x0D - mov esi, EndOfLoader - call write - +main: jmp Die - diff --git a/boot/loader/multiboot.inc b/boot/loader/multiboot.inc index f013eda..8874596 100644 --- a/boot/loader/multiboot.inc +++ b/boot/loader/multiboot.inc @@ -24,10 +24,10 @@ ;=----------------------------------------------------------------------------=; ;; MULTIBOOT HEADER -%define MB_AOUT_KLUDGE 1 << 16 ; We are not an ELF executable -%define MB_ALIGN 1 << 0 ; Ask to align loaded modules on page boundaries -%define MB_MEMINFO 1 << 1 ; Ask to provide memory map -%define MB_HEADER_MAGIC 0x1BADB002 -%define MB_HEADER_FLAGS MB_AOUT_KLUDGE|MB_ALIGN|MB_MEMINFO -%define CHECKSUM -(MB_HEADER_MAGIC + MB_HEADER_FLAGS) -%define KERNEL_STACK 0x00200000 ; Stack starts at the 2mb address & grows down +MB_AOUT_KLUDGE equ 1 << 16 ; We are not an ELF executable +MB_ALIGN equ 1 << 0 ; Ask to align loaded modules on page boundaries +MB_MEMINFO equ 1 << 1 ; Ask to provide memory map +MB_HEADER_MAGIC equ 0x1BADB002 +MB_HEADER_FLAGS equ MB_AOUT_KLUDGE|MB_ALIGN|MB_MEMINFO +CHECKSUM equ -(MB_HEADER_MAGIC + MB_HEADER_FLAGS) +KERNEL_STACK equ 0x00200000 ; Stack starts at the 2mb address & grows down diff --git a/build/obj/boot/loader.bin b/build/obj/boot/loader.bin index e12a50a9249c8e894d057034b1482000b1067b68..c5b1e9d04c8c64290d711872813bf39368172aab 100644 GIT binary patch literal 74 zcmYf6Inj5c?|{LjR~`%k3=9lR8`erQGcYpz_78j_02Tp>LVy8~zlVWAfgy`wZb0x0 TPM~P>5sudkzrMWw_xcwA7#|jm literal 2053 zcmeHI|4Um}6hAkKjg4k69kdMg!*1;y6gFqeDqC@M+NMNwHD9_KE1JdRT@xGgO7emo z`(YU}rgUgML%Uy zgkGq7g|@nYU1DxFbb}q?5t*Hh6%~i(*bQYb8(1XFfvOKOauu7xL~-FVdmR(SBTus_ zE^&PSTQpFaWH+;yFo1LBM}5+?)|jMg>@0JSWl`sv6mDAvUs%vzUedD;=FU!(XXIUz zPu;fUH?q$Y14aT+RqQ_dUX!CErSVr_zdKr~TOM_19|~ljfe18HNrb8lN>;6^>U)Tp zT8Dwvx&{4eCn<-A_f`uk6h_LH^%fW@yNmtXv(^K9AZVxGQwdqHw(463Nw=9xQJd*k1XMYxLiQF8Z=tq z8EBLwIT-H2vwFFi?l+svrrq>-K=hsC%H#I8noiWz)WARMtYL3=i1Qi_*HQ$cMs1K~ zvG2T0Wr;>aub+BpRP@PM6a7IsKpRds@XG1)hW%0GV?r~AccIM};IYuFMMC+e;6f$>5i8t{f>x*vl)xe}nQ&1j$}8=6`;<8(lzQO&hj zvi&p|E*5GZ&qbS}R1TDCxm)zcQBDF>$xR#@oM{5=%VKGGe zz1j_6QY`GpCH=d@iD2{`PB}__5pOgg7Rk+4=P7ForHxIeAYNb1tA@yXQkCglh!j7b z-^$PZ5IvI4=|{WXy(U~W2Y=$T;2PfC`A_qo{GHM<4LX1co@{Be-P2`zU-MD)e5oC!3cypqD(W=h{(Amz z|Lq;HyBy9oHuDEbezC@8ekX(TDAvi~0~Gg25>RYt;y%G&#jjV&J9rfv4;QU$V^ z0$FE$o|KU0Dn-(+*e#9=+p7Aw>Mxva?{H@w(|7RIO(YUaTkWNRqTufV%N6fpVnn+N zC<=HZu0vrrC?8^wR7LtX9R~cIVR)tM&es3{ From 9b8854a177cb2a4b674a4fc2bad165230c2a596a Mon Sep 17 00:00:00 2001 From: Adrien Bourmault Date: Mon, 4 Mar 2019 22:50:35 +0100 Subject: [PATCH 02/11] Makefile testing stuff --- Makefile | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index e25d76a..78b7f00 100644 --- a/Makefile +++ b/Makefile @@ -83,11 +83,14 @@ make_disk: @$(MBRDIR)/create_disk.sh $(BINDIR)/disk.img @echo ${CL2}[make_disk]${CL} OK${CL3} +testloader: loader + @qemu-system-x86_64 -hda build/bin/disk.img -d cpu_reset & + @ndisasm $(OBJDIR)/boot/loader.bin -b 32 > loader_dism.asm + + boot: make_disk boot.mbr loader @echo ${CL2}[[boot]]${CL} Terminated without error.${CL3} all: boot kernel @echo ${CL2}[[all]]${CL} Terminated without error.${CL3} -# TEST - From a24008e617d484093d15d4da93b5aefa6330655b Mon Sep 17 00:00:00 2001 From: Adrien Bourmault Date: Mon, 4 Mar 2019 22:58:48 +0100 Subject: [PATCH 03/11] gitignore update --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 8e35884..8b8d806 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ # Test files test-*.c +loader_dism.asm # Object files *.o From 991b34eea3249ccf0aa8444c55dcee38980ecfc1 Mon Sep 17 00:00:00 2001 From: Adrien Bourmault Date: Tue, 5 Mar 2019 00:15:08 +0100 Subject: [PATCH 04/11] some stuff --- boot/loader/loader.asm | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/boot/loader/loader.asm b/boot/loader/loader.asm index 44315fa..0b9da7f 100644 --- a/boot/loader/loader.asm +++ b/boot/loader/loader.asm @@ -27,46 +27,50 @@ [BITS 32] [global _start] -[ORG 0x100000] ; Where GRUB loads us. +[ORG 0x100000] ; Where GRUB loads us. %include "boot/loader/multiboot.inc" +;; 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 - mov es, ax ; And es because it is jealous + mov ax, cs ; correcting cs after the horrible far jump + mov ds, ax ; hm... And ds too + mov es, ax ; And es because it is jealous ;mov [Bootdrv], dl xor dl, dl - jmp 0x0000:main ; pas sûr + jmp 0x0000:main ; pas sûr +;; Magnificent multiboot header for GRUB ------------------------------------ ;; MB_header: align 4 dd MB_HEADER_MAGIC dd MB_HEADER_FLAGS dd CHECKSUM - dd MB_header ; Header address - dd _start ; Address of code entry point - dd 00 ; (end of code) not necessary - dd 00 ; (bss) not necessary - dd MB_start ; entry address GRUB will start at + dd MB_header ; Header address + dd _start ; Address of code entry point + dd 00 ; (end of code) not necessary + dd 00 ; (bss) not necessary + dd MB_start ; entry address GRUB will start at +;; Multiboot entry point for Grub ------------------------------------------- ;; MB_start: - mov esp, KERNEL_STACK ; Setup the stack - push 0 ; Reset EFLAGS + mov esp, KERNEL_STACK ; Setup the stack + push 0 ; Reset EFLAGS popf - push eax ; 2nd argument is magic number - push ebx ; 1st argument multiboot info pointer + push eax ; 2nd argument is magic number + push ebx ; 1st argument multiboot info pointer call main - add esp, 8 ; Cleanup 8 bytes pushed as arguments - jmp Die + add esp, 8 ; Cleanup arguments "A la MIPS" + jmp Die ; Aufwiedersehen -;; BEGIN OF THE HOLE -------------------------------------------------------- ;; +;; THE HOLE ----------------------------------------------------------------- ;; Die: cli - hlt ; die nooooow + hlt ; die nooooow ;jmp 0xF000:0xFFF0 jmp $ -;; END OF THE HOLE ---------------------------------------------------------- ;; +;; THE CODE ------------------------------------------------------------------;; main: + jmp Die From d609c9d890e43b68d2f72c3e52bbffb459dfeffa Mon Sep 17 00:00:00 2001 From: Adrien Bourmault Date: Tue, 5 Mar 2019 15:50:02 +0100 Subject: [PATCH 05/11] Paging work and stuff --- .gitignore | 1 + Makefile | 2 +- boot/loader/cpu/cpuid.asm | 65 ---------------------- boot/loader/io/rmmem.asm | 113 -------------------------------------- boot/loader/io/rmterm.asm | 70 ----------------------- boot/loader/loader.asm | 31 +++++++++-- boot/loader/multiboot.inc | 33 ----------- build/obj/boot/loader.bin | Bin 74 -> 12647 bytes 8 files changed, 29 insertions(+), 286 deletions(-) delete mode 100644 boot/loader/cpu/cpuid.asm delete mode 100644 boot/loader/io/rmmem.asm delete mode 100644 boot/loader/io/rmterm.asm delete mode 100644 boot/loader/multiboot.inc diff --git a/.gitignore b/.gitignore index 8b8d806..37da073 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ # Test files test-*.c loader_dism.asm +qemu.log # Object files *.o diff --git a/Makefile b/Makefile index 78b7f00..052f64c 100644 --- a/Makefile +++ b/Makefile @@ -84,7 +84,7 @@ make_disk: @echo ${CL2}[make_disk]${CL} OK${CL3} testloader: loader - @qemu-system-x86_64 -hda build/bin/disk.img -d cpu_reset & + @qemu-system-x86_64 -hda build/bin/disk.img -d cpu_reset,guest_errors,pcall -s -S -enable-kvm 2> qemu.log & @ndisasm $(OBJDIR)/boot/loader.bin -b 32 > loader_dism.asm diff --git a/boot/loader/cpu/cpuid.asm b/boot/loader/cpu/cpuid.asm deleted file mode 100644 index 89c1bde..0000000 --- a/boot/loader/cpu/cpuid.asm +++ /dev/null @@ -1,65 +0,0 @@ -;=----------------------------------------------------------------------------=; -; GNU GPL OS/K ; -; ; -; Desc: Basic realmode CPU Detection ; -; (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 16] - -;; GLOBAL DATA -NoLongMode db 0x0A, 0x0D, "ERROR : Your computer is not designed for x64 OS", 0 - -;; TEXT - -Is64bits: -;-----------------------------------------------------------------------; -; Checks if the CPU is compatible with 64-bits operating systems ; -; If the 21th bit of the eax register is set, then CPUID is supported ; -; We then test CPUID's result to see if long mode is supported ; -;-----------------------------------------------------------------------; - pushfd ; recovering the flags in eax - pop eax - mov ecx, eax - xor eax, 0x200000 - push eax - popfd - pushfd - pop eax - xor eax, ecx - shr eax, 21 - and eax, 1 ; magical spell of murta - push ecx - popfd - test eax, eax - jz .NonCompat ; if (CPUID non supporté) goto NonCompat - mov eax, 0x80000000 - cpuid - cmp eax, 0x80000001 - jb .NonCompat ; if (eax <= 0x80000001) goto NonCompat - mov eax, 0x80000001 - cpuid - test edx, 1 << 29 - jz .NonCompat ; if (edx != 1 << 29) goto NonCompat - ret ; back to mbr.s -.NonCompat: - stc - ret diff --git a/boot/loader/io/rmmem.asm b/boot/loader/io/rmmem.asm deleted file mode 100644 index 865b9a9..0000000 --- a/boot/loader/io/rmmem.asm +++ /dev/null @@ -1,113 +0,0 @@ -;=----------------------------------------------------------------------------=; -; GNU GPL OS/K ; -; ; -; Desc: Basic Memory Realmode 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 16] - -;; GDT WITH DOC -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: - -;; TEXT - -set_a20: - push ax - in al, 0x92 - or al, 2 - out 0x92, al - pop ax - ret diff --git a/boot/loader/io/rmterm.asm b/boot/loader/io/rmterm.asm deleted file mode 100644 index 275ff71..0000000 --- a/boot/loader/io/rmterm.asm +++ /dev/null @@ -1,70 +0,0 @@ -;=----------------------------------------------------------------------------=; -; GNU GPL OS/K ; -; ; -; Desc: Basic realmode terminal 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 16] - -disable_cursor: - pushf - push eax - push edx - mov dx, 0x3D4 - mov al, 0xA ; low cursor shape register - out dx, al - inc dx - mov al, 0x20 ; bits 6-7 unused, bit 5 disables the cursor, bits 0-4 control the cursor shape - out dx, al - pop edx - pop eax - popf - ret - -get_dimensions: - push eax - push ebx - mov ah, 0x0F - int 0x10 - mov [VGA_HEIGHT], ah - mov [VIDEO_MODE], al - pop ebx - pop eax - ret - -PrintB: -;---------------------------------------------------; -; Print out a simple string. ; -; ; -; DS:SI = String to print ; -; ; -; Returns: None ; -; ; -;---------------------------------------------------; - lodsb ; Load byte from ds:si to al - or al, al ; If al is empty stop looping - jz .done ; Done looping and return - mov ah, 0x0e ; Teletype output - int 0x10 ; Video interupt - jmp PrintB ; Loop untill string is null - .done: - ret diff --git a/boot/loader/loader.asm b/boot/loader/loader.asm index 0b9da7f..1fb8f51 100644 --- a/boot/loader/loader.asm +++ b/boot/loader/loader.asm @@ -29,7 +29,7 @@ [global _start] [ORG 0x100000] ; Where GRUB loads us. -%include "boot/loader/multiboot.inc" +%include "boot/loader/multiboot/header.inc" ;; Normal entry point, but a little bit unused since we never use it because... _start: @@ -59,18 +59,41 @@ MB_start: popf push eax ; 2nd argument is magic number push ebx ; 1st argument multiboot info pointer + mov ecx, eax call main add esp, 8 ; Cleanup arguments "A la MIPS" jmp Die ; Aufwiedersehen -;; THE HOLE ----------------------------------------------------------------- ;; +;; THE HOLES ---------------------------------------------------------------- ;; +Error: + mov dword [0xb8000], 0x4f524f45 + mov dword [0xb8004], 0x4f3a4f52 + mov dword [0xb8008], 0x4f204f20 + mov byte [0xb800a], al + jmp Die + Die: cli hlt ; die nooooow ;jmp 0xF000:0xFFF0 jmp $ -;; THE CODE ------------------------------------------------------------------;; +;; THE CODE ----------------------------------------------------------------- ;; main: + call MB_check + + call Check_cpuid + call Is64Bits + + call Setup_paging + call Go64 + + mov dword [0xb8000], 0x2f4b2f4f + ret + +;; INCLUDES ----------------------------------------------------------------- ;; +%include "boot/loader/cpu/cpuid.inc" +%include "boot/loader/multiboot/check.inc" +%include "boot/loader/mem/structures.inc" +%include "boot/loader/mem/management.inc" - jmp Die diff --git a/boot/loader/multiboot.inc b/boot/loader/multiboot.inc deleted file mode 100644 index 8874596..0000000 --- a/boot/loader/multiboot.inc +++ /dev/null @@ -1,33 +0,0 @@ -;=----------------------------------------------------------------------------=; -; GNU GPL OS/K ; -; ; -; Desc: Multiboot header ; -; (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 . ; -;=----------------------------------------------------------------------------=; - -;; MULTIBOOT HEADER -MB_AOUT_KLUDGE equ 1 << 16 ; We are not an ELF executable -MB_ALIGN equ 1 << 0 ; Ask to align loaded modules on page boundaries -MB_MEMINFO equ 1 << 1 ; Ask to provide memory map -MB_HEADER_MAGIC equ 0x1BADB002 -MB_HEADER_FLAGS equ MB_AOUT_KLUDGE|MB_ALIGN|MB_MEMINFO -CHECKSUM equ -(MB_HEADER_MAGIC + MB_HEADER_FLAGS) -KERNEL_STACK equ 0x00200000 ; Stack starts at the 2mb address & grows down diff --git a/build/obj/boot/loader.bin b/build/obj/boot/loader.bin index c5b1e9d04c8c64290d711872813bf39368172aab..8721f45ff79db257469fd909defc93f881d3203e 100644 GIT binary patch literal 12647 zcmeI(ze_?<6bJD0`~gzPeGN@5H=!xWm(Wnu(9qOy)fR_lhn66+EqL-KA&eSB7n?(e zh9@*UGw>}DG&veLXm1U~g6v%Nk7)S5;oNi1^Fbqm%C-pdjC8nlZZl%hm|lH z^rJF;bK23}*=KS6L?r2is_COrYp}t6=Oq@bb)sZ1(t*mVPBg+oam;_PUf|jq=D8-L$Ad(i5#7Db*4yiOU7zkDKmY;|fB*y_ z009U<00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P$##AOHafKmY;|fB*y_009U<00Izz z00bcLzXe=cGRg77_hgvl((1h6W>a6B-y%pFeZ(EkOOaQ-zh4|vh^Wx#hYCC+5?vvC bjxR-`*R+W|k%|+)SrC?xUYy5lk?`7o2fS}% delta 35 tcmV+;0NnrQVoD2UjL44Ij=(U|>PV3bFA(Sn0001k#0cvE`t-sE)5(5AL From 70b5c0690e66e52169944d8f51d8413be47b17d4 Mon Sep 17 00:00:00 2001 From: Adrien Bourmault Date: Tue, 5 Mar 2019 19:11:35 +0100 Subject: [PATCH 06/11] stuff --- Makefile | 2 +- boot/loader/loader.asm | 23 ++++++++++++++++++++++- build/obj/boot/loader.bin | Bin 12647 -> 12644 bytes 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 052f64c..49bb50e 100644 --- a/Makefile +++ b/Makefile @@ -84,7 +84,7 @@ 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 -s -S -enable-kvm 2> qemu.log & + @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/loader.asm b/boot/loader/loader.asm index 1fb8f51..586d18e 100644 --- a/boot/loader/loader.asm +++ b/boot/loader/loader.asm @@ -86,7 +86,28 @@ main: call Is64Bits call Setup_paging - call Go64 + + ;; Registering paging + mov eax, PML4_table + mov cr3, eax ; Load PML4 to cr3 + + mov eax, cr4 + or eax, 1 << 5 + mov cr4, eax ; Enable PAE + + ;; Activate long mode + mov ecx, 0xC0000080 ; address of MSR + rdmsr ; read MSR + or eax, 1 << 8 ; LME = 1. (Long Mode Enable) + wrmsr ; write MSR + + ;; Enable paging + mov eax, cr0 + or eax, 1 << 31 ; make MSR bit 31 (PG = Paging) to 1 : + ; |1|000000000000000000000000000000 + ; | + ; `------ Paging bit + mov cr0, eax mov dword [0xb8000], 0x2f4b2f4f ret diff --git a/build/obj/boot/loader.bin b/build/obj/boot/loader.bin index 8721f45ff79db257469fd909defc93f881d3203e..182a3e209f7fadaa2e907c05e87f344e1c0f846e 100644 GIT binary patch delta 152 zcmaE!^dxCQfoKZ@1H+3H5Mc!(mKrcH?9iBOXQ(l;L)+wK=Kufy=R|ZKG-Y5=Ux?+W;dt+ delta 119 zcmaEo^gL-ofkX@g1H%g&5FrX8Y7KzI79cTktv1u^i4*UNOO*Zp|G)7k(}uO$rHqF+ z7`#ja@);N(Fl^>wlr<1z5ENi&KEb@0fl+{A2ZJJ%GuhryTmZy#Z2ZZ<#K2Jc Date: Tue, 5 Mar 2019 19:24:14 +0100 Subject: [PATCH 07/11] stuff --- boot/loader/cpu/cpuid.inc | 70 +++++++++++++++++++ boot/loader/mem/management.inc | 54 +++++++++++++++ boot/loader/mem/structures.inc | 113 +++++++++++++++++++++++++++++++ boot/loader/multiboot/check.inc | 35 ++++++++++ boot/loader/multiboot/header.inc | 34 ++++++++++ 5 files changed, 306 insertions(+) create mode 100644 boot/loader/cpu/cpuid.inc create mode 100644 boot/loader/mem/management.inc create mode 100644 boot/loader/mem/structures.inc create mode 100644 boot/loader/multiboot/check.inc create mode 100644 boot/loader/multiboot/header.inc diff --git a/boot/loader/cpu/cpuid.inc b/boot/loader/cpu/cpuid.inc new file mode 100644 index 0000000..44e19e7 --- /dev/null +++ b/boot/loader/cpu/cpuid.inc @@ -0,0 +1,70 @@ +;=----------------------------------------------------------------------------=; +; GNU GPL OS/K ; +; ; +; Desc: Basic realmode CPU Detection ; +; (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 32] + +; ---------------------------------------------------------------------------- ; +; Checks if the CPU is compatible with 64-bits operating systems ; +; If the 21th bit of the eax register is set, then CPUID is supported ; +; We then test CPUID's result to see if long mode is supported ; +; ---------------------------------------------------------------------------- ; +Is64Bits: + ;; test if extended processor info in available + mov eax, 0x80000000 ; implicit argument for cpuid + cpuid ; get highest supported argument + cmp eax, 0x80000001 ; it needs to be at least 0x80000001 + jb .no_64 ; if it's less, the CPU is too old for long mode + + ;; use extended info to test if long mode is available + mov eax, 0x80000001 ; argument for extended processor info + cpuid ; returns various feature bits in ecx and edx + test edx, 1 << 29 ; test if the LM-bit is set in the D-register + jz .no_64 ; If it's not set, there is no long mode + ret +.no_64: + mov al, "2" ; ERROR 1 : 64bits unsupported + jmp Error + +; ---------------------------------------------------------------------------- ; +; Check if CPUID is supported by flip the bit 21 (ID bit) in the FLAGS ; +; register. If we can flip, CPUID is available. ; +; ---------------------------------------------------------------------------- ; +Check_cpuid: + pushfd ; Copy FLAGS in to EAX via stack + pop eax + mov ecx, eax ; Copy to ECX as well for comparing later on + xor eax, 1 << 21 ; Flip the ID bit + push eax ; Copy EAX to FLAGS via the stack + popfd + pushfd ; Copy FLAGS back to EAX (with the flipped bit if CPUID is supported) + pop eax + push ecx ; flipping the flipped ID bit back if it was ever flipped like flipper + popfd + cmp eax, ecx ; VERITY MOMENT + je .no_cpuid + ret +.no_cpuid: + mov al, "1" ; ERROR 1 : CPUID UNSUPPORTED + jmp Error diff --git a/boot/loader/mem/management.inc b/boot/loader/mem/management.inc new file mode 100644 index 0000000..3790a9d --- /dev/null +++ b/boot/loader/mem/management.inc @@ -0,0 +1,54 @@ +;=----------------------------------------------------------------------------=; +; GNU GPL OS/K ; +; ; +; Desc: Memory management from protected mode ; +; (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 32] + +; ---------------------------------------------------------------------------- ; +; Constructor for the page tables in protected mode ; +; ---------------------------------------------------------------------------- ; +Setup_paging: + ;; Map the first PML4 entry to PDP table + mov eax, PDP_table + or eax, 0b11 ; present + writable + mov [PML4_table], eax + + ;; Map the first PDP entry to PD table + mov eax, PD_table + or eax, 0b11 ; present + writable + mov [PDP_table], eax + + ;; Map each PD entry to a 'huge' 2MiB page + mov ecx, 0 ; counter variable +.map_p2_table: + ;; map ecx-th PD entry to a huge page that starts at address 2MiB*ecx + mov eax, 0x200000 + mul ecx ; start address of ecx-th page + or eax, 0b10000011 ; present + writable + huge + mov [PD_table + ecx * 8], eax + inc ecx + cmp ecx, 512 ; if counter == 512, the whole PD table is mapped + jne .map_p2_table ; else map the next entry + + ret diff --git a/boot/loader/mem/structures.inc b/boot/loader/mem/structures.inc new file mode 100644 index 0000000..31e98b4 --- /dev/null +++ b/boot/loader/mem/structures.inc @@ -0,0 +1,113 @@ +;=----------------------------------------------------------------------------=; +; GNU GPL OS/K ; +; ; +; Desc: Memory Design Structures ; +; (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 32] + +;; GDT WITH DOC +ALIGN 4 +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: + +;; EMPTY PAGE TABLES (identity of the first 1GiB) +ALIGN 4 +PML4_table: + resb 4096 +PDP_table: + resb 4096 +PD_table: + resb 4096 diff --git a/boot/loader/multiboot/check.inc b/boot/loader/multiboot/check.inc new file mode 100644 index 0000000..e1b42e3 --- /dev/null +++ b/boot/loader/multiboot/check.inc @@ -0,0 +1,35 @@ +;=----------------------------------------------------------------------------=; +; GNU GPL OS/K ; +; ; +; Desc: Multiboot useful 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 . ; +;=----------------------------------------------------------------------------=; + +; ---------------------------------------------------------------------------- ; +; Multiboot check function to ensure we are launch by GRUB ; +; ---------------------------------------------------------------------------- ; +MB_check: + cmp ecx, MB_GRUB_MAGIC ; The magic number must be in ecx + jne .no_MB + ret +.no_MB: + mov al, "0" ; ERROR 0 : No multiboot + jmp Error diff --git a/boot/loader/multiboot/header.inc b/boot/loader/multiboot/header.inc new file mode 100644 index 0000000..8688c28 --- /dev/null +++ b/boot/loader/multiboot/header.inc @@ -0,0 +1,34 @@ +;=----------------------------------------------------------------------------=; +; GNU GPL OS/K ; +; ; +; Desc: Multiboot header ; +; (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 . ; +;=----------------------------------------------------------------------------=; + +;; MULTIBOOT HEADER +MB_AOUT_KLUDGE equ 1 << 16 ; We are not an ELF executable +MB_ALIGN equ 1 << 0 ; Ask to align loaded modules on page boundaries +MB_MEMINFO equ 1 << 1 ; Ask to provide memory map +MB_HEADER_MAGIC equ 0x1badb002 +MB_GRUB_MAGIC equ 0x2badb002 +MB_HEADER_FLAGS equ MB_AOUT_KLUDGE|MB_ALIGN|MB_MEMINFO +CHECKSUM equ -(MB_HEADER_MAGIC + MB_HEADER_FLAGS) +KERNEL_STACK equ 0x00200000 ; Stack starts at the 2mb address & grows down From 33d68464b2b1df4d5217c58001cfe7f11fa680b5 Mon Sep 17 00:00:00 2001 From: Adrien Bourmault Date: Tue, 5 Mar 2019 19:54:14 +0100 Subject: [PATCH 08/11] LONG MODE MULTIBOOT WORKS gsp! --- boot/loader/loader.asm | 61 ++++++++++++++++----------------- boot/loader/mem/management.inc | 28 +++++++++++++++ build/obj/boot/loader.bin | Bin 12644 -> 12649 bytes 3 files changed, 57 insertions(+), 32 deletions(-) diff --git a/boot/loader/loader.asm b/boot/loader/loader.asm index 586d18e..09b565b 100644 --- a/boot/loader/loader.asm +++ b/boot/loader/loader.asm @@ -38,7 +38,7 @@ _start: mov es, ax ; And es because it is jealous ;mov [Bootdrv], dl xor dl, dl - jmp 0x0000:main ; pas sûr + jmp 0x0000:_loader ; pas sûr ;; Magnificent multiboot header for GRUB ------------------------------------ ;; MB_header: @@ -60,7 +60,7 @@ MB_start: push eax ; 2nd argument is magic number push ebx ; 1st argument multiboot info pointer mov ecx, eax - call main + call _loader add esp, 8 ; Cleanup arguments "A la MIPS" jmp Die ; Aufwiedersehen @@ -79,42 +79,39 @@ Die: jmp $ ;; THE CODE ----------------------------------------------------------------- ;; -main: - call MB_check +; ---------------------------------------------------------------------------- ; +; _loader ; +; ; +; This is the function that initiates the launch of OS/K. It verifies that ; +; Grub has properly loaded this loader and makes the appropriate setup so ; +; that the kernel will work properly ; +; ; +; Why this original design ? Because it works well and prevent us to cause ; +; triple faults by aligment error or too long jumps (yup, it can be a problem); +; ; +; ---------------------------------------------------------------------------- ; +_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 + jmp lnext3 +%include "boot/loader/mem/management.inc" - ;; Registering paging - mov eax, PML4_table - mov cr3, eax ; Load PML4 to cr3 - - mov eax, cr4 - or eax, 1 << 5 - mov cr4, eax ; Enable PAE - - ;; Activate long mode - mov ecx, 0xC0000080 ; address of MSR - rdmsr ; read MSR - or eax, 1 << 8 ; LME = 1. (Long Mode Enable) - wrmsr ; write MSR - - ;; Enable paging - mov eax, cr0 - or eax, 1 << 31 ; make MSR bit 31 (PG = Paging) to 1 : - ; |1|000000000000000000000000000000 - ; | - ; `------ Paging bit - mov cr0, eax - +lnext3: mov dword [0xb8000], 0x2f4b2f4f ret -;; INCLUDES ----------------------------------------------------------------- ;; -%include "boot/loader/cpu/cpuid.inc" -%include "boot/loader/multiboot/check.inc" -%include "boot/loader/mem/structures.inc" -%include "boot/loader/mem/management.inc" - diff --git a/boot/loader/mem/management.inc b/boot/loader/mem/management.inc index 3790a9d..3634666 100644 --- a/boot/loader/mem/management.inc +++ b/boot/loader/mem/management.inc @@ -52,3 +52,31 @@ Setup_paging: jne .map_p2_table ; else map the next entry ret + +; ---------------------------------------------------------------------------- ; +; Enable long mode and paging ; +; ---------------------------------------------------------------------------- ; +Go64: + ;; Registering paging + mov eax, PML4_table + mov cr3, eax ; Load PML4 to cr3 + + mov eax, cr4 + or eax, 1 << 5 + mov cr4, eax ; Enable PAE + + ;; Activate long mode + mov ecx, 0xC0000080 ; address of MSR + rdmsr ; read MSR + or eax, 1 << 8 ; LME = 1. (Long Mode Enable) + wrmsr ; write MSR + + ;; Enable paging + mov eax, cr0 + or eax, 1 << 31 ; make MSR bit 31 (PG = Paging) to 1 : + ; |1|000000000000000000000000000000 + ; | + ; `------ Paging bit + mov cr0, eax + + ret diff --git a/build/obj/boot/loader.bin b/build/obj/boot/loader.bin index 182a3e209f7fadaa2e907c05e87f344e1c0f846e..faf31098a145ef011cb83636a3ffd826bcb67367 100644 GIT binary patch delta 155 zcmaEo^fGBezSwKt#-B_Z)@qkB9^PQ^`oxQO|NsAgZ8dR+g8u9Ib0RtqnldmbFa*q< z6A?Jq@Tt17mtC8UhDx9FO>`!7$!{kz;J`Jj*!YtHsI>IS;T<0sCbp^b96rv<(7?^$ukWpY7yy`? BMb7{L delta 150 zcmaEv^dxCQzW9q41_p)~DImfML@YI6VA!F-IN8ilo%=W|LjyO1zrMHr;fbvZCNDGp z|NlQHqVu3B1A_uXz}z_zfpaZSlrSFNVEEDxDAo9rX~SCWQXt>pr5%v3!N|e5@rsOr p#10KX0fy!i%!@S`1%QStLOFty`3=SRKwQVhpA1Y445d#F0|5RJH?jZ# From cdcb30683907411f81da038afe59d01721e5b407 Mon Sep 17 00:00:00 2001 From: Adrien Bourmault Date: Tue, 5 Mar 2019 20:40:34 +0100 Subject: [PATCH 09/11] LONG MODE MULTIBOOT WORKS gsp! --- boot/loader/loader.asm | 1 + boot/loader/mem/management.inc | 7 +++++++ boot/loader/mem/structures.inc | 4 ++-- build/obj/boot/loader.bin | Bin 12649 -> 20612 bytes 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/boot/loader/loader.asm b/boot/loader/loader.asm index 09b565b..2040668 100644 --- a/boot/loader/loader.asm +++ b/boot/loader/loader.asm @@ -108,6 +108,7 @@ lnext: %include "boot/loader/mem/structures.inc" lnext2: call Setup_paging + call Go64 jmp lnext3 %include "boot/loader/mem/management.inc" diff --git a/boot/loader/mem/management.inc b/boot/loader/mem/management.inc index 3634666..48ff4cc 100644 --- a/boot/loader/mem/management.inc +++ b/boot/loader/mem/management.inc @@ -57,6 +57,8 @@ Setup_paging: ; Enable long mode and paging ; ; ---------------------------------------------------------------------------- ; Go64: + pusha + ;; Registering paging mov eax, PML4_table mov cr3, eax ; Load PML4 to cr3 @@ -78,5 +80,10 @@ Go64: ; | ; `------ Paging bit mov cr0, eax + jmp .end + nop + nop +.end: + popa ret diff --git a/boot/loader/mem/structures.inc b/boot/loader/mem/structures.inc index 31e98b4..4947b9d 100644 --- a/boot/loader/mem/structures.inc +++ b/boot/loader/mem/structures.inc @@ -26,7 +26,7 @@ [BITS 32] ;; GDT WITH DOC -ALIGN 4 +ALIGN 4096 GDT64: NULL_SELECTOR: ;; null selector within 64 bits dw GDT_LENGTH ; limit of GDT @@ -104,7 +104,7 @@ GDT64: GDT_LENGTH: ;; EMPTY PAGE TABLES (identity of the first 1GiB) -ALIGN 4 +ALIGN 4096 PML4_table: resb 4096 PDP_table: diff --git a/build/obj/boot/loader.bin b/build/obj/boot/loader.bin index faf31098a145ef011cb83636a3ffd826bcb67367..1b1f11896fe51199cc124b80b5c4c94d9415d1f8 100644 GIT binary patch literal 20612 zcmeI)&ntvM7{Kvo7ZGinQ~G>c|EUn^aoJiIm|rsyzk7s@8>p`XMQ8xyxFXI*H2556_NDOL1&Ys zNPKM}FAAeD*f(rMJA`Qmw->$+%>LWhj`Q~pIuvqn??phj&PS>O8A zb`6}ozqn7AS$oqXx>r;6BhQ7=a~#KRFwlJpraF|;VL2NlgQ>orY1Xdji+Q)VJ5xIC zPmZ3b?9NP92EruY=hmZp-5@&A?lJF+lxYYcfB*srAb1#1Tyk7(d2RR7h0vy%IjUGsBx+JGI>6__9khO)rb0QkSsE}8)I*a op*6YN{ETO8Eu-rSCRcOma(S-aC>iMYj`!BT05voAUH||9 delta 140 zcmZo!$oMj8!YNfH0|tf(6Fx9pU;u&t|AEA;^ALJcKa{_IGo!+PeGdkP7fe9u*XcVx z2naAVpI~16fkA*_#|H%{2Pn7`WXKK%1_g%i4|$t`>`s=mAbH2epA0~~rB4p;_`opP UCqSL&@Nrg#25ts_eQ*840IWnXGXMYp From 2c458b81a41e026ea7936302d904c5d98a194e6d Mon Sep 17 00:00:00 2001 From: Adrien Bourmault Date: Tue, 5 Mar 2019 22:50:29 +0100 Subject: [PATCH 10/11] The bug is now fixed. We can focus on the elf loader --- Makefile | 8 ++ boot/loader/cpu/cpu.asm | 46 --------- boot/loader/cpu/cpuid.inc | 4 +- boot/loader/io/ata.asm | 159 -------------------------------- boot/loader/io/lmmem.asm | 43 --------- boot/loader/io/lmterm.asm | 131 -------------------------- boot/loader/loader.asm | 80 ++++++++++++---- boot/loader/mem/management.inc | 19 ++++ boot/loader/mem/structures.inc | 88 +++--------------- boot/loader/multiboot/check.inc | 2 +- build/obj/boot/loader.bin | Bin 20612 -> 23674 bytes 11 files changed, 105 insertions(+), 475 deletions(-) delete mode 100644 boot/loader/cpu/cpu.asm delete mode 100644 boot/loader/io/ata.asm delete mode 100644 boot/loader/io/lmmem.asm delete mode 100644 boot/loader/io/lmterm.asm diff --git a/Makefile b/Makefile index 49bb50e..9568181 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 1b1f11896fe51199cc124b80b5c4c94d9415d1f8..aa061943967b20e5b9d84eddee8eb76d504d6709 100644 GIT binary patch literal 23674 zcmeI)&r1|x7zgm@U6pigneEUis29US1hyFkl~EfA3mtY>BQ?owNv8~S%f{-^LD`E- zu}FvLkWh9g`augu?Jl8P8|_|-=#tRIqQlrkNLFT6)AR0FP=7(u_dPuC^ZuBb*AMS3 z%)wVbQ%p`KbG~P9PLY?0T&bHY%1F>cF#OtE>QTK;@p1bek)*>k5^7G|H@9+s{9&b4 zU#OsgYHAEN1q&7BoHYfva8}8g49eiBo0Fm1r5qnscsK?v`trg0K3yFm8l2}xuI(3j zJ?&d>-AVH;2ei>`f~!7nT2!1nMlQ65M>ZFok^1R=+qQ>M zAOHafKmY;|fB*y_009U<00I#BQ^5JMUySD^X+&PT;oS&M=wSlN&oR+9s3 zoZ&Uk)hbkvDy`Oe>)fwLhBFH9hI-hm`L;+$V9>e7EF;QOdt+~>jOntu>wppK+vj$B zD1!2T3xt}(O)Yx%lSo~Br)S@bp-HZ0#n5N2K8O@?_0g&3L`uGUd$rP7&@&_g6PLoy z4%D+VVpi{ojA`Sl%Zz=q?J@UwQspyWZTsi0Ke@N9y)_@sJY7P>|IhSlp>45Yn*9Fp zcFkAGow1nF-Fr|5o7e4QdX5;#Hq)?z|eez!46dN Z!VXBh&YcvH%YB@cp@EyhU*B8*FaRGOP)q;- From 7a90572f2b32e3ae5ba26a93f24e1014fbc561e7 Mon Sep 17 00:00:00 2001 From: Adrien Bourmault Date: Wed, 6 Mar 2019 20:01:09 +0100 Subject: [PATCH 11/11] Bug fixed stuff --- boot/loader/cpu/cpu.inc | 46 +++++++++++ boot/loader/io/ata.inc | 159 ++++++++++++++++++++++++++++++++++++ boot/loader/io/terminal.inc | 126 ++++++++++++++++++++++++++++ 3 files changed, 331 insertions(+) create mode 100644 boot/loader/cpu/cpu.inc create mode 100644 boot/loader/io/ata.inc create mode 100644 boot/loader/io/terminal.inc diff --git a/boot/loader/cpu/cpu.inc b/boot/loader/cpu/cpu.inc new file mode 100644 index 0000000..b875758 --- /dev/null +++ b/boot/loader/cpu/cpu.inc @@ -0,0 +1,46 @@ +;=----------------------------------------------------------------------------=; +; 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/io/ata.inc b/boot/loader/io/ata.inc new file mode 100644 index 0000000..c37cfc6 --- /dev/null +++ b/boot/loader/io/ata.inc @@ -0,0 +1,159 @@ +;=----------------------------------------------------------------------------=; +; 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/terminal.inc b/boot/loader/io/terminal.inc new file mode 100644 index 0000000..77fcadb --- /dev/null +++ b/boot/loader/io/terminal.inc @@ -0,0 +1,126 @@ +;=----------------------------------------------------------------------------=; +; 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 + +NextTRAM dq 0xB8000 ; Last position of cursor +VGA_HEIGHT64 dq 80 +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