Added build system and some core boot files

This commit is contained in:
2022-12-13 20:21:28 +00:00
parent a54e2eaabc
commit 3402207602
10 changed files with 472 additions and 40 deletions

213
arch/x86_64/start_32.S Normal file
View File

@@ -0,0 +1,213 @@
.set ALIGN, 1 << 0
.set MEMINFO, 1 << 1
.set VIDMODE, 1 << 2
.set FLAGS, ALIGN | MEMINFO
.set MAGIC, 0x1BADB002
.set CHECKSUM, -(MAGIC + FLAGS)
/* the amount of memory to allocate for bootstrap page directories. */
#define BOOTSTRAP_PDIR_SIZE 0x1000
.extern start_64 # defined in start_64.S
.code32
.section .boot.rodata, "a", @progbits
no_long_mode_err:
.asciz "This system is not 64-bit. Press any key to reboot."
unsupported_cpu_err:
.asciz "Your CPU is not supported by Magenta. Press any key to reboot."
.section .boot.bss, "aw", @nobits
bootstrap_pml4t: # a single PML4T
.skip 0x1000
bootstrap_pdpt: # a single PDPT
.skip 0x1000
bootstrap_pdir_buf: # a buffer of page directories. each pdir entry can be used to map 2MB of virtual memory.
.skip BOOTSTRAP_PDIR_SIZE
bootstrap_stack_bottom:
.skip 0x1000
bootstrap_stack_top:
.section .boot.text, "ax", @progbits
.align 4
.long MAGIC
.long FLAGS
.long CHECKSUM
# Print an error message and wait for RETURN if the system's CPU doesn't support long mode.
no_long_mode:
# print error message
mov $no_long_mode_err, %esi
mov $0xb8000, %edi
1:
movsb
movb $12, (%edi)
incl %edi
cmpb $0, (%esi)
jne 1b
2:
inb $0x64, %al
test $0x01, %al
jz 3f
inb $0x60, %al
jmp 2b
3:
inb $0x64, %al
test $0x01, %al
jz 3b
int $0xff
cli
hlt
# Print an error message and wait for RETURN if the system's CPU isn't supported.
unsupported_cpu:
# print error message
mov $unsupported_cpu_err, %esi
mov $0xb8000, %edi
1:
movsb
movb $12, (%edi)
incl %edi
cmpb $0, (%esi)
jne 1b
2:
inb $0x64, %al
test $0x01, %al
jz 3f
inb $0x60, %al
jmp 2b
3:
inb $0x64, %al
test $0x01, %al
jz 3b
int $0xff
cli
hlt
init_page_tables:
/* STEP 1: add an entry in the PML4T pointing to the PDPT.
NOTE that we actually add two entries in the PML4T that both point to the same PDPT.
This allows us to map the kernel at both vaddr 0x0 AND vaddr 0xffffffff80000000 using the same PDPT */
mov $bootstrap_pml4t, %edi
mov $bootstrap_pdpt, %esi
# in %ESI, build a PML4T entry containing the base address of the PDPT
xor $0xFFF, %esi
or $0x3, %esi
# add the PML4T entries at PML4T[0] and PML4T[511]
mov %esi, (%edi)
add $0xFF8, %edi
mov %esi, (%edi)
/* STEP 2: initialise the PDPT.
We need to create an entry in the PDPT for every page directory we intend to use. */
# BOOTSTRAP_PDIR_SIZE contains the total size of the page directory buffer.
# use it to calculate the number of page directories we're using.
mov $0, %edx
mov $BOOTSTRAP_PDIR_SIZE, %eax
mov $0x1000, %ebx
idiv %ebx
mov $bootstrap_pdpt, %edi
mov $bootstrap_pdir_buf, %esi
/* %ESI is a pointer into the pagedir buffer.
%EDI is a pointer into the PDPT.
%EAX is the total number of page directories.
%EBX is where we build the PDPT entry. */
1:
mov %esi, %ebx
xor $0xFFF, %ebx
or $0x3, %ebx
# skip the first 4 bytes of the 8-byte entry, leaving them zero.
add $0x4, %edi
mov %ebx, (%edi)
add $0x1000, %esi
add $0x4, %edi
sub $0x1, %eax
cmp $0x0, %eax
jne 1b
/* STEP 3: initialise the page directories.
Each page directory can be used to map 2MiB of virtual memory.
The exact number of page directories in use is determined by BOOTSTRAP_PDIR_SIZE */
/* the total number of page directory entries is stored in %EAX */
mov $0, %edx
mov $BOOTSTRAP_PDIR_SIZE, %eax
mov $0x8, %ebx
idiv %ebx
mov $0x0, %esi
mov $bootstrap_pdir_buf, %edi
/* %EDI is a pointer into the pagedir buffer.
%ESI is the physical address being mapped. must be a multiple of 2MiB.
%EAX is the total number of page directories.
%EBX is where we build the pagedir entry. */
2:
mov %esi, %ebx
xor $0xFFF, %ebx
or $0x3, %ebx
# skip the first 4 bytes of the 8-byte entry, leaving them zero.
add $0x4, %edi
mov %ebx, (%edi)
add $0x200000, %esi
add $0x4, %edi
dec %eax
jnz 2b
ret
long_mode_switch:
ret
.global _start
.type _start, @function
_start:
mov $bootstrap_stack_top, %esp
push %ebx # store the pointer to the multiboot info block.
# check if long mode is supported
movl $0x80000000, %eax # Extended-function 80000000h.
cpuid # Is largest extended function
cmpl $0x80000000, %eax # any function > 80000000h?
jbe no_long_mode # If not, no long mode.
movl $0x80000001, %eax # Extended-function 80000001h.
cpuid # Now EDX = extended-features flags.
btl $29, %edx # Test if long mode is supported.
jnc no_long_mode # Exit if not supported.
movl $1, %eax
cpuid
btl $3, %edx
mov $0xb8000, %eax
movb $76, (%eax)
inc %eax
movb $0xF, (%eax)
call init_page_tables
call long_mode_switch # calls start_64, does not return
cli
hlt