mirror of https://gitlab.com/nakst/essence
booting into 32 bit kernels
This commit is contained in:
parent
4e6549d625
commit
1ce7df083a
|
@ -303,6 +303,7 @@ bool MMArchMapPage(MMSpace *space, uintptr_t physicalAddress, uintptr_t virtualA
|
|||
// That said, a CPU won't overwrite and clear a dirty bit when writing out its accessed flag (tested on Qemu);
|
||||
// see here https://stackoverflow.com/questions/69024372/.
|
||||
// Tl;dr: if a CPU ever sees an entry without these bits set, it can overwrite the entry with junk whenever it feels like it.
|
||||
// TODO Should we be marking page tables as dirty/accessed? (Including those made by the 32-bit AND 64-bit bootloader and MMArchInitialise).
|
||||
value |= (1 << 5) | (1 << 6);
|
||||
|
||||
if ((oldValue & 1) && !(flags & MM_MAP_PAGE_OVERWRITE)) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[bits 16]
|
||||
[org 0x1000]
|
||||
|
||||
; This is missing any fileSystem specific macros.
|
||||
; This is missing any file system specific macros.
|
||||
%define vesa_info 0x7000
|
||||
%define os_installation_identifier 0x7FF0
|
||||
%define temporary_load_buffer 0x9000
|
||||
|
@ -363,7 +363,184 @@ setup_elf:
|
|||
jne error_32
|
||||
cmp byte [ebx + 4],2
|
||||
je setup_elf_64
|
||||
cmp byte [ebx + 4],1
|
||||
jne error_32
|
||||
jmp setup_elf_32
|
||||
|
||||
setup_elf_32:
|
||||
mov dword [page_table_allocation_location],0x2000
|
||||
|
||||
; Check the ELF data is correct
|
||||
mov ebx,[kernel_buffer]
|
||||
mov esi,error_bad_kernel
|
||||
cmp byte [ebx + 5],1
|
||||
jne error_32
|
||||
cmp byte [ebx + 7],0
|
||||
jne error_32
|
||||
cmp byte [ebx + 16],2
|
||||
jne error_32
|
||||
cmp byte [ebx + 18],0x03
|
||||
jne error_32
|
||||
|
||||
; Find the program headers
|
||||
; EAX = ELF header, EBX = program headers
|
||||
mov eax,ebx
|
||||
mov ebx,[eax + 28]
|
||||
add ebx,eax
|
||||
|
||||
; ECX = entries, EDX = size of entry
|
||||
movzx ecx,word [eax + 44]
|
||||
movzx edx,word [eax + 42]
|
||||
|
||||
; Loop through each program header
|
||||
.loop_program_headers:
|
||||
push eax
|
||||
push ecx
|
||||
push edx
|
||||
push ebx
|
||||
|
||||
; Only deal with load segments
|
||||
mov eax,[ebx]
|
||||
cmp eax,1
|
||||
jne .next_entry
|
||||
|
||||
; Work out how many physical pages we need to allocate
|
||||
mov ecx,[ebx + 20]
|
||||
shr ecx,12
|
||||
inc ecx
|
||||
|
||||
; Get the starting virtual address
|
||||
mov eax,[ebx + 8]
|
||||
mov [.target_page],eax
|
||||
|
||||
; For every frame in the segment
|
||||
.frame_loop:
|
||||
xor ebx,ebx
|
||||
|
||||
; For every memory region
|
||||
.memory_region_loop:
|
||||
|
||||
; Check the region has enough pages remaining
|
||||
mov eax,[ebx + memory_map + 8]
|
||||
or eax,eax
|
||||
jz .try_next_memory_region
|
||||
|
||||
; Remove one page from the region
|
||||
mov eax,[ebx + memory_map + 4]
|
||||
or eax,eax
|
||||
jnz .try_next_memory_region ; Reject 64-bit pages.
|
||||
mov eax,[ebx + memory_map + 0]
|
||||
mov [.physical_page],eax
|
||||
add eax,0x1000
|
||||
mov [ebx + memory_map + 0],eax
|
||||
sub dword [ebx + memory_map + 8],1
|
||||
|
||||
jmp .found_physical_page
|
||||
|
||||
; Go to the next memory region
|
||||
.try_next_memory_region:
|
||||
add ebx,16
|
||||
mov eax,[load_memory_map.pointer]
|
||||
cmp ebx,eax
|
||||
jne .memory_region_loop
|
||||
mov esi,error_no_memory
|
||||
jmp error_32
|
||||
|
||||
; Map the page into virtual memory
|
||||
.found_physical_page:
|
||||
|
||||
; Make sure we have a page table
|
||||
mov eax,[.target_page]
|
||||
shr eax,22
|
||||
shl eax,2
|
||||
add eax,0xFFFFF000
|
||||
mov ebx,[eax]
|
||||
cmp ebx,0
|
||||
jne .has_pt
|
||||
mov ebx,[page_table_allocation_location]
|
||||
add ebx,page_directory
|
||||
or ebx,7
|
||||
mov [eax],ebx
|
||||
add dword [page_table_allocation_location],0x1000
|
||||
mov eax,cr3
|
||||
mov cr3,eax
|
||||
.has_pt:
|
||||
|
||||
; Map the page!
|
||||
mov eax,[.target_page]
|
||||
shr eax,12
|
||||
mov ebx,[.physical_page]
|
||||
or ebx,0x103
|
||||
shl eax,2
|
||||
add eax,0xFFC00000
|
||||
mov [eax],ebx
|
||||
mov ebx,[.target_page]
|
||||
invlpg [ebx]
|
||||
|
||||
; Go to the next frame
|
||||
add dword [.target_page],0x1000
|
||||
dec ecx
|
||||
or ecx,ecx
|
||||
jnz .frame_loop
|
||||
|
||||
; Restore the pointer to the segment
|
||||
pop ebx
|
||||
push ebx
|
||||
|
||||
; Clear the memory
|
||||
mov ecx,[ebx + 20]
|
||||
xor eax,eax
|
||||
mov edi,[ebx + 8]
|
||||
rep stosb
|
||||
|
||||
; Copy the memory
|
||||
mov ecx,[ebx + 16]
|
||||
mov esi,[ebx + 4]
|
||||
add esi,[kernel_buffer]
|
||||
mov edi,[ebx + 8]
|
||||
rep movsb
|
||||
|
||||
; Go to the next entry
|
||||
.next_entry:
|
||||
pop ebx
|
||||
pop edx
|
||||
pop ecx
|
||||
pop eax
|
||||
|
||||
add ebx,edx
|
||||
dec ecx
|
||||
or ecx,ecx
|
||||
jnz .loop_program_headers
|
||||
|
||||
jmp run_kernel32
|
||||
|
||||
.target_page: dd 0
|
||||
.physical_page: dd 0
|
||||
|
||||
run_kernel32:
|
||||
; Let the kernel use the memory that was used to store the executable
|
||||
xor eax,eax
|
||||
mov ebx,[load_memory_map.pointer]
|
||||
mov [memory_map + ebx + 4],eax
|
||||
mov [memory_map + ebx + 12],eax
|
||||
mov [memory_map + ebx + 16],eax
|
||||
mov [memory_map + ebx + 20],eax
|
||||
mov eax,[memory_map + ebx + 8]
|
||||
mov [memory_map + ebx + 24],eax
|
||||
mov eax,[memory_map + ebx + 12]
|
||||
mov [memory_map + ebx + 28],eax
|
||||
mov eax,[kernel_buffer]
|
||||
mov [memory_map + ebx],eax
|
||||
mov eax,[kernel_size]
|
||||
shr eax,12
|
||||
mov [memory_map + ebx + 8],eax
|
||||
|
||||
; Execute the kernel's _start function
|
||||
mov ebx,[kernel_buffer]
|
||||
mov ecx,[ebx + 24]
|
||||
xor edi,edi
|
||||
mov esi,1
|
||||
jmp ecx
|
||||
|
||||
setup_elf_64:
|
||||
; Check that the processor is 64-bit
|
||||
|
|
10
util/build.c
10
util/build.c
|
@ -2,14 +2,16 @@
|
|||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
#define TOOLCHAIN_PREFIX "x86_64-essence"
|
||||
#define TARGET_NAME "x86_64"
|
||||
#define TOOLCHAIN_HAS_RED_ZONE
|
||||
#define TOOLCHAIN_HAS_CSTDLIB
|
||||
#define QEMU_EXECUTABLE "qemu-system-x86_64"
|
||||
#else
|
||||
#define TOOLCHAIN_PREFIX "i686-elf"
|
||||
#define TARGET_NAME "x86_32"
|
||||
#define QEMU_EXECUTABLE "qemu-system-i386"
|
||||
#endif
|
||||
|
||||
#define WARNING_FLAGS \
|
||||
|
@ -519,7 +521,7 @@ void Run(int emulator, int log, int debug) {
|
|||
serialFlags[0] = 0;
|
||||
}
|
||||
|
||||
CallSystemF("%s %s qemu-system-x86_64 %s%s %s -m %d %s -smp cores=%d -cpu Haswell "
|
||||
CallSystemF("%s %s " QEMU_EXECUTABLE " %s%s %s -m %d %s -smp cores=%d -cpu Haswell "
|
||||
" -device qemu-xhci,id=xhci -device usb-kbd,bus=xhci.0,id=mykeyboard -device usb-mouse,bus=xhci.0,id=mymouse "
|
||||
" -netdev user,id=u1 -device e1000,netdev=u1 -object filter-dump,id=f1,netdev=u1,file=bin/net.dat "
|
||||
" %s %s %s %s %s %s %s ",
|
||||
|
@ -1397,7 +1399,9 @@ void DoCommand(const char *l) {
|
|||
LineCountFile("", "start.sh");
|
||||
|
||||
const char *folders[] = {
|
||||
"desktop/", "boot/x86/", "drivers/", "kernel/", "apps/", "apps/file_manager/", "shared/", "util/"
|
||||
"desktop/", "boot/x86/", "drivers/", "kernel/",
|
||||
"apps/", "apps/file_manager/", "shared/", "util/",
|
||||
"arch/", "arch/x86_32/", "arch/x86_64/",
|
||||
};
|
||||
|
||||
for (uintptr_t i = 0; i < sizeof(folders) / sizeof(folders[0]); i++) {
|
||||
|
|
Loading…
Reference in New Issue