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);
|
// 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/.
|
// 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.
|
// 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);
|
value |= (1 << 5) | (1 << 6);
|
||||||
|
|
||||||
if ((oldValue & 1) && !(flags & MM_MAP_PAGE_OVERWRITE)) {
|
if ((oldValue & 1) && !(flags & MM_MAP_PAGE_OVERWRITE)) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
[bits 16]
|
[bits 16]
|
||||||
[org 0x1000]
|
[org 0x1000]
|
||||||
|
|
||||||
; This is missing any fileSystem specific macros.
|
; This is missing any file system specific macros.
|
||||||
%define vesa_info 0x7000
|
%define vesa_info 0x7000
|
||||||
%define os_installation_identifier 0x7FF0
|
%define os_installation_identifier 0x7FF0
|
||||||
%define temporary_load_buffer 0x9000
|
%define temporary_load_buffer 0x9000
|
||||||
|
@ -363,7 +363,184 @@ setup_elf:
|
||||||
jne error_32
|
jne error_32
|
||||||
cmp byte [ebx + 4],2
|
cmp byte [ebx + 4],2
|
||||||
je setup_elf_64
|
je setup_elf_64
|
||||||
|
cmp byte [ebx + 4],1
|
||||||
jne error_32
|
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:
|
setup_elf_64:
|
||||||
; Check that the processor is 64-bit
|
; Check that the processor is 64-bit
|
||||||
|
|
10
util/build.c
10
util/build.c
|
@ -2,14 +2,16 @@
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 1
|
#if 0
|
||||||
#define TOOLCHAIN_PREFIX "x86_64-essence"
|
#define TOOLCHAIN_PREFIX "x86_64-essence"
|
||||||
#define TARGET_NAME "x86_64"
|
#define TARGET_NAME "x86_64"
|
||||||
#define TOOLCHAIN_HAS_RED_ZONE
|
#define TOOLCHAIN_HAS_RED_ZONE
|
||||||
#define TOOLCHAIN_HAS_CSTDLIB
|
#define TOOLCHAIN_HAS_CSTDLIB
|
||||||
|
#define QEMU_EXECUTABLE "qemu-system-x86_64"
|
||||||
#else
|
#else
|
||||||
#define TOOLCHAIN_PREFIX "i686-elf"
|
#define TOOLCHAIN_PREFIX "i686-elf"
|
||||||
#define TARGET_NAME "x86_32"
|
#define TARGET_NAME "x86_32"
|
||||||
|
#define QEMU_EXECUTABLE "qemu-system-i386"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define WARNING_FLAGS \
|
#define WARNING_FLAGS \
|
||||||
|
@ -519,7 +521,7 @@ void Run(int emulator, int log, int debug) {
|
||||||
serialFlags[0] = 0;
|
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 "
|
" -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 "
|
" -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 ",
|
" %s %s %s %s %s %s %s ",
|
||||||
|
@ -1397,7 +1399,9 @@ void DoCommand(const char *l) {
|
||||||
LineCountFile("", "start.sh");
|
LineCountFile("", "start.sh");
|
||||||
|
|
||||||
const char *folders[] = {
|
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++) {
|
for (uintptr_t i = 0; i < sizeof(folders) / sizeof(folders[0]); i++) {
|
||||||
|
|
Loading…
Reference in New Issue