Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- KERNEL_STACKSIZE equ 2*1024*1024
- section .text
- bits 32
- header_start:
- ; magic number
- dd 0xe85250d6
- ; architecture
- dd 0
- ; header length
- dd header_end - header_start
- ; checksum
- dd - (0xe85250d6 + 0 + (header_end - header_start))
- bootinfo_request_tag:
- dd 1
- dd bootinfo_request_tag_end - bootinfo_request_tag
- dd 6 ; memory map
- dd 1 ; boot command line
- dd 8 ; framebuffer info
- dd 12 ; efi64 system table pointer
- bootinfo_request_tag_end:
- framebuffer_tag:
- dw 5 ;type
- dw 1 ;flag
- dd 20 ;size
- dd 800 ; width
- dd 600 ; height
- dd 32 ; depth
- framebuffer_tag_end:
- dd 0
- end_tag:
- dd 0
- dd 8
- header_end:
- bits 32
- global start
- start:
- mov esp, stack_top
- push ebx
- call check_multiboot
- call check_cpuid
- call check_long_mode
- call setup_page_tables
- call enable_paging
- pop edi
- lgdt [gdt64.pointer]
- jmp gdt64.code_segment:long_mode_start
- hlt
- check_multiboot:
- cmp eax, 0x36d76289
- jne .no_multiboot
- ret
- .no_multiboot:
- mov al, "M"
- jmp error
- check_cpuid:
- pushfd
- pop eax
- mov ecx, eax
- xor eax, 1 << 21
- push eax
- popfd
- pushfd
- pop eax
- push ecx
- popfd
- cmp eax, ecx
- je .no_cpuid
- ret
- .no_cpuid:
- mov al, "C"
- jmp error
- check_long_mode:
- mov eax, 0x80000000
- cpuid
- cmp eax, 0x80000001
- jb .no_long_mode
- mov eax, 0x80000001
- cpuid
- test edx, 1 << 29
- jz .no_long_mode
- ret
- .no_long_mode:
- mov al, "L"
- jmp error
- ; Identitiy map first 4GiB
- setup_page_tables:
- mov eax, page_table_l3
- or eax, 0b11 ; present, writable
- mov [page_table_l4], eax
- mov eax, page_table_l2_0 ; Map 1st GiB
- or eax, 0b11 ; present, writable
- mov [page_table_l3+8*0], eax
- mov eax, page_table_l2_1 ; Map 2nd GiB
- or eax, 0b11 ; present, writable
- mov [page_table_l3+8*1], eax
- mov eax, page_table_l2_2 ; Map 3rd GiB
- or eax, 0b11 ; present, writable
- mov [page_table_l3+8*2], eax
- mov eax, page_table_l2_3 ; Map 4th GiB
- or eax, 0b11 ; present, writable
- mov [page_table_l3+8*3], eax
- mov ecx, 0 ; counter
- .loop:
- mov eax, 0x200000 ; 2MiB
- mul ecx
- or eax, 0b10000011 ; present, writable, huge page
- mov [page_table_l2 + ecx * 8], eax
- inc ecx ; increment counter
- cmp ecx, 512*4 ; checks if the whole table is mapped
- jne .loop ; if not, continue
- ret
- enable_paging:
- ; pass page table location to cpu
- mov eax, page_table_l4
- mov cr3, eax
- ; enable PAE
- mov eax, cr4
- or eax, 1 << 5
- mov cr4, eax
- ; enable long mode
- mov ecx, 0xC0000080
- rdmsr
- or eax, 1 << 8
- wrmsr
- ; enable paging
- mov eax, cr0
- or eax, 1 << 31
- mov cr0, eax
- ret
- error:
- ; print "ERR: X" where X is the error code
- mov dword [0xb8000], 0x4f524f45
- mov dword [0xb8004], 0x4f3a4f52
- mov dword [0xb8008], 0x4f204f20
- mov byte [0xb800a], al
- hlt
- bits 64
- long_mode_start:
- ; load null into all data segment registers
- mov ax, 0
- mov ss, ax
- mov ds, ax
- mov es, ax
- mov fs, ax
- mov gs, ax
- mov rsp,KERNEL_STACK+KERNEL_STACKSIZE
- ; Ensure top 32 bits of RDI are 0
- mov edi, edi
- extern kernel_main
- ; 1st parameter in RDI contains ptr to multiboot tag structure
- call kernel_main
- hlt
- bits 32
- section .bss
- align 4096
- page_table_l4:
- resb 4096
- page_table_l3:
- resb 4096
- page_table_l2:
- page_table_l2_0:
- resb 4096
- page_table_l2_1:
- resb 4096
- page_table_l2_2:
- resb 4096
- page_table_l2_3:
- resb 4096
- stack_bottom:
- resb 4096 * 4
- stack_top:
- bits 64
- KERNEL_STACK:
- resb KERNEL_STACKSIZE
- bits 32
- section .rodata
- gdt64:
- dq 0 ; zero entry
- .code_segment: equ $ - gdt64
- dq (1 << 43) | (1 << 44) | (1 << 47) | (1 << 53) ; code segment
- .pointer:
- dw $ - gdt64 - 1 ; length
- dq gdt64 ; address
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement