From 764fec4d75d3f15b421722cab4e17341fc283f6d Mon Sep 17 00:00:00 2001 From: Aiken Harris Date: Fri, 17 Oct 2025 09:05:24 +0200 Subject: [PATCH] Implement low-level CPU initialization support for i686 and AMD64 boot sectors --- boot/bootsect/amd64/cpu.S | 143 ++++++++++++++++++++++++++++++++++++++ boot/bootsect/i686/cpu.S | 123 ++++++++++++++++++++++++++++++++ 2 files changed, 266 insertions(+) create mode 100644 boot/bootsect/amd64/cpu.S create mode 100644 boot/bootsect/i686/cpu.S diff --git a/boot/bootsect/amd64/cpu.S b/boot/bootsect/amd64/cpu.S new file mode 100644 index 0000000..da9efd0 --- /dev/null +++ b/boot/bootsect/amd64/cpu.S @@ -0,0 +1,143 @@ +/** +* PROJECT: ExectOS +* COPYRIGHT: See COPYING.md in the top level directory +* FILE: boot/bootsect/amd64/cpu.S +* DESCRIPTION: Low-level support for CPU initialization +* DEVELOPERS: Aiken Harris +*/ + + +BuildPageMap: + /* Generate page map for first 1GB of memory */ + pushaw + pushw %es + cld + movw $(0x1000 / 16), %ax + movw %ax, %es + xorw %di, %di + movl $(0x2000 | 0x07), %eax + stosl + xorl %eax, %eax + movw $1021, %cx + rep stosl + movw $(0x2000 / 16), %ax + movw %ax, %es + xorw %di, %di + movl $(0x3000 | 0x07), %eax + stosl + xorl %eax, %eax + movw $1021, %cx + rep stosl + movw $(0x3000 / 16), %ax + movw %ax, %es + xorw %di, %di + movw $512, %cx + movl $0x00000083, %eax +.BuildPageMapLoop: + /* Identity map 512 pages of 2MB */ + movl %eax, %es:(%di) + addl $2097152, %eax + addw $0x08, %di + loop .BuildPageMapLoop + popw %es + popaw + ret + +InitializeCpu: + /* Check if CPU supports CPUID, long mode and PAE */ + pushal + pushfl + popl %eax + movl %eax, %ebx + xorl $0x00200000, %eax + pushl %eax + popfl + pushfl + popl %eax + cmpl %ebx, %eax + je CpuUnsupported + movl $0x01, %eax + cpuid + testl $0x40, %edx + jz CpuUnsupported + movl $0x80000000, %eax + cpuid + cmpl $0x80000000, %eax + jbe CpuUnsupported + movl $0x80000001, %eax + cpuid + testl $0x20000000, %edx + jz CpuUnsupported + popal + ret + +LoadGdt: + /* Load Global Descriptor Table */ + lgdt .GdtPointer + ret + +RunStage2: + /* Switch to long mode and pass control to Stage 2 */ + call BuildPageMap + call ParseExecutableHeader + xorl %edx, %edx + pushl %edx + pushl %eax + cli + xorw %ax, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + movw %ax, %ss + movl %cr4, %eax + orl $0x00A0, %eax + movl %eax, %cr4 + movl $0x00001000, %eax + movl %eax, %cr3 + movl $0xC0000080, %ecx + rdmsr + orl $0x00000100, %eax + wrmsr + movl %cr0, %eax + orl $0x80000001, %eax + movl %eax, %cr0 + ljmp $0x10, $.Stage2LongMode +.code64 +.Stage2LongMode: + /* Set segments and stack, then jump to Stage 2 */ + movw $0x18, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %ss + xorw %ax, %ax + movw %ax, %fs + movw %ax, %gs + popq %rax + xorq %rbx, %rbx + xorq %rcx, %rcx + xorq %rdx, %rdx + xorq %rsi, %rsi + xorq %rdi, %rdi + xorq %rbp, %rbp + jmp *%rax + +.code16 +.GdtDescriptor: + /* Global Descriptor Table */ + .quad 0x0000000000000000 + .quad 0x0000000000000000 + .quad 0x00AF9A000000FFFF + .quad 0x00CF92000000FFFF + .quad 0x00009E000000FFFF + .quad 0x000092000000FFFF + .quad 0x00CF9B000000FFFF + +.GdtPointer: + /* Pointer to Global Descriptor Table */ + .word .GdtPointer - .GdtDescriptor - 1 + .long .GdtDescriptor + +.Stage2FileName: + /* Name of Stage 2 executable file */ + .ascii "BOOTX64 EFI" diff --git a/boot/bootsect/i686/cpu.S b/boot/bootsect/i686/cpu.S new file mode 100644 index 0000000..44fc495 --- /dev/null +++ b/boot/bootsect/i686/cpu.S @@ -0,0 +1,123 @@ +/** +* PROJECT: ExectOS +* COPYRIGHT: See COPYING.md in the top level directory +* FILE: boot/bootsect/i686/cpu.S +* DESCRIPTION: Low-level support for CPU initialization +* DEVELOPERS: Aiken Harris +*/ + + +BuildPageMap: + /* Generate page map for first 16MB of memory */ + pushaw + pushw %es + cld + movw $(0x1000 >> 0x04), %ax + movw %ax, %es + xorw %di, %di + movl $(0x2000 | 0x03), %eax + stosl + movl $(0x3000 | 0x03), %eax + stosl + movl $(0x4000 | 0x03), %eax + stosl + movl $(0x5000 | 0x03), %eax + stosl + xorl %eax, %eax + movw $(1024 - 4), %cx + rep stosl + movl $0x00000003, %eax + movl $4, %edx + movw $(0x2000 >> 0x04), %bx +.BuildPageMapLoop: + /* Identity map 1024 pages of 4KB */ + movw %bx, %es + xorw %di, %di + pushl %edx + movw $1024, %cx +.FillPageMapTable: + /* Fill the page table */ + movl %eax, %es:(%di) + addl $4096, %eax + addw $0x04, %di + loop .FillPageMapTable + popl %edx + addw $(0x1000 >> 0x04), %bx + decl %edx + jnz .BuildPageMapLoop + popw %es + popaw + ret + +InitializeCpu: + /* Check if CPU supports CPUID */ + pushal + pushfl + popl %eax + movl %eax, %ebx + xorl $0x00200000, %eax + pushl %eax + popfl + pushfl + popl %eax + cmpl %ebx, %eax + je CpuUnsupported + popal + ret + +LoadGdt: + /* Load Global Descriptor Table */ + lgdt .GdtPointer + ret + +RunStage2: + /* Switch to protected mode and pass control to Stage 2 */ + call BuildPageMap + call ParseExecutableHeader + pushl %eax + cli + movl %cr0, %eax + orl $0x01, %eax + movl %eax, %cr0 + ljmp $0x08, $.Stage2ProtectedMode +.code32 +.Stage2ProtectedMode: + /* Set segments and stack, then jump to Stage 2 */ + movw $0x10, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %ss + xorw %ax, %ax + movw %ax, %fs + movw %ax, %gs + popl %eax + xorl %ebx, %ebx + xorl %ecx, %ecx + xorl %edx, %edx + xorl %esi, %esi + xorl %edi, %edi + xorl %ebp, %ebp + movl $0x1000, %ebx + movl %ebx, %cr3 + movl %cr0, %ebx + orl $0x80000000, %ebx + movl %ebx, %cr0 + jmp *%eax + +.code16 +.GdtDescriptor: + /* Global Descriptor Table */ + .quad 0x0000000000000000 + .quad 0x00CF9A000000FFFF + .quad 0x00CF92000000FFFF + .quad 0x00009E000000FFFF + .quad 0x000092000000FFFF + +.GdtPointer: + /* Pointer to Global Descriptor Table */ + .word .GdtPointer - .GdtDescriptor - 1 + .long .GdtDescriptor + +.Stage2FileName: + /* Name of Stage 2 executable file */ + .ascii "BOOTIA32EFI"