commit
0c9aaec6df
|
@ -11,12 +11,11 @@ test-*.c
|
||||||
*.elf
|
*.elf
|
||||||
*.S
|
*.S
|
||||||
|
|
||||||
|
|
||||||
# Linker output
|
# Linker output
|
||||||
*.ilk
|
*.ilk
|
||||||
*.map
|
*.map
|
||||||
*.exp
|
*.exp
|
||||||
*.bin
|
|
||||||
*.img
|
|
||||||
|
|
||||||
# Precompiled Headers
|
# Precompiled Headers
|
||||||
*.gch
|
*.gch
|
||||||
|
@ -41,6 +40,8 @@ test-*.c
|
||||||
*.i*86
|
*.i*86
|
||||||
*.x86_64
|
*.x86_64
|
||||||
*.hex
|
*.hex
|
||||||
|
*.bin
|
||||||
|
*.img
|
||||||
|
|
||||||
# Debug files
|
# Debug files
|
||||||
*.dSYM/
|
*.dSYM/
|
||||||
|
|
11
Makefile
11
Makefile
|
@ -29,15 +29,16 @@ ASM=nasm
|
||||||
ASMFLAGS=
|
ASMFLAGS=
|
||||||
BOOTFLAGS=-f bin
|
BOOTFLAGS=-f bin
|
||||||
|
|
||||||
BOOTDIR=boot
|
MBRDIR=boot/mbr
|
||||||
|
LOADERDIR=boot/loader
|
||||||
OBJDIR=build/obj
|
OBJDIR=build/obj
|
||||||
BINDIR=build/bin
|
BINDIR=build/bin
|
||||||
|
|
||||||
boot.mbr.asm: $(BOOTDIR)/mbr.asm $(BOOTDIR)/mbr.inc
|
boot.mbr.asm: $(MBRDIR)/mbr.asm $(MBRDIR)/mbr.inc
|
||||||
$(ASM) $(BOOTFLAGS) $(BOOTDIR)/mbr.asm -o $(OBJDIR)/boot/mbr.bin
|
$(ASM) $(BOOTFLAGS) $(MBRDIR)/mbr.asm -o $(OBJDIR)/boot/mbr.bin
|
||||||
|
|
||||||
boot.loader.asm: $(BOOTDIR)/loader.asm
|
boot.loader.asm: $(LOADERDIR)/loader.asm
|
||||||
$(ASM) $(BOOTFLAGS) $(BOOTDIR)/loader.asm -o $(OBJDIR)/boot/loader.bin
|
$(ASM) $(BOOTFLAGS) $(LOADERDIR)/loader.asm -o $(OBJDIR)/boot/loader.bin
|
||||||
|
|
||||||
bootloader: boot.mbr.asm boot.loader.asm
|
bootloader: boot.mbr.asm boot.loader.asm
|
||||||
cp $(OBJDIR)/boot/mbr.bin $(BINDIR)/mbr.bin
|
cp $(OBJDIR)/boot/mbr.bin $(BINDIR)/mbr.bin
|
||||||
|
|
357
boot/loader.asm
357
boot/loader.asm
|
@ -1,357 +0,0 @@
|
||||||
;=----------------------------------------------------------------------------=;
|
|
||||||
; GNU GPL OS/K ;
|
|
||||||
; ;
|
|
||||||
; Authors: spectral` ;
|
|
||||||
; NeoX ;
|
|
||||||
; ;
|
|
||||||
; Desc: Kernel (second stage) Loader for OS/K ;
|
|
||||||
; (x86_64 architecture only) ;
|
|
||||||
;=----------------------------------------------------------------------------=;
|
|
||||||
|
|
||||||
;;VIDEO
|
|
||||||
%define TRAM 0x0B8000 ; [T]ext[RAM]
|
|
||||||
%define VRAM 0x0A0000 ; [V]ideo[RAM]
|
|
||||||
|
|
||||||
;; 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
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[BITS 16]
|
|
||||||
[ORG 0x1000]
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
;; 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:
|
|
||||||
|
|
||||||
%include "boot/loader16.inc"
|
|
||||||
|
|
||||||
main:
|
|
||||||
|
|
||||||
;; compatibility check
|
|
||||||
push si
|
|
||||||
mov si, Init
|
|
||||||
call PrintB
|
|
||||||
pop si
|
|
||||||
call Is64bits
|
|
||||||
jc ErrorNo64
|
|
||||||
push si
|
|
||||||
mov si, Pass
|
|
||||||
call PrintB
|
|
||||||
pop si
|
|
||||||
|
|
||||||
;; Enabling A20
|
|
||||||
push si
|
|
||||||
mov si, EnA20
|
|
||||||
call PrintB
|
|
||||||
pop si
|
|
||||||
in al, 0x92
|
|
||||||
or al, 2
|
|
||||||
out 0x92, al
|
|
||||||
push si
|
|
||||||
mov si, Pass
|
|
||||||
call PrintB
|
|
||||||
pop si
|
|
||||||
|
|
||||||
;; DISABLING CURSOR BLINKING AND GETTING INFOS
|
|
||||||
call get_dimensions
|
|
||||||
call disable_cursor
|
|
||||||
|
|
||||||
;;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
|
|
||||||
|
|
||||||
ErrorNo64:
|
|
||||||
mov si, NoLongMode
|
|
||||||
call PrintB
|
|
||||||
Die:
|
|
||||||
cli
|
|
||||||
hlt ; die nooooow
|
|
||||||
jmp 0xF000:0xFFF0
|
|
||||||
|
|
||||||
[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]
|
|
||||||
|
|
||||||
%include "boot/loader64.inc"
|
|
||||||
|
|
||||||
;; 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
|
|
||||||
ReadAttempt db 0x09, " Attempt to read a sector with ATA commands...", 0x0A, 0x0D, 0x0A, 0x0D,0
|
|
||||||
txt db 0x09, " Switching to Long Mode... ", 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
|
|
||||||
|
|
||||||
NoLongMode db 0x0A, 0x0D, "ERROR : Your computer is not designed for x64 OS", 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"
|
|
||||||
|
|
||||||
Bootdrv db 0
|
|
||||||
UserData dw 0
|
|
||||||
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
|
|
||||||
A20_OK db 0
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
mov rcx, 2
|
|
||||||
.looping:
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
loop .looping ; Temporized because the ATA drive must be ready
|
|
||||||
|
|
||||||
call ata_read
|
|
||||||
|
|
||||||
jmp Die
|
|
||||||
|
|
||||||
; times 1024 nop
|
|
||||||
; XXX ;
|
|
||||||
; It seems impossible to have an executable > 2.0 kB...
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
;=----------------------------------------------------------------------------=;
|
||||||
|
; GNU GPL OS/K ;
|
||||||
|
; ;
|
||||||
|
; Authors: spectral` ;
|
||||||
|
; NeoX ;
|
||||||
|
; ;
|
||||||
|
; Desc: Basic longmode CPU functions ;
|
||||||
|
; (x86_64 architecture only) ;
|
||||||
|
;=----------------------------------------------------------------------------=;
|
||||||
|
|
||||||
|
[BITS 64]
|
||||||
|
|
||||||
|
temporize:
|
||||||
|
push rcx
|
||||||
|
mov rcx, 2000
|
||||||
|
.looping:
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
loop .looping
|
||||||
|
pop rcx
|
||||||
|
ret
|
|
@ -0,0 +1,50 @@
|
||||||
|
;=----------------------------------------------------------------------------=;
|
||||||
|
; GNU GPL OS/K ;
|
||||||
|
; ;
|
||||||
|
; Authors: spectral` ;
|
||||||
|
; NeoX ;
|
||||||
|
; ;
|
||||||
|
; Desc: Basic realmode CPU Detection ;
|
||||||
|
; (x86_64 architecture only) ;
|
||||||
|
;=----------------------------------------------------------------------------=;
|
||||||
|
|
||||||
|
[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
|
|
@ -7,4 +7,4 @@
|
||||||
// Desc: ELF64 Parser and Loader //
|
// Desc: ELF64 Parser and Loader //
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
//STUB
|
int stub;
|
|
@ -0,0 +1,18 @@
|
||||||
|
;=----------------------------------------------------------------------------=;
|
||||||
|
; GNU GPL OS/K ;
|
||||||
|
; ;
|
||||||
|
; Authors: spectral` ;
|
||||||
|
; NeoX ;
|
||||||
|
; ;
|
||||||
|
; Desc: Basic File Allocation Table Long mode Driver ;
|
||||||
|
; (x86_64 architecture only) ;
|
||||||
|
;=----------------------------------------------------------------------------=;
|
||||||
|
|
||||||
|
[BITS 64]
|
||||||
|
|
||||||
|
;; GLOBAL DATA
|
||||||
|
UserData dw 0
|
||||||
|
|
||||||
|
;; TEXT
|
||||||
|
|
||||||
|
nop
|
|
@ -0,0 +1,138 @@
|
||||||
|
;=----------------------------------------------------------------------------=;
|
||||||
|
; GNU GPL OS/K ;
|
||||||
|
; ;
|
||||||
|
; Authors: spectral` ;
|
||||||
|
; NeoX ;
|
||||||
|
; ;
|
||||||
|
; Desc: Basic Read Only ATA Long mode Driver ;
|
||||||
|
; (x86_64 architecture only) ;
|
||||||
|
;=----------------------------------------------------------------------------=;
|
||||||
|
|
||||||
|
[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
|
||||||
|
end db "[End of Sector]", 0x0
|
||||||
|
buffer: times 513 db "_"
|
||||||
|
|
||||||
|
;; TEXT
|
||||||
|
|
||||||
|
ata_read:
|
||||||
|
;-----------------------------------------------------------------------;
|
||||||
|
; x64/LM ATA Reading function ;
|
||||||
|
; ;
|
||||||
|
; ;
|
||||||
|
;-----------------------------------------------------------------------;
|
||||||
|
|
||||||
|
; 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 rdx
|
||||||
|
push rcx
|
||||||
|
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, 1 ; Read one sector
|
||||||
|
out dx, al
|
||||||
|
|
||||||
|
mov dx, 0x1f3 ; Sector number port
|
||||||
|
mov al, 1 ; Read sector one
|
||||||
|
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, buffer
|
||||||
|
mov dx, 0x1f0 ; Data port - data comes in and out of here.
|
||||||
|
rep insw
|
||||||
|
pop rdi
|
||||||
|
pop rcx
|
||||||
|
pop rdx
|
||||||
|
pop rbx
|
||||||
|
pop rax
|
||||||
|
mov bl, 0x0F
|
||||||
|
mov esi, buffer
|
||||||
|
call dump
|
||||||
|
mov bl, 0x0A
|
||||||
|
mov esi, end
|
||||||
|
call write
|
||||||
|
ret
|
|
@ -0,0 +1,28 @@
|
||||||
|
;=----------------------------------------------------------------------------=;
|
||||||
|
; GNU GPL OS/K ;
|
||||||
|
; ;
|
||||||
|
; Authors: spectral` ;
|
||||||
|
; NeoX ;
|
||||||
|
; ;
|
||||||
|
; Desc: Basic Memory Long mode Functions ;
|
||||||
|
; (x86_64 architecture only) ;
|
||||||
|
;=----------------------------------------------------------------------------=;
|
||||||
|
[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
|
|
@ -0,0 +1,116 @@
|
||||||
|
;=----------------------------------------------------------------------------=;
|
||||||
|
; GNU GPL OS/K ;
|
||||||
|
; ;
|
||||||
|
; Authors: spectral` ;
|
||||||
|
; NeoX ;
|
||||||
|
; ;
|
||||||
|
; Desc: Basic Colored VGA Terminal Long mode Driver ;
|
||||||
|
; (x86_64 architecture only) ;
|
||||||
|
;=----------------------------------------------------------------------------=;
|
||||||
|
|
||||||
|
;;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 Printing Functions ;
|
||||||
|
; bl : color code ;
|
||||||
|
; esi : string 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
|
||||||
|
add qword [NextTRAM], 0x2 ; Cursor moving
|
||||||
|
add qword [VGA_X], 0x2 ; coord + 2 because 2 subpixels
|
||||||
|
loop .pLoop
|
||||||
|
pop rcx
|
||||||
|
pop rdi
|
||||||
|
pop rsi
|
||||||
|
ret
|
|
@ -0,0 +1,98 @@
|
||||||
|
;=----------------------------------------------------------------------------=;
|
||||||
|
; GNU GPL OS/K ;
|
||||||
|
; ;
|
||||||
|
; Authors: spectral` ;
|
||||||
|
; NeoX ;
|
||||||
|
; ;
|
||||||
|
; Desc: Basic Memory Realmode Driver ;
|
||||||
|
; (x86_64 architecture only) ;
|
||||||
|
;=----------------------------------------------------------------------------=;
|
||||||
|
|
||||||
|
[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
|
|
@ -4,7 +4,7 @@
|
||||||
; Authors: spectral` ;
|
; Authors: spectral` ;
|
||||||
; NeoX ;
|
; NeoX ;
|
||||||
; ;
|
; ;
|
||||||
; Desc: Kernel (second stage) Loader for OS/K INCLUDED FUNCTIONS ;
|
; Desc: Basic realmode terminal functions ;
|
||||||
; (x86_64 architecture only) ;
|
; (x86_64 architecture only) ;
|
||||||
;=----------------------------------------------------------------------------=;
|
;=----------------------------------------------------------------------------=;
|
||||||
|
|
||||||
|
@ -36,40 +36,6 @@ get_dimensions:
|
||||||
pop eax
|
pop eax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
PrintB:
|
PrintB:
|
||||||
;---------------------------------------------------;
|
;---------------------------------------------------;
|
||||||
; Print out a simple string. ;
|
; Print out a simple string. ;
|
|
@ -0,0 +1,233 @@
|
||||||
|
;=----------------------------------------------------------------------------=;
|
||||||
|
; GNU GPL OS/K ;
|
||||||
|
; ;
|
||||||
|
; Authors: spectral` ;
|
||||||
|
; NeoX ;
|
||||||
|
; ;
|
||||||
|
; Desc: Kernel (second stage) Loader for OS/K ;
|
||||||
|
; (x86_64 architecture only) ;
|
||||||
|
;=----------------------------------------------------------------------------=;
|
||||||
|
|
||||||
|
[BITS 16]
|
||||||
|
[ORG 0x1000]
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
%include "boot/loader/cpu/cpuid.asm"
|
||||||
|
%include "boot/loader/io/rmterm.asm"
|
||||||
|
%include "boot/loader/io/rmmem.asm"
|
||||||
|
|
||||||
|
main:
|
||||||
|
|
||||||
|
;; compatibility check
|
||||||
|
push si
|
||||||
|
mov si, Init
|
||||||
|
call PrintB
|
||||||
|
pop si
|
||||||
|
|
||||||
|
call Is64bits
|
||||||
|
|
||||||
|
jc ErrorNo64
|
||||||
|
push si
|
||||||
|
mov si, Pass
|
||||||
|
call PrintB
|
||||||
|
pop si
|
||||||
|
|
||||||
|
;; Enabling A20
|
||||||
|
push si
|
||||||
|
mov si, EnA20
|
||||||
|
call PrintB
|
||||||
|
pop si
|
||||||
|
|
||||||
|
call set_a20
|
||||||
|
|
||||||
|
push si
|
||||||
|
mov si, Pass
|
||||||
|
call PrintB
|
||||||
|
pop si
|
||||||
|
|
||||||
|
;; DISABLING CURSOR BLINKING AND GETTING INFOS
|
||||||
|
call get_dimensions
|
||||||
|
call disable_cursor
|
||||||
|
|
||||||
|
;;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
|
||||||
|
|
||||||
|
;; THE HOLE ----------------------------------------------------------------- ;;
|
||||||
|
ErrorNo64:
|
||||||
|
mov si, NoLongMode
|
||||||
|
call PrintB
|
||||||
|
Die:
|
||||||
|
cli
|
||||||
|
hlt ; die nooooow
|
||||||
|
jmp 0xF000:0xFFF0
|
||||||
|
;; 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
|
||||||
|
ReadAttempt db 0x09, " Attempt to read a sector with ATA commands...", 0x0A, 0x0D, 0x0A, 0x0D,0
|
||||||
|
txt db 0x09, " Switching to Long Mode... ", 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
|
||||||
|
call ata_read
|
||||||
|
|
||||||
|
jmp Die
|
||||||
|
|
||||||
|
; times 1024 nop
|
||||||
|
; XXX ;
|
||||||
|
; It seems impossible to have an executable > 2.0 kB...
|
|
@ -1,200 +0,0 @@
|
||||||
;=----------------------------------------------------------------------------=;
|
|
||||||
; GNU GPL OS/K ;
|
|
||||||
; ;
|
|
||||||
; Authors: spectral` ;
|
|
||||||
; NeoX ;
|
|
||||||
; ;
|
|
||||||
; Desc: Kernel (second stage) Loader for OS/K INCLUDED FUNCTIONS ;
|
|
||||||
; (x86_64 architecture only) ;
|
|
||||||
;=----------------------------------------------------------------------------=;
|
|
||||||
|
|
||||||
[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 Printing Functions ;
|
|
||||||
; bl : color code ;
|
|
||||||
; esi : string 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
|
|
||||||
add qword [NextTRAM], 0x2 ; Cursor moving
|
|
||||||
add qword [VGA_X], 0x2 ; coord + 2 because 2 subpixels
|
|
||||||
loop .pLoop
|
|
||||||
pop rcx
|
|
||||||
pop rdi
|
|
||||||
pop rsi
|
|
||||||
ret
|
|
||||||
|
|
||||||
ata_read:
|
|
||||||
;-----------------------------------------------------------------------;
|
|
||||||
; x64/LM ATA Reading function ;
|
|
||||||
; ;
|
|
||||||
; ;
|
|
||||||
;-----------------------------------------------------------------------;
|
|
||||||
|
|
||||||
; 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 rdx
|
|
||||||
push rcx
|
|
||||||
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, 1 ;Read one sector
|
|
||||||
out dx, al
|
|
||||||
|
|
||||||
mov dx, 0x1f3 ;Sector number port
|
|
||||||
mov al, 1 ;Read sector one
|
|
||||||
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, 20 ;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
|
|
||||||
mov rdi, buffer
|
|
||||||
mov dx, 0x1f0 ;Data port - data comes in and out of here.
|
|
||||||
rep insw
|
|
||||||
pop rdi
|
|
||||||
pop rcx
|
|
||||||
pop rdx
|
|
||||||
pop rbx
|
|
||||||
pop rax
|
|
||||||
mov bl, 0x0F
|
|
||||||
mov esi, buffer
|
|
||||||
call dump
|
|
||||||
mov bl, 0x0A
|
|
||||||
mov esi, end
|
|
||||||
call write
|
|
||||||
ret
|
|
||||||
|
|
||||||
buffer: times 512 db "_"
|
|
||||||
end: db "[End of Sector]", 0x0
|
|
|
@ -59,11 +59,11 @@ BPB:
|
||||||
;; ENTRY POINT
|
;; ENTRY POINT
|
||||||
_start:
|
_start:
|
||||||
jmp BOOT_SEG:$+5 ; Fix the cs:ip registers with a vaudou magical trip
|
jmp BOOT_SEG:$+5 ; Fix the cs:ip registers with a vaudou magical trip
|
||||||
|
|
||||||
bootstrap:
|
bootstrap:
|
||||||
jmp go
|
jmp go
|
||||||
|
|
||||||
;; LOVELY DATA
|
;; LOVELY DATA
|
||||||
FileNotFound db "First Stage ERROR : NO LOADER", 0
|
FileNotFound db "First Stage ERROR : NO LOADER", 0
|
||||||
DiskError db "First Stage ERROR : DISK", 0
|
DiskError db "First Stage ERROR : DISK", 0
|
||||||
UserData dw 0
|
UserData dw 0
|
||||||
|
@ -84,7 +84,7 @@ go:
|
||||||
mov sp, STACK_OFF ; Ok man, the stack is in 4K :O
|
mov sp, STACK_OFF ; Ok man, the stack is in 4K :O
|
||||||
sti
|
sti
|
||||||
mov bp, (0x7c0-STACK_SEG) << 4 ; Correct bp (the disk description table)
|
mov bp, (0x7c0-STACK_SEG) << 4 ; Correct bp (the disk description table)
|
||||||
|
|
||||||
;; INITIALIZE BOOT DISK
|
;; INITIALIZE BOOT DISK
|
||||||
or dl, dl ; Verifying dl points actually to the boot drive
|
or dl, dl ; Verifying dl points actually to the boot drive
|
||||||
jz load_root
|
jz load_root
|
||||||
|
@ -113,7 +113,7 @@ load_root:
|
||||||
add ax, word [reservedSectors] ; increase ax by the reserved sectors
|
add ax, word [reservedSectors] ; increase ax by the reserved sectors
|
||||||
mov word [UserData], ax ; Start of user data = startOfRoot + numberOfRoot
|
mov word [UserData], ax ; Start of user data = startOfRoot + numberOfRoot
|
||||||
add word [UserData], cx ; Add the size and location of the root directory
|
add word [UserData], cx ; Add the size and location of the root directory
|
||||||
|
|
||||||
mov di, BUFFER_SEG ; Set the extra segment to the disk buffer
|
mov di, BUFFER_SEG ; Set the extra segment to the disk buffer
|
||||||
mov es, di
|
mov es, di
|
||||||
mov di, BUFFER_OFF ; Set es:di and load the root directory into the disk buffer
|
mov di, BUFFER_OFF ; Set es:di and load the root directory into the disk buffer
|
||||||
|
@ -134,14 +134,14 @@ search_root:
|
||||||
add di, ax ; Add the offset to point to the next entry
|
add di, ax ; Add the offset to point to the next entry
|
||||||
xchg dx, cx
|
xchg dx, cx
|
||||||
loop search_root ; Continue to search for the file
|
loop search_root ; Continue to search for the file
|
||||||
|
|
||||||
;; ERROR...
|
;; ERROR...
|
||||||
mov si, FileNotFound ; Could not find the file
|
mov si, FileNotFound ; Could not find the file
|
||||||
call print
|
call print
|
||||||
call reboot
|
call reboot
|
||||||
|
|
||||||
;; LOAD THE FAT FROM THE FILE
|
;; LOAD THE FAT FROM THE FILE
|
||||||
load_fat:
|
load_fat:
|
||||||
mov ax, word [es:di + 15] ; Get the file cluster at offset 26
|
mov ax, word [es:di + 15] ; Get the file cluster at offset 26
|
||||||
push ax ; Store the FAT cluster
|
push ax ; Store the FAT cluster
|
||||||
xor ax, ax ; Size of fat = (fats * fatSectors)
|
xor ax, ax ; Size of fat = (fats * fatSectors)
|
||||||
|
@ -168,7 +168,7 @@ load_fat:
|
||||||
; ...
|
; ...
|
||||||
call reboot
|
call reboot
|
||||||
|
|
||||||
%include "boot/mbr.inc"
|
%include "boot/mbr/mbr.inc"
|
||||||
|
|
||||||
;; END
|
;; END
|
||||||
times 510 - ($ - $$) db 0 ; Pad remainder of boot sector with zeros
|
times 510 - ($ - $$) db 0 ; Pad remainder of boot sector with zeros
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue