Files
quark-kernel/src/x86/entry.S

342 lines
6.2 KiB
ArmAsm
Executable File

.section .multiboot
/*
* Define constants for the multiboot header. See Multiboot 2 Specifications for details.
*/
.set align, 1<<0
.set meminfo, 1<<1
.set magic, 0xE85250D6
.set arch, 0
.set headerLength, _multibootHeaderEnd - _multibootHeaderStart
.set checksum, -(magic + arch + headerLength)
.set tagNotOptional, 0
.set tagInfoRequestType, 1
.set tagInfoRequestSize, _multibootInfoTagEnd - _multibootInfoTagStart
.set requestBootCommand, 1
.set requestBootLoaderName, 2
.set requestBootModules, 3
.set requestMemoryInfo, 4
.set requestBootDevice, 5
.set requestMemoryMap, 6
.set tagAddressType, 2
.set tagAddressSize, 24
.set tagAddressHeaderLocation, LOAD_START
.set tagAddressLoadStart, LOAD_START
.set tagAddressLoadEnd, LOAD_END
.set tagAddressBSSEnd, BSS_END
.set tagEntryType, 3
.set tagEntrySize, 12
.set tagEntryAddress, _start - (0xFF900000 - 0x100000)
.set tagModuleAlignType, 6
.set tagModuleAlignSize, 8
/*
* Each multiboot tag must be 8-byte aligned, or GRUB will not be able to read the header.
*/
.align 8
_multibootHeaderStart:
.long magic
.long arch
.long headerLength
.long checksum
.align 8
_multibootInfoTagStart:
.short tagInfoRequestType
.short tagNotOptional
.long tagInfoRequestSize
.long requestBootCommand
.long requestBootLoaderName
.long requestBootModules
.long requestMemoryInfo
.long requestBootDevice
.long requestMemoryMap
_multibootInfoTagEnd:
.align 8
.short tagAddressType
.short tagNotOptional
.long tagAddressSize
.long tagAddressHeaderLocation
.long tagAddressLoadStart
.long tagAddressLoadEnd
.long tagAddressBSSEnd
.align 8
.short tagEntryType
.short tagNotOptional
.long tagEntrySize
.long tagEntryAddress
.align 8
.short tagModuleAlignType
.short tagNotOptional
.long tagModuleAlignSize
.align 8
/*
* Terminate list of multiboot header tags.
* Ending tag has type = 0, flags = 0, size = 8
*/
.long 0
.long 8
_multibootHeaderEnd:
.section .rodata
gdt:
.long 0, 0
.short 0xFFFF
.short 0x0000
.short 0x9A00
.short 0x00CF
.short 0xFFFF
.short 0x0000
.short 0x9200
.short 0x00CF
gdt_info:
.short 23
.long gdt
.section .bss
.align 16
stackBottom:
.skip 8192
stackTop:
.align 4096
_tempPgDir:
.skip 4096
_tempIdentityMap:
.skip 4096
_tempPgTable:
.skip 8192
_bootCmdLine:
.skip 64
.align 64
.global system_info
system_info:
.skip 16
.align 64
.global memory_map
memory_map:
.skip 16 * 16
.section .text
.global _start
.type _start, @function
_start:
cmp $0x36d76289, %eax
jne _err
movb $64, 0xB8000
mov $system_info, %edi
sub $BASE_DIFF, %edi
add $8, %ebx
switch:
mov (%ebx), %eax
cmp $0, %eax
je s_end
cmp $1, %eax
je tag_1
cmp $3, %eax
je tag_3
cmp $4, %eax
je tag_4
cmp $6, %eax
je tag_6
cmp $21, %eax
je tag_21
jmp def
# Boot command line
tag_1:
mov 4(%ebx), %ecx
sub $8, %ecx
mov %ebx, %esi
add $8, %esi
mov $_bootCmdLine, %edi
sub $BASE_DIFF, %edi
rep movsb
mov $system_info, %edi
sub $BASE_DIFF, %edi
jmp def
tag_3:
mov 8(%ebx), %esi
mov (%esi), %eax
mov %al, (0xB8004)
mov %ah, (0xB8006)
shr $16, %eax
mov %al, (0xB8008)
mov %ah, (0xB800a)
jmp def
# Basic memory info
tag_4:
mov 8(%ebx), %eax
mov %eax, (%edi)
mov 12(%ebx), %eax
mov %eax, 4(%edi)
jmp def
# Memory map
tag_6:
mov $memory_map, %esi
sub $BASE_DIFF, %esi # set esi to point to the table in the kernel image
mov 4(%ebx), %ecx
sub $16, %ecx # set ecx to store the size of the table provided by the bootloader
mov 8(%ebx), %edx # set edx to store the size of each table entry
add $16, %ebx # move ebx up to the first entry
1: mov (%ebx), %eax
mov %eax, (%esi) # save the address of that region in memory
mov 8(%ebx), %eax
mov %eax, 4(%esi) # save the size of that region in memory
mov 16(%ebx), %eax
mov %eax, 8(%esi) # save the type of memory in that region
add $12, %esi # move esi to the next entry in the kernel's array
add %edx, %ebx # move ebx to the next entry in the bootloader's array
sub %edx, %ecx # subtract the size of an entry from ecx.
jnz 1b # loop if there are entries left
mov $0, %eax
mov %eax, (%esi)
mov %eax, 4(%esi)
mov %eax, 8(%esi)
jmp switch
# Program image location
tag_21:
mov 8(%ebx), %eax
mov %eax, 8(%edi)
jmp def
def:
mov 4(%ebx), %eax
add $7, %eax
and $0xFFFFFFF8, %eax
add %eax, %ebx
jmp switch
s_end:
movb $64, 0xB8002
mov $0, %ecx
1:
# Generate a page table entry pointing to a page in the kernel binary
mov %ecx, %eax
mov $4096, %edx
mul %edx
or $3, %eax
# Load the address of the temporary page table and translate it to a physical address
mov $_tempPgTable, %edi
sub $BASE_DIFF, %edi
# Save the PTE into an entry in the temporary page table
mov %eax, (%edi, %ecx, 4)
# Load the address of the identity map and translate it to a physical address
mov $_tempIdentityMap, %edi
sub $BASE_DIFF, %edi
# Save the PTE into an entry in the identity map
mov %eax, (%edi, %ecx, 4)
# Increment count and loop
inc %ecx
mov $IMAGE_SIZE, %edx
add $256, %edx
cmp %edx, %ecx
jne 1b
# Load the physical address of the identity map, and generate a PDE
mov $_tempIdentityMap, %eax
sub $BASE_DIFF, %eax
or $3, %eax
# Load the physical address of the page directory
mov $_tempPgDir, %edi
sub $BASE_DIFF, %edi
# Save the PDE to the first element in the page directory
mov %eax, (%edi)
# Load the physical address of the temporary page table, and generate a PDE
mov $_tempPgTable, %eax
sub $BASE_DIFF, %eax
or $3, %eax
# Save the PDE to the entry corresponding to 0xC0000000
mov %eax, 4088(%edi)
# Set the last entry in the page directory to point to the page directory itself
mov %edi, %eax
or $3, %eax
mov %eax, 4092(%edi)
# Load the physical address of the page directory into CR3
mov $_tempPgDir, %edi
sub $BASE_DIFF, %edi
mov %edi, %cr3
# Enable paging
mov %cr0, %eax
or $0x80010000, %eax
mov %eax, %cr0
# Jump into mapped kernel binary
lea 2f, %eax
jmp *%eax
2:
# Delete PDE corresponding to identity map. We shouldn't need it anymore.
movl $0, (_tempIdentityMap)
# Reload page tables
mov %cr3, %eax
mov %eax, %cr3
# Initialize stack
mov $stackTop, %esp
lgdt gdt_info
jmp $8, $.ldcs
.ldcs:
mov $16, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %gs
mov %ax, %fs
mov %ax, %ss
mov $_bootCmdLine, %eax
push %eax
# Call main function
call main
_err:
cli
3: hlt
jmp 3b
.size _start, . - _start