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
	
	 nakst
						nakst