Skip to content

Instantly share code, notes, and snippets.

@erincandescent
Created September 2, 2013 02:32
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 erincandescent/6408764 to your computer and use it in GitHub Desktop.
Save erincandescent/6408764 to your computer and use it in GitHub Desktop.
#include "mbconstants.h"
#include "architecture.h"
.extern KMain
.extern BootStackTop
.extern IMAGE_END
.extern BSS_END
#define MB2_FLAGS (MB2_IFLAG_VIDEO | MB2_IFLAG_MBFIELDS)
#define MB2_CHECKSUM ((-(MB2_IMAGE_MAGIC + MB2_FLAGS)) & 0xFFFFFFFF)
// ------------------------------------------------------------
// The following are all physical addresses!
// ------------------------------------------------------------
# Multiboot Header
.code32
.align 8
mb_hdr:
# Primary header
.long MB2_IMAGE_MAGIC
.long MB2_FLAGS
.long MB2_CHECKSUM
# Address header
.long mb_hdr - VIRTUAL_BASE
.long 0x00100000
.long IMAGE_END - VIRTUAL_BASE
.long BSS_END - VIRTUAL_BASE
.long KLoader - VIRTUAL_BASE
# Video mode
.long 1 # EGA Text mode
.long 80 # 80 char wide
.long 50 # 50 char tall
.long 0 # Bits per pixel (ignored)
.global KLoader
KLoader:
# Switch to our GDT
lgdt GDTR32 - VIRTUAL_BASE
# Store away Multiboot info
movl %eax, %edi # di and si are sufficiently far away to not be used. More importantly,
movl %ebx, %esi # %rdi and %rsi are the first and second function params in the ABI
# Check CPU does long mode
movl $0x80000000, %eax
cpuid
cmpl $0x80000000, %eax
jbe noLong
movl $0x80000001, %eax
cpuid
bt $29, %edx
jnc noLong
# Enable PAE
movl %cr4, %eax
bts $5, %eax
movl %eax, %cr4
# Load page table address
movl $(KPML4Base - VIRTUAL_BASE), %eax
movl %eax, %cr3
# Set LME
mov $0xC0000080, %ecx
rdmsr
bts $8, %eax
wrmsr
# Enable paging
mov %cr0, %eax
bts $31, %eax
mov %eax, %cr0
# Now in long-compatibility32 mode
# Jump to 64-bit code
ljmp $0x18, $(KStub64 - VIRTUAL_BASE)
.code64
KStub64:
movabs $KEntry64, %rax
jmp *%rax
.code32
noLong:
mov $0xb8000, %eax
mov $nlmsg - VIRTUAL_BASE, %ebx
mov $0x40, %cl
0: mov (%ebx), %ch
test $0xff, %cl
jz 1f
mov %cx, (%eax)
inc %ebx
add $2, %eax
jmp 0b
1: jmp 1b
nlmsg:
.asciz "64-bit processor required"
GDTR32:
.word 0xFFFF
.long KGDT - VIRTUAL_BASE
// ------------------------------------------------------------
// Virtual addresses from now on!
// ------------------------------------------------------------
.code64
KEntry64:
# Reload GDT
leaq GDTR(%rip), %rax
lgdt (%rax)
mov $0x10, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %ss
# Load stack
leaq BootStackTop(%rip), %rsp
# Finished
call KMain
# KMain returned?
movq $(VIRTUAL_BASE + 0xB8000), %rax
lea remsg(%rip), %rbx
mov $0x0F, %ch
0: mov (%rbx), %cl
test $0xff, %cl
jz 1f
mov %cx, (%rax)
inc %rbx
add $2, %rax
jmp 0b
1: jmp 1b
remsg:
.asciz "Kernel returned from main (fault)"
.section .data
.global GDTR
GDTR:
.word 0xFFFF
.quad KGDT
.align 8
.global KGDT
KGDT:
# Segment 0x00: Required NULL
.quad 0
# Segment 0x08: Code32
.word 0xFFFF # 4GB limit[0..15]
.word 0 # 0 Base[0..15]
.byte 0 # 0 Base[16..23]
.byte 0x9A # Present, Code, Readable, Ring 0
.byte 0xCF # 4GB limit[16..20], 4kb granularity, 32bit size
.byte 0x00 # 0 Base [24..31]
# Segment 0x10: Data32
.word 0xFFFF # 4GB limit[0..15]
.word 0 # 0 Base[0..15]
.byte 0 # 0 Base[16..23]
.byte 0x93 # Present, Data, Writable, Ring 0
.byte 0xCF # 4GB limit[16..20], 4kb granularity, 32bit size
.byte 0x00 # 0 Base [24..31]
# Segment 0x18: Code64
.word 0 # Limit ign
.word 0 # Base ign
.byte 0 # Base ign
.byte 0x9A # Present, Code, Readable, Ring 0
.byte 0xA0 # 4kb granularity, long mode
.byte 0 # Base ign
# Zero rest
.fill 8188, 8, 0
.align 4096
.global KPML4Base
KPML4Base:
# Identity map start
.quad 0x103 + (PDPTBase - VIRTUAL_BASE)
.fill 255, 8, 0
# Map kernel
.quad 0x103 + (PDPTBase - VIRTUAL_BASE)
.fill 255, 8, 0
# Point to PD for first 1GB
PDPTBase:
.quad 0x103 + (PDBase - VIRTUAL_BASE)
.fill 511, 8, 0
# Identity map first 1GB (We don't know if the CPU
# supports 1GB pages)
PDBase:
.set paddr, 0
.rept 512
.quad paddr | 0x183
.set paddr, paddr + 0x0200000
.endr
.section .bss
.align 8
BootStack:
.space 0x10000, 0
BootStackTop:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment