Skip to content

Instantly share code, notes, and snippets.

@Wazzaps
Last active April 10, 2019 21:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Wazzaps/36f8ab629f043856eae6a10aa46fe851 to your computer and use it in GitHub Desktop.
Save Wazzaps/36f8ab629f043856eae6a10aa46fe851 to your computer and use it in GitHub Desktop.
x86_64 boot problems :)
check_exception old: 0xffffffff new 0xe
0: v=0e e=0000 i=0 cpl=0 IP=0010:00000000004000a6 pc=00000000004000a6 SP=0018:000000000040f000 CR2=00000000004000a6
EAX=80000011 EBX=00100400 ECX=c0000080 EDX=00000000
ESI=00000001 EDI=00000000 EBP=00000000 ESP=0040f000
EIP=004000a6 EFL=00000006 [-----P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
CS =0010 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
DS =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
FS =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
GS =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT= 00000000000010b0 00000020
IDT= 0000000000000000 00000000
CR0=80000011 CR2=00000000004000a6 CR3=0000000000406000 CR4=00000020
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=00000001 CCD=00000100 CCO=LOGICL
EFER=0000000000000500
check_exception old: 0xe new 0xd
1: v=08 e=0000 i=0 cpl=0 IP=0010:00000000004000a6 pc=00000000004000a6 SP=0018:000000000040f000 env->regs[R_EAX]=0000000080000011
EAX=80000011 EBX=00100400 ECX=c0000080 EDX=00000000
ESI=00000001 EDI=00000000 EBP=00000000 ESP=0040f000
EIP=004000a6 EFL=00000006 [-----P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
CS =0010 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
DS =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
FS =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
GS =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT= 00000000000010b0 00000020
IDT= 0000000000000000 00000000
CR0=80000011 CR2=00000000004000a6 CR3=0000000000406000 CR4=00000020
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=00000001 CCD=00000100 CCO=LOGICL
EFER=0000000000000500
check_exception old: 0x8 new 0xd
SMM: enter
EAX=00000001 EBX=0000000b ECX=02000000 EDX=02000628
ESI=00000000 EDI=02000000 EBP=00000007 ESP=00006d78
EIP=000ee460 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
CS =0008 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT= 000f7080 00000037
IDT= 000f70be 00000000
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=00000080 CCD=00000001 CCO=LOGICB
EFER=0000000000000000
// Taken from http://ringzeroandlower.com/2017/08/08/x86-64-kernel-boot.html
#include "arch/x86_64/gdt.h"
#include "arch/x86_64/mmu.h"
#include "arch/x86_64/msr.h"
#include "arch/x86_64/kernel.h"
#include "arch/x86_64/sizes.h"
#include "arch/x86_64/multiboot2.h"
.set HEADER_LENGTH, header_end - header_start
.set CHECKSUM, -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE_I386 + HEADER_LENGTH)
.section .multiboot, "ax"
header_start:
.long MULTIBOOT2_HEADER_MAGIC
.long MULTIBOOT_ARCHITECTURE_I386
.long HEADER_LENGTH
.long CHECKSUM
// multiboot tags go here
.short MULTIBOOT_HEADER_TAG_END
.short 0 // flags, none set
.long 8 // size, including itself (short + short + long)
header_end:
.code32
.section .bss
.comm pml4, PML4_SIZE, PML4_ALIGNMENT
.comm low_pdpt, PDPT_SIZE, PDPT_ALIGNMENT
.comm high_pdpt, PDPT_SIZE, PDPT_ALIGNMENT
.comm low_page_directory_table, PAGE_DIRECTORY_SIZE, PAGE_DIRECTORY_ALIGNMENT
.comm high_page_directory_table, PAGE_DIRECTORY_SIZE, PAGE_DIRECTORY_ALIGNMENT
.comm tmp_stack, KERNEL_BOOT_STACK_SIZE, KERNEL_BOOT_STACK_ALIGNMENT
.data
.align GDT_TABLE_ALIGNMENT
gdt_table:
.8byte GDT_FIRST_ENTRY
.8byte GDT_KERNEL_ENTRY
gdt_table_end:
.skip (GDT_TABLE_SIZE - (gdt_table_end - gdt_table))
gdt_ptr:
.short GDT_TABLE_SIZE - 1
.long gdt_table
.section .text, "ax"
.global _start
.type _start, @function
_start:
movl $tmp_stack + KERNEL_BOOT_STACK_SIZE, %esp
movl $low_pdpt, %eax
or $(MMU_PRESENT | MMU_WRITABLE), %eax
movl %eax, pml4 + (PML4_ADDR_TO_ENTRY_INDEX(KERNEL_PHYSICAL_START) * PML4_ENTRY_SIZE)
movl $high_pdpt, %eax
or $(MMU_PRESENT | MMU_WRITABLE), %eax
movl %eax, pml4 + (PML4_ADDR_TO_ENTRY_INDEX(KERNEL_VIRTUAL_START) * PML4_ENTRY_SIZE)
movl $low_page_directory_table, %eax
or $(MMU_PRESENT | MMU_WRITABLE), %eax
movl %eax, low_pdpt + (PDPT_ADDR_TO_ENTRY_INDEX(KERNEL_PHYSICAL_START) * PDPT_ENTRY_SIZE)
movl $high_page_directory_table, %eax
or $(MMU_PRESENT | MMU_WRITABLE), %eax
movl %eax, high_pdpt + (PDPT_ADDR_TO_ENTRY_INDEX(KERNEL_VIRTUAL_START) * PDPT_ENTRY_SIZE)
mov $0, %ecx
movl $_kernel_physical_end, %esi
shrl $TWO_MEGABYTES_SHIFT, %esi
addl $1, %esi
page_directory_table_loop:
movl $TWO_MEGABYTES, %eax
mul %ecx
or $(MMU_PRESENT | MMU_WRITABLE | MMU_PDE_TWO_MB), %eax
movl %eax, low_page_directory_table(, %ecx, PAGE_DIRECTORY_ENTRY_SIZE)
movl %eax, high_page_directory_table(, %ecx, PAGE_DIRECTORY_ENTRY_SIZE)
inc %ecx
cmp %esi, %ecx
jne page_directory_table_loop // if not equal redo loop
movl $pml4, %eax
movl %eax, %cr3
movl $KERNEL_CR4, %eax
movl %eax, %cr4
movl $MSR_EFER, %ecx
rdmsr
or $MSR_EFER_LME, %eax
wrmsr
movl $KERNEL_CR0, %eax
// This is the last place that hangs and doesn't bootloop
// 1:
// jmp 1b
movl %eax, %cr0 // <-------- crash
lgdt gdt_ptr
ljmp $(KERNEL_GDT_ENTRY * GDT_ENTRY_SIZE), $_start64
cli
hlt
.code64
.global _start64
.type _start64, @function
_start64:
// Setup segment selectors
movw $0, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movw %ax, %ss
call kernel_main
// Should never reach here
cli
hlt
1:
jmp 1b
(qemu) info registers
EAX=80000011 EBX=00100400 ECX=c0000080 EDX=00000000
ESI=00000001 EDI=00000000 EBP=00000000 ESP=0040f000
EIP=004000a3 EFL=00000006 [-----P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
CS =0010 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
DS =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
FS =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
GS =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT= 000010b0 00000020
IDT= 00000000 00000000
CR0=00000011 CR2=00000000 CR3=00406000 CR4=00000020
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
EFER=0000000000000100
FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000
XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000
XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000
XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000
(qemu) x/64x 0x406000
0000000000406000: 0x00405003 0x00000000 0x00000000 0x00000000
0000000000406010: 0x00000000 0x00000000 0x00000000 0x00000000
0000000000406020: 0x00000000 0x00000000 0x00000000 0x00000000
0000000000406030: 0x00000000 0x00000000 0x00000000 0x00000000
0000000000406040: 0x00000000 0x00000000 0x00000000 0x00000000
0000000000406050: 0x00000000 0x00000000 0x00000000 0x00000000
0000000000406060: 0x00000000 0x00000000 0x00000000 0x00000000
0000000000406070: 0x00000000 0x00000000 0x00000000 0x00000000
0000000000406080: 0x00000000 0x00000000 0x00000000 0x00000000
0000000000406090: 0x00000000 0x00000000 0x00000000 0x00000000
00000000004060a0: 0x00000000 0x00000000 0x00000000 0x00000000
00000000004060b0: 0x00000000 0x00000000 0x00000000 0x00000000
00000000004060c0: 0x00000000 0x00000000 0x00000000 0x00000000
00000000004060d0: 0x00000000 0x00000000 0x00000000 0x00000000
00000000004060e0: 0x00000000 0x00000000 0x00000000 0x00000000
00000000004060f0: 0x00000000 0x00000000 0x00000000 0x00000000
(qemu) x/64x 0x405000
0000000000405000: 0x00404003 0x00000000 0x00000000 0x00000000
0000000000405010: 0x00000000 0x00000000 0x00000000 0x00000000
0000000000405020: 0x00000000 0x00000000 0x00000000 0x00000000
0000000000405030: 0x00000000 0x00000000 0x00000000 0x00000000
0000000000405040: 0x00000000 0x00000000 0x00000000 0x00000000
0000000000405050: 0x00000000 0x00000000 0x00000000 0x00000000
0000000000405060: 0x00000000 0x00000000 0x00000000 0x00000000
0000000000405070: 0x00000000 0x00000000 0x00000000 0x00000000
0000000000405080: 0x00000000 0x00000000 0x00000000 0x00000000
0000000000405090: 0x00000000 0x00000000 0x00000000 0x00000000
00000000004050a0: 0x00000000 0x00000000 0x00000000 0x00000000
00000000004050b0: 0x00000000 0x00000000 0x00000000 0x00000000
00000000004050c0: 0x00000000 0x00000000 0x00000000 0x00000000
00000000004050d0: 0x00000000 0x00000000 0x00000000 0x00000000
00000000004050e0: 0x00000000 0x00000000 0x00000000 0x00000000
00000000004050f0: 0x00000000 0x00000000 0x00000000 0x00000000
(qemu) x/64x 0x404000
0000000000404000: 0x00000083 0x00000000 0x00000000 0x00000000
0000000000404010: 0x00000000 0x00000000 0x00000000 0x00000000
0000000000404020: 0x00000000 0x00000000 0x00000000 0x00000000
0000000000404030: 0x00000000 0x00000000 0x00000000 0x00000000
0000000000404040: 0x00000000 0x00000000 0x00000000 0x00000000
0000000000404050: 0x00000000 0x00000000 0x00000000 0x00000000
0000000000404060: 0x00000000 0x00000000 0x00000000 0x00000000
0000000000404070: 0x00000000 0x00000000 0x00000000 0x00000000
0000000000404080: 0x00000000 0x00000000 0x00000000 0x00000000
0000000000404090: 0x00000000 0x00000000 0x00000000 0x00000000
00000000004040a0: 0x00000000 0x00000000 0x00000000 0x00000000
00000000004040b0: 0x00000000 0x00000000 0x00000000 0x00000000
00000000004040c0: 0x00000000 0x00000000 0x00000000 0x00000000
00000000004040d0: 0x00000000 0x00000000 0x00000000 0x00000000
00000000004040e0: 0x00000000 0x00000000 0x00000000 0x00000000
00000000004040f0: 0x00000000 0x00000000 0x00000000 0x00000000
#pragma once
#include "arch/x86_64/control_register.h"
// START macros must have the same value in the kernel linker script
#define KERNEL_PHYSICAL_START 0x0000000000400000
#define KERNEL_VIRTUAL_START 0xFFFFFFFF80400000
#define KERNEL_GDT_ENTRY 1
#define KERNEL_CR0 \
( \
CONTROL_REGISTER0_PAGE | \
CONTROL_REGISTER0_PROTECTED_MODE_ENABLED | \
CONTROL_REGISTER0_EXTENSION_TYPE \
)
#define KERNEL_CR4 (CONTROL_REGISTER4_PHYSICAL_ADDRESS_EXTENSION)
#define KERNEL_BOOT_STACK_SIZE 0x8000
#define KERNEL_BOOT_STACK_ALIGNMENT 0x1000
COMMON_FLAGS=-target x86_64-pc-none-elf -O2 -march=x86-64 -Iinclude -mcmodel=large -ffreestanding -mno-mmx -mno-sse -mno-sse2 -fno-builtin -nostdlib -fPIC -mno-red-zone -DARCH_X86_64 -Wall -Wextra
CFLAGS=$(COMMON_FLAGS) -flto=thin -ffunction-sections -fdata-sections -fPIC
LDFLAGS=$(COMMON_FLAGS) -fno-pie -no-pie -flto=thin -fuse-ld=lld
# ...
build/%.c.bc: %.c
mkdir -p $$(dirname $@)
clang $(CFLAGS) -c $< -o $@
build/%.c.o: build/%.c.bc
mkdir -p $$(dirname $@)
clang $(CFLAGS) -c $< -o $@
build/%.S.o: %.S
mkdir -p $$(dirname $@)
clang $(CFLAGS) -c $< -o $@
build/kernel: $(OBJS)
ld.lld -T kernel.ld -v $^ -o $@
# ...
run:
qemu-system-x86_64 -drive format=raw,file=build/kernel.img -monitor stdio -m 1024M
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment