Skip to content
Snippets Groups Projects
Commit fb3c98b5 authored by Bensong Liu's avatar Bensong Liu
Browse files

64bit kernel prepared

parent 6b3032f6
No related branches found
No related tags found
1 merge request!2X64 MBR mode done.
...@@ -26,7 +26,7 @@ Just used this mode to launch 64bit long mode. No paging enabled. ...@@ -26,7 +26,7 @@ Just used this mode to launch 64bit long mode. No paging enabled.
- 64bit long mode age - 64bit long mode age
0x1000 - 0x5000 : 64bit long mode paging table**s** 0x1000 - 0x5000 : 64bit long mode paging table**s**
0x00100000 - 0x00300000 : 512 * 4K pages, before kernel initializing page table in C++. 0x00000000 - 0x00200000 : 512 * 4K pages, before the kernel initializing page table in C++.
## bootloader(legacy) disk model ## bootloader(legacy) disk model
......
...@@ -106,7 +106,6 @@ _prot_begin: ...@@ -106,7 +106,6 @@ _prot_begin:
je _test_passed je _test_passed
mov ebx, _motd_no_long_mode mov ebx, _motd_no_long_mode
call println_vga call println_vga
jmp _stall ; debug, tmp
jmp _call_kern_32 jmp _call_kern_32
_test_passed: _test_passed:
...@@ -140,17 +139,20 @@ _stall: ...@@ -140,17 +139,20 @@ _stall:
jmp $ jmp $
_motd_disk_error: _motd_disk_error:
db 'DISK_IO_ERROR', 0x0 db 'MED', 0x0
_motd_32: _motd_32:
db '[LOAD KERN SUCC] [ENTER X86 MODE SUCC]', 0x0 db 'M32', 0x0
_motd_kern_ok: _motd_kern_ok:
db '[LOAD KERN SUCC]', 0x0 db 'MKN', 0x0
_motd_endk: _motd_endk:
db '[LOAD KERN SUCC] [ENTER X86 MODE SUCC] [KERN EXITED]', 0x0 db 'MEK', 0x0
_motd_no_long_mode: _motd_no_long_mode:
db '[ENTER LONG MODE ERR] NOT_SUPPORTED', 0x0 db 'MNL', 0x0
_boot_drive_id: _boot_drive_id:
db 0x0 db 0x0
_motd_debug_point:
db 'MDB', 0x0
%include "./mbr_end.inc" %include "./mbr_end.inc"
......
...@@ -2,38 +2,38 @@ ...@@ -2,38 +2,38 @@
; requires: str.32.inc ; requires: str.32.inc
; runs in 32bit protection mode ; runs in 32bit protection mode
test_cpuid_support: ;test_cpuid_support:
; Check if CPUID is supported by attempting to flip the ID bit (bit 21) in ; ; Check if CPUID is supported by attempting to flip the ID bit (bit 21) in
; the FLAGS register. If we can flip it, CPUID is available. ; ; the FLAGS register. If we can flip it, CPUID is available.
;
; Copy FLAGS in to EAX via stack ; ; Copy FLAGS in to EAX via stack
pushfd ; pushfd
pop eax ; pop eax
;
; Copy to ECX as well for comparing later on ; ; Copy to ECX as well for comparing later on
mov ecx, eax ; mov ecx, eax
;
; Flip the ID bit ; ; Flip the ID bit
xor eax, 1 << 21 ; xor eax, 1 << 21
;
; Copy EAX to FLAGS via the stack ; ; Copy EAX to FLAGS via the stack
push eax ; push eax
popfd ; popfd
;
; Copy FLAGS back to EAX (with the flipped bit if CPUID is supported) ; ; Copy FLAGS back to EAX (with the flipped bit if CPUID is supported)
pushfd ; pushfd
pop eax ; pop eax
;
; Restore FLAGS from the old version stored in ECX (i.e. flipping the ID bit ; ; Restore FLAGS from the old version stored in ECX (i.e. flipping the ID bit
; back if it was ever flipped). ; ; back if it was ever flipped).
push ecx ; push ecx
popfd ; popfd
;
; Compare EAX and ECX. If they are equal then that means the bit wasn't ; ; Compare EAX and ECX. If they are equal then that means the bit wasn't
; flipped, and CPUID isn't supported. ; ; flipped, and CPUID isn't supported.
sub eax, ecx ; sub eax, ecx
; eax != 0 if CPUID supported, eax==0 if not supported. ; ; eax != 0 if CPUID supported, eax==0 if not supported.
ret ; ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
...@@ -41,12 +41,12 @@ test_support_long_mode: ...@@ -41,12 +41,12 @@ test_support_long_mode:
; test if possible to enter x64 mode. ; test if possible to enter x64 mode.
; return value in eax. ; return value in eax.
; return 0 = OK. 1 = CPUID_NOT_AVAIL, 2 = CPUID_EXT_NOT_AVAIL, 3 = LONGMODE_NOT_AVAIL ; return 0 = OK. 1 = CPUID_NOT_AVAIL, 2 = CPUID_EXT_NOT_AVAIL, 3 = LONGMODE_NOT_AVAIL
call test_cpuid_support ; call test_cpuid_support
cmp eax, 0 ; cmp eax, 0
jne _cpuid_supported ; jne _cpuid_supported
mov eax, 1 ; mov eax, 1
ret ; ret
_cpuid_supported: ;_cpuid_supported:
mov eax, 0x80000000 ; Set the A-register to 0x80000000. mov eax, 0x80000000 ; Set the A-register to 0x80000000.
cpuid ; CPU identification. cpuid ; CPU identification.
cmp eax, 0x80000001 ; Compare the A-register with 0x80000001. cmp eax, 0x80000001 ; Compare the A-register with 0x80000001.
...@@ -118,8 +118,8 @@ inline_enter_long_mode: ...@@ -118,8 +118,8 @@ inline_enter_long_mode:
mov edi, 0x4000 mov edi, 0x4000
; fill all entries of the PT. This is a trick, which not setting all bits in entry. ; fill all entries of the PT. This is a trick, which not setting all bits in entry.
; This page table has 512 4K page, 0x00100000 - 0x00300000. ; This page table has 512 4K page, 0x00000000 - 0x00200000.
mov ebx, 0x00100003 ; BIT M--12 contains PageFrameNumber. mov ebx, 0x00000003 ; BIT M--12 contains PageFrameNumber.
mov ecx, 512 ; counter mov ecx, 512 ; counter
_set_one_entry: _set_one_entry:
mov DWORD [edi], ebx mov DWORD [edi], ebx
...@@ -142,6 +142,7 @@ _set_one_entry: ...@@ -142,6 +142,7 @@ _set_one_entry:
or eax, 1 << 31 ; Set the PG-bit, which is the 32nd bit (bit 31). or eax, 1 << 31 ; Set the PG-bit, which is the 32nd bit (bit 31).
mov cr0, eax ; Set control register 0 to the A-register. mov cr0, eax ; Set control register 0 to the A-register.
;;;;;;;;;;;;;;;;; Section 3: enter 64bit long mode ;;;;;;;;;;;;;;;;; Section 3: enter 64bit long mode
lgdt [GDT64.Pointer] ; Load the 64-bit global descriptor table. lgdt [GDT64.Pointer] ; Load the 64-bit global descriptor table.
jmp GDT64.Code:Realm64 ; Set the code segment and enter 64-bit long mode. jmp GDT64.Code:Realm64 ; Set the code segment and enter 64-bit long mode.
...@@ -157,6 +158,8 @@ Realm64: ...@@ -157,6 +158,8 @@ Realm64:
mov gs, ax ; Set the G-segment to the A-register. mov gs, ax ; Set the G-segment to the A-register.
mov ss, ax ; Set the stack segment to the A-register. mov ss, ax ; Set the stack segment to the A-register.
; done ; done
; 32bit print_vga not working in 64bit mode
......
# BITS could be 32 or 64.
BITS ?= 64
ifeq ($(BITS), 64)
ARCH = x86_64
else
ARCH = i386
endif
assemble: kernel head assemble: kernel head
ld -o kernel.img -Ttext 0x7e00 --oformat binary image_head.o kernel.o -m elf_i386 ld -o kernel.img -Ttext 0x7e00 --oformat binary image_head.o kernel.o -m elf_$(ARCH)
# Sector 1 = bootloader, Sector 2 - (512B TO 64K) = kernel # Sector 1 = bootloader, Sector 2 - (512B TO 64K) = kernel
# Extend kernel.img to correct size. # Extend kernel.img to correct size.
test $$(stat -c %s kernel.img) -le 65024 test $$(stat -c %s kernel.img) -le 65024
truncate --size=65024 kernel.img truncate --size=65024 kernel.img
head: head:
nasm -f elf image_head.asm -o image_head.o nasm -f elf -DBITS=$(BITS) image_head.asm -o image_head.o
kernel: kernel:
g++ -ffreestanding -fno-pie -c kernel.cc -o kernel.o -m32 -std=c++17 g++ -ffreestanding -fno-pie -c kernel.cc -o kernel.o -m$(BITS) -std=c++17
kernel_x64:
g++ -ffreestanding -fno-pie -c kernel.cc -o kernel.o -m64 -std=c++17
clean: clean:
rm *.o *.img rm *.o *.img
......
[bits 64]
[extern main]
call main
ret
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment