λ

furix

cute os

settings

arch/x86_64/entry.S

2907 bytes raw

.section .text

.set PAGE_PRESENT, 1 << 0
.set PAGE_WRITE, 1 << 1
.set PAGE_SIZE, 1 << 7

.code32
.global _start
_start:
    mov $stack_top, %esp

    mov %ebx, mb_info_ptr

    # clear bss

    mov $__bss_start, %ecx
    jmp .bss_zero_check
.bss_zero_loop:
    movl $0, (%ecx)
    add $4, %ecx
.bss_zero_check:
    cmp $__bss_end, %ecx
    jb .bss_zero_loop

    # fail if not loaded by multiboot2

    cmp $MB_BOOTLOADER_MAGIC, %eax
    jne .boot_failure

    # map first gb to page_table_l2

    mov $0, %ecx
.page_loop:
    mov %ecx, %eax
    shl $21, %eax

    or $(PAGE_PRESENT | PAGE_WRITE | PAGE_SIZE), %eax
    mov %eax, page_table_l2(,%ecx,8)

    inc %ecx
    cmp $512, %ecx
    jne .page_loop
    
    # the rest of the levels

    mov $page_table_l2, %eax
    or $(PAGE_PRESENT | PAGE_WRITE), %eax
    mov %eax, page_table_l3

    mov $page_table_l3, %eax
    or $(PAGE_PRESENT | PAGE_WRITE), %eax
    mov %eax, page_table_l4

    # page table addr to CR3

    mov $page_table_l4, %eax
    mov %eax, %cr3

    # enable PAE (CR4.PAE)

    mov %cr4, %eax
    or $(1 << 5), %eax
    mov %eax, %cr4

    # enable long mode (EFER.LME)

    mov $0xc0000080, %ecx
    rdmsr
    or $(1 << 8), %eax
    wrmsr

    # enable paging (CR0.PG)

    mov %cr0, %eax
    or $(1 << 31), %eax
    mov %eax, %cr0

    # enable GDT and jump to long mode

    lgdt gdt64_ptr
    ljmp $0x08, $long_main

.boot_failure:
    # TODO: more failure cases liek idk cpu doesnt support long mode

    movb $'e', 0xb8000
    movb $' ', 0xb8001 # green

    cli
.halt32:
    hlt
    jmp .halt32

.code64
long_main:
    mov $stack_top, %rsp

    mov $0, %ax
    mov %ax, %ds
    mov %ax, %es
    mov %ax, %fs
    mov %ax, %gs
    mov %ax, %ss

    call kernel_main

    cli
.halt64:
    hlt
    jmp .halt64

.section .rodata

mb_info_ptr:
    .space 4

.set GDT_FL_LONG, 1 << 53
.set GDT_ACC_RDWR, 1 << 41
.set GDT_ACC_EXEC, 1 << 43
.set GDT_ACC_NOTSYS, 1 << 44
.set GDT_ACC_PRESENT, 1 << 47

gdt64:
    .quad 0
    .quad GDT_ACC_PRESENT | GDT_ACC_NOTSYS | GDT_ACC_RDWR | GDT_ACC_EXEC | GDT_FL_LONG
    .quad GDT_ACC_PRESENT | GDT_ACC_NOTSYS | GDT_ACC_RDWR
gdt64_ptr:
    .word . - gdt64 - 1
    .quad gdt64

.section .bss

.align 4096
page_table_l4:
    .space 4096
page_table_l3:
    .space 4096
page_table_l2:
    .space 4096

.align 16
stack_bottom:
    .space 1024 * 16
stack_top:

.section .multiboot, "a"

.set MB_BOOTLOADER_MAGIC, 0x36d76289

.set MB_MAGIC, 0xE85250D6
.set MB_ARCH, 0
.set MB_LENGTH, (multiboot_hdr_end - multiboot_hdr)
.set MB_CHECKSUM, -(MB_LENGTH + MB_ARCH + MB_MAGIC)

.align 8
multiboot_hdr:
    .long MB_MAGIC
    .long MB_ARCH
    .long MB_LENGTH
    .long MB_CHECKSUM
multiboot_hdr_end:

.set MB_TAG_END, 0
.set MB_TAG_INFO_REQ, 1

.set MB_INFO_MMAP, 6

.align 8
    .word MB_TAG_INFO_REQ
    .word 0
    .long 8 + 4
    .long MB_INFO_MMAP

.align 8
    .word MB_TAG_END
    .word 0
    .long 8