#include "init/init.h" extern "C" [[maybe_unused]] [[noreturn]] __attribute__((used)) void __entry64() { init(); while (true) __asm__ volatile (""); } asm(R"( .global __start .section .startup_text, "ax" .type __start, @function .code32 .align 16 __start: cli mov $__start_stack_end, %esp mov %ebx, __multiboot_info call __clear mov $__hello_string, %esi call __print call __check_if_x64 call __go_to_x64 jmp __stop32 __stop32: hlt jmp __stop32 __x64_not_supported: mov $__x64_not_supported_string, %esi call __print jmp __stop32 __check_if_x64: pushfl pop %eax mov %eax, %ecx xor $(1 << 21), %eax push %eax popfl pushfl pop %eax push %ecx popfl cmp %eax, %ecx je __x64_not_supported mov $0x80000000, %eax cpuid cmp $0x80000001, %eax jb __x64_not_supported mov $0x80000001, %eax cpuid test $(1 << 29), %edx jz __x64_not_supported mov $__x64_supported_string, %esi call __print ret __go_to_x64: push %ebx mov $__page_level_4, %eax mov %eax, %cr3 mov %cr4, %eax or $(0x1 << 5), %eax mov %eax, %cr4 mov $0xC0000080, %ecx rdmsr or $(0x1 << 8), %eax wrmsr mov %cr0, %eax or $(0x1 << 31), %eax mov %eax, %cr0 pop %edi lgdt __gdt_end jmp $0b1000, $__start64 jmp __stop32 .code64 .align 16 __start64: mov $0b10000, %ax mov %ax, %ds mov %ax, %es mov %ax, %fs mov %ax, %gs mov %ax, %ss movabsq $__start64_high, %rax jmp* %rax __stop64: hlt jmp __stop64 .section .text .type __start64_high, @function .code64 .align 16 __start64_high: call __entry64 hlt jmp __start64_high )"); // data section asm(R"( .global __multiboot_info .global __cursor .section .startup_data, "aw" __cursor: .int 0x0 __hello_string: .string "Starting PrOSess! 32bit start!\n" __x64_not_supported_string: .string "x64 is not supported!\n" __x64_supported_string: .string "x64 is supported!\n" __multiboot_info: .long 0x0 __start_stack: .skip 0x1000 .align 8 __start_stack_end: .quad 0 )"); // string operation section asm(R"( .section .startup_text, "ax" .code32 .align 16 __clear: movl $0, (__cursor) mov $0x0, %eax mov $0xb8000, %edi mov $0x2000, %ecx rep stosw mov $0x3D4, %dx mov $0x0A, %al out %al, %dx inc %dx mov $0x20, %al out %al, %dx ret __print: mov $0xB8000, %edi add (__cursor), %edi __print_loop: mov (%esi), %al mov $0x0F, %ah cmp $0, %al je __print_end cmp $'\n', %al je __print_next_line mov %ax, (%edi) add $2, %edi add $1, %esi jmp __print_loop __print_next_line: sub $0xB8000, %edi mov %edi, (__cursor) add $0xB8000, %edi call __next_line mov $0xB8000, %edi add (__cursor), %edi add $1, %esi jmp __print_loop __print_end: sub $0xB8000, %edi mov %edi, (__cursor) ret __next_line: push %eax push %ecx mov (__cursor), %eax leal 159(%eax), %ecx movl $1717986919, %eax imull %ecx sarl $31, %ecx sarl $6, %edx subl %ecx, %edx leal (%edx,%edx,4), %eax sall $5, %eax mov %eax, (__cursor) pop %ecx pop %eax ret )"); // tmp page table asm(R"( .section .startup_data, "aw" .align 0x1000 __page_level_4: .quad __page_level_3_low_1gb_identity_map + ((1 << 0) | (1 << 1)) .zero 0x7F8 .quad __page_level_3_kernel_1gb_identity_map + ((1 << 0) | (1 << 1)) .zero 0x7F8 .align 0x1000 __page_level_3_low_1gb_identity_map: .quad (1 << 0) | (1 << 1) | (1 << 7) | 0x0 .zero 0xFF8 # rest of table is 0 .align 0x1000 __page_level_3_kernel_1gb_identity_map: .quad (1 << 0) | (1 << 1) | (1 << 7) | 0x0 .zero 0xFF8 # rest of table is 0 )"); // startup gdt asm(R"( .section .startup_data, "aw" .align 0x1000 __gdt: .quad 0 .quad (1 << 43) | (1 << 44) | (1 << 47) | (1 << 53) # code segment .quad (1 << 41) | (1 << 44) | (1 << 47) # data segment .align 0x1000 __gdt_end: .word __gdt_end - __gdt - 1 .quad __gdt )");