120 lines
3.4 KiB
NASM
120 lines
3.4 KiB
NASM
bits 32
|
|
|
|
%define MULTIBOOT_PAGE_ALIGN 0x00000001
|
|
%define MULTIBOOT_MEMORY_INFO 0x00000002
|
|
%define MULTIBOOT_HEADER_MAGIC 0x1BADB002
|
|
%define MULTIBOOT_HEADER_FLAGS (MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO)
|
|
|
|
%define CR0_MP 0x00000002 /* bit 01 -> enable monitor coprocessor */
|
|
%define CR0_NE 0x00000020 /* bit 05 -> enable native x87 FPU mode */
|
|
%define CR0_WP 0x00010000 /* bit 16 -> enable write protect (for CoW) */
|
|
%define CR0_AM 0x00040000 /* bit 18 -> enable alignment checking */
|
|
%define CR0_PG 0x80000000 /* bit 31 -> enable paging */
|
|
|
|
%define PAGE_OFFSET 0xC0000000
|
|
%define GDT_BASE (0xFFFFFFFF - (PAGE_OFFSET - 1))
|
|
|
|
%define KERNEL_CS 0x8
|
|
%define KERNEL_DS 0x10
|
|
|
|
section .setup
|
|
|
|
align 4
|
|
tmp_gdtr:
|
|
dw ((3 * 8) - 1)
|
|
tmp_gdta:
|
|
dd tmp_gdt
|
|
|
|
align 4
|
|
tmp_gdt:
|
|
; NULL DESCRIPTOR
|
|
dw 0x0000
|
|
dw 0x0000
|
|
dw 0x0000
|
|
dw 0x0000
|
|
|
|
; KERNEL CODE
|
|
dw 0xFFFF ; segment limit 15-00
|
|
dw 0x0000 ; base address 15-00
|
|
db 0x00 ; base address 23-16
|
|
db 0x9A ; P=1 DPL=00 S=1 TYPE=1010 (exec/read)
|
|
db 0xCF ; G=1 DB=1 0=0 AVL=0 SEGLIM=1111
|
|
db (GDT_BASE >> 24) ; base address 31-24 (0x40)
|
|
|
|
; KERNEL DATA
|
|
dw 0xFFFF ; segment limit 15-00
|
|
dw 0x0000 ; base address 15-00
|
|
db 0x00 ; base address 23-16
|
|
db 0x92 ; P=1 DPL=00 S=1 TYPE=0010 (read/write)
|
|
db 0xCF ; G=1 DB=1 0=0 AVL=0 SEGLIM=1111
|
|
db (GDT_BASE >> 24) ; base address 31-24 (0x40)
|
|
|
|
align 4
|
|
multiboot_header:
|
|
dd MULTIBOOT_HEADER_MAGIC
|
|
dd MULTIBOOT_HEADER_FLAGS
|
|
dd -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
|
|
dd 0 ; header_addr
|
|
dd 0 ; load_addr
|
|
dd 0 ; load_end_addr
|
|
dd 0 ; bss_end_addr
|
|
dd 0 ; entry_addr
|
|
dd 0 ; mode_type
|
|
dd 0 ; width
|
|
dd 0 ; height
|
|
dd 0 ; depth
|
|
|
|
section .text
|
|
global _start
|
|
|
|
extern setup_tmp_pgdir
|
|
extern bss_init
|
|
extern gdt_init
|
|
extern get_last_boot_addr
|
|
extern kmain
|
|
|
|
_start:
|
|
cli
|
|
lgdt [tmp_gdtr] ; load GDTR with the temporary GDT
|
|
mov cx, KERNEL_DS
|
|
mov ds, cx
|
|
mov es, cx
|
|
mov fs, cx
|
|
mov gs, cx
|
|
mov ss, cx
|
|
jmp KERNEL_CS:setup_kernel
|
|
|
|
align 4
|
|
global setup_kernel
|
|
setup_kernel:
|
|
mov esp, PAGE_OFFSET + 0x10000 ; default stack address (0xC0000000 + 0x10000)
|
|
push 0 ; reset EFLAGS
|
|
popf
|
|
|
|
push ebx ; save Multiboot info structure
|
|
push eax ; save Multiboot magic value
|
|
call setup_tmp_pgdir
|
|
mov cr3, eax
|
|
|
|
mov eax, cr0
|
|
and eax, 0x00000011 ; disable all, preserve ET & PE (GRUB)
|
|
or eax, 0x80000000 ; CR0_PG ; enable PG
|
|
or eax, 0x40000 ; CR0_AM ; enable AM
|
|
or eax, 0x10000 ; CR0_WP ; enable WP
|
|
or eax, 0x20 ; CR0_NE ; enable NE
|
|
or eax, 0x02 ; CR0_MP ; enable MP
|
|
mov cr0, eax
|
|
|
|
call bss_init ; initialize BSS segment
|
|
call gdt_init ; setup and load the definitive GDT
|
|
call get_last_boot_addr
|
|
pop ecx ; restore Multiboot magic value
|
|
pop ebx ; restore Multiboot info structure
|
|
|
|
push eax ; save the last boot address
|
|
push ebx ; save Multiboot info structure
|
|
push ecx ; save Multiboot magic value
|
|
call kmain
|
|
|
|
jmp $
|