diff --git a/build/build-temp-vm-uefi-1.sh b/build/build-temp-vm-uefi-1.sh index 5cf4ec13..2f584970 100755 --- a/build/build-temp-vm-uefi-1.sh +++ b/build/build-temp-vm-uefi-1.sh @@ -51,9 +51,15 @@ rm ../src/Home/Registry.ZC 2> /dev/null rm ../src/Home/MakeHome.ZC 2> /dev/null mount_tempdisk sudo cp -r ../src/* $TMPMOUNT -[ ! -d "limine" ] && git clone https://github.com/limine-bootloader/limine.git --branch=v3.0-branch-binary --depth=1 + +if [ ! -d "limine" ]; then + git clone https://github.com/limine-bootloader/limine.git --branch=v3.0-branch-binary --depth=1 + make -C limine +fi + sudo mkdir -p $TMPMOUNT/EFI/BOOT sudo cp limine/BOOTX64.EFI $TMPMOUNT/EFI/BOOT/BOOTX64.EFI +sudo cp limine/limine.sys $TMPMOUNT/ sudo cp ../zealbooter/zealbooter.elf $TMPMOUNT/Boot/ZealBooter.ELF umount_tempdisk @@ -69,8 +75,12 @@ if [ ! -d "ovmf" ]; then cd .. fi -echo "Testing..." -qemu-system-x86_64 -machine q35,accel=kvm -drive format=raw,file=$TMPDISK -m 1G -rtc base=localtime -bios ovmf/OVMF.fd -no-reboot -no-shutdown +./limine/limine-deploy $TMPDISK + +echo "Testing UEFI..." +qemu-system-x86_64 -machine q35,accel=kvm -drive format=raw,file=$TMPDISK -m 1G -rtc base=localtime -bios ovmf/OVMF.fd -smp 4 +echo "Testing BIOS..." +qemu-system-x86_64 -machine q35,accel=kvm -drive format=raw,file=$TMPDISK -m 1G -rtc base=localtime -smp 4 echo "Deleting temp folder..." rm -rf $TMPDIR diff --git a/src/Kernel/KStart16.ZC b/src/Kernel/KStart16.ZC index f90fa601..106b27b1 100755 --- a/src/Kernel/KStart16.ZC +++ b/src/Kernel/KStart16.ZC @@ -33,7 +33,7 @@ MEM_E820:: DU8 MEM_E820_ENTRIES_NUM * sizeof(CMemE820) DUP (0); MEM_PHYSICAL_SPACE:: DU64 0; SYS_GDT_PTR:: DU16 sizeof(CGDT) - 1; DU64 0; -SYS_PCI_BUSES:: DU16 256; +SYS_PCI_BUSES:: DU16 0; ALIGN 16, OC_NOP @@ -51,7 +51,7 @@ GDT_TR_RING3: DU8 MP_PROCESSORS_NUM * 16 DUP(0); #assert $$ - SYS_GDT == sizeof(CGDT) SYS_FONT_PTR:: DU32 0; - +/* SYS_FRAMEBUFFER:: SYS_FRAMEBUFFER_ADDR: DU8 sizeof(U8 *); SYS_FRAMEBUFFER_WIDTH: DU64 0; @@ -68,12 +68,9 @@ SYS_FRAMEBUFFER_BLUE_MASK_SHIFT: DU8 0; SYS_FRAMEBUFFER_UNUSED: DU8 0,0,0,0,0,0,0; SYS_FRAMEBUFFER_EDID_SIZE: DU64 0; SYS_FRAMEBUFFER_EDID_ADDR: DU8 sizeof(U8 *); - +*/ SYS_VBE_INFO:: DU8 sizeof(CVBEInfo) DUP(0); SYS_VBE_MODES:: DU8 sizeof(CVBEModeShort) * VBE_MODES_NUM DUP(0); - -ALIGN 16, OC_NOP -DU64 0x5439581381193aaf, 0x2a8a30e69ec9f845; SYS_VBE_FINAL_MODE:: DU8 sizeof(CVBEMode) DUP(0); SYS_VBE_FINAL_MODE_NUM::DU16 0; //mode number of final mode set #assert $$ - SYS_KERNEL == sizeof(CKernel) - sizeof(CZXE) diff --git a/src/Kernel/KStart32.ZC b/src/Kernel/KStart32.ZC index 2ffb36ba..987cc75c 100755 --- a/src/Kernel/KStart32.ZC +++ b/src/Kernel/KStart32.ZC @@ -98,12 +98,11 @@ CORE0_32BIT_INIT:: //Entry point for $LK,"BootRAM",A="MN:BootRAM"$. MOV FS, AX MOV GS, AX MOV SS, AX - MOV ESP, BOOT_RAM_LIMIT //Tmp Stack + //MOV ESP, BOOT_RAM_LIMIT //Tmp Stack //Patch abs addresses MOV ECX, U32 CPatchTableAbsAddr.abs_address_count[ESI] LEA ESI, U32 CPatchTableAbsAddr.abs_address[ESI] - @@05: LODSD ADD EAX, EDI ADD U32 [EAX], EDI diff --git a/src/Kernel/MultiProc.ZC b/src/Kernel/MultiProc.ZC index 528fd988..9a7c7cf3 100755 --- a/src/Kernel/MultiProc.ZC +++ b/src/Kernel/MultiProc.ZC @@ -96,7 +96,7 @@ CTSS *TSSNew(I64 cpu_num) tss->tr = offset(CGDT.tr) + cpu_num * 16; tss->tr_ring3= offset(CGDT.tr_ring3) + cpu_num * 16; - d = (0x80d8)(U8 *) + tss->tr; + d = (&sys_gdt)(U8 *) + tss->tr; d1 = d(U8 *) + 4; *d = 0x0000FFFF; *d1 = 0x008F8900; @@ -106,7 +106,7 @@ CTSS *TSSNew(I64 cpu_num) *d1++ = tss >> 32; *d1 = 0; - d = (0x80d8)(U8 *) + tss->tr_ring3; + d = (&sys_gdt)(U8 *) + tss->tr_ring3; d1 = d(U8 *) + 4; *d = 0x0000FFFF; *d1 = 0x008FE900; @@ -193,7 +193,6 @@ U0 MPAPICInit() RAXSet(Gs->tss->tr); LTR AX - if (Gs->num) { IntInit1; diff --git a/src/limine.cfg b/src/limine.cfg index 6d6d2091..56701749 100644 --- a/src/limine.cfg +++ b/src/limine.cfg @@ -1,6 +1,8 @@ TIMEOUT=2 +INTERFACE_RESOLUTION=1024x768 :ZealOS PROTOCOL=limine +RESOLUTION=1024x768 KERNEL_PATH=boot:///Boot/ZealBooter.ELF MODULE_PATH=boot:///Boot/Kernel.ZXE diff --git a/zealbooter/GNUmakefile b/zealbooter/GNUmakefile index 72671afa..6148ec08 100644 --- a/zealbooter/GNUmakefile +++ b/zealbooter/GNUmakefile @@ -41,6 +41,7 @@ override CFLAGS += \ -fno-stack-check \ -fno-pie \ -fno-pic \ + -Wno-address-of-packed-member \ -m64 \ -march=x86-64 \ -mabi=sysv \ diff --git a/zealbooter/lower.S b/zealbooter/trampoline.S similarity index 68% rename from zealbooter/lower.S rename to zealbooter/trampoline.S index 8abdb9dc..9e04fbb3 100644 --- a/zealbooter/lower.S +++ b/zealbooter/trampoline.S @@ -1,24 +1,24 @@ .section .text -.global lower -lower: - pushq $0x18 - addq $(1f - lower), %rax +.global trampoline +trampoline: + lgdt (%rcx) + + pushq $0x30 + addq $(1f - trampoline), %rax pushq %rax lretq .code32 1: - mov $0x20, %eax + mov $0x10, %eax mov %eax, %ds mov %eax, %es mov %eax, %fs mov %eax, %gs mov %eax, %ss - lgdt (%ecx) - mov %cr0, %eax btr $31, %eax mov %eax, %cr0 @@ -31,6 +31,7 @@ lower: mov %ebx, %eax mov $2, %ebx - mov $0x7c00, %esp jmp *%eax +.global trampoline_end +trampoline_end: diff --git a/zealbooter/zealbooter.c b/zealbooter/zealbooter.c index 07ab0a89..d810a258 100644 --- a/zealbooter/zealbooter.c +++ b/zealbooter/zealbooter.c @@ -28,6 +28,21 @@ static volatile struct limine_framebuffer_request framebuffer_request = { .revision = 0 }; +struct CZXE { + uint16_t jmp; + uint8_t module_align_bits; + uint8_t reserved; + uint32_t signature; + int64_t org; + int64_t patch_table_offset; + int64_t file_size; +} __attribute__((packed)); + +struct CDate { + uint32_t time; + int32_t date; +} __attribute__((packed)); + #define MEM_E820_ENTRIES_NUM 48 #define MEM_E820T_USABLE 1 @@ -37,9 +52,15 @@ static volatile struct limine_framebuffer_request framebuffer_request = { #define MEM_E820T_BAD_MEM 5 #define MEM_E820T_PERM_MEM 7 +struct CMemE820 { + uint8_t *base; + int64_t len; + uint8_t type, pad[3]; +} __attribute__((packed)); + struct CGDTEntry { uint64_t lo, hi; -}; +} __attribute__((packed)); #define MP_PROCESSORS_NUM 128 @@ -54,29 +75,32 @@ struct CGDT { struct CGDTEntry ds_ring3; struct CGDTEntry tr[MP_PROCESSORS_NUM]; struct CGDTEntry tr_ring3[MP_PROCESSORS_NUM]; -}; +} __attribute__((packed)); -struct CZXE { - uint16_t jmp; - uint8_t module_align_bits; - uint8_t reserved; - uint32_t signature; - int64_t org; - int64_t patch_table_offset; - int64_t file_size; -}; +struct CVBEInfo { + uint8_t signature[4]; + uint16_t version; + uint32_t oem, capabilities, video_modes; + uint16_t total_memory, software_revision; + uint32_t vendor, product_name, product_revision; + uint8_t reserved[222], oem_data[256]; +} __attribute__((packed)); -struct CDate { - uint32_t time; - int32_t date; -}; +struct CVBEModeShort { + uint16_t width, height, mode_num; + uint32_t max_pixel_clock; +} __attribute__((packed)); -struct CMemE820 { - uint8_t *base; - int64_t len; - uint8_t type; - uint8_t pad[3]; -}; +struct CVBEMode { + uint16_t attributes, pad0[7], pitch, width, height; + uint8_t pad1[3], bpp, pad2, memory_model, pad[12]; + uint32_t framebuffer; + uint16_t pad3[9]; + uint32_t max_pixel_clock; + uint8_t reserved[190]; +} __attribute__((packed)); + +#define VBE_MODES_NUM 32 struct CSysLimitBase { uint16_t limit; @@ -101,16 +125,20 @@ struct CKernel { uint8_t *base; } __attribute__((packed)) sys_gdt_ptr; uint16_t sys_pci_buses; - struct CGDT sys_gdt; + struct CGDT sys_gdt __attribute__((aligned(16))); uint32_t sys_font_ptr; - struct limine_framebuffer limine_fb; +// struct limine_framebuffer limine_fb; + struct CVBEInfo sys_vbe_info; + struct CVBEModeShort sys_vbe_modes[VBE_MODES_NUM]; + struct CVBEMode sys_vbe_mode; + uint16_t sys_vbe_mode_num; } __attribute__((packed)); #define BOOT_SRC_RAM 2 #define RLF_16BIT 0b01 #define RLF_VESA 0b10 -void lower(void); +extern symbol trampoline, trampoline_end; struct E801 { size_t lowermem; @@ -140,40 +168,38 @@ struct E801 get_E801(void) { return E801; } -struct CVBEMode { - uint16_t attributes, pad0[7], pitch, width, height; - uint8_t pad1[3], bpp, pad2, memory_model, pad[12]; - uint32_t framebuffer; - uint16_t pad3[9]; - uint32_t max_pixel_clock; - uint8_t reserved[190]; -} __attribute__((packed)); - void _start(void) { struct limine_file *kernel = module_request.response->modules[0]; - struct CKernel *CKernel = (void *)0x7c00; - memcpy(CKernel, kernel->address, kernel->size); + struct CKernel *CKernel = kernel->address; - struct CVBEMode *sys_vbe_mode; - for (uint64_t *p = (uint64_t *)CKernel; ; p++) { - if (*p != 0x5439581381193aaf) { + size_t trampoline_size = (uintptr_t)trampoline_end - (uintptr_t)trampoline; + + size_t boot_stack_size = 32768; + + uintptr_t final_address = (uintptr_t)-1; + for (size_t i = 0; i < memmap_request.response->entry_count; i++) { + struct limine_memmap_entry *entry = memmap_request.response->entries[i]; + + if (entry->type != LIMINE_MEMMAP_USABLE) { continue; } - p++; - if (*p != 0x2a8a30e69ec9f845) { - continue; + + if (entry->length >= ALIGN_UP(kernel->size + trampoline_size, 16) + boot_stack_size) { + final_address = entry->base; + break; } - p++; - sys_vbe_mode = (void *)p; - break; + } + if (final_address == (uintptr_t)-1) { + // TODO: Panic. Show something? + for (;;); } struct limine_framebuffer *fb = framebuffer_request.response->framebuffers[0]; - sys_vbe_mode->pitch = fb->pitch; - sys_vbe_mode->width = fb->width; - sys_vbe_mode->height = fb->height; - sys_vbe_mode->bpp = fb->bpp; - sys_vbe_mode->framebuffer = (uintptr_t)fb->address - hhdm_request.response->offset; + CKernel->sys_vbe_mode.pitch = fb->pitch; + CKernel->sys_vbe_mode.width = fb->width; + CKernel->sys_vbe_mode.height = fb->height; + CKernel->sys_vbe_mode.bpp = fb->bpp; + CKernel->sys_vbe_mode.framebuffer = (uintptr_t)fb->address - hhdm_request.response->offset; void *CORE0_32BIT_INIT; for (uint64_t *p = (uint64_t *)CKernel; ; p++) { @@ -189,26 +215,25 @@ void _start(void) { break; } + CORE0_32BIT_INIT -= (uintptr_t)kernel->address; + CORE0_32BIT_INIT += final_address; + CKernel->boot_src = BOOT_SRC_RAM; CKernel->boot_blk = 0; CKernel->boot_patch_table_base = (uintptr_t)CKernel + CKernel->h.patch_table_offset; - -// asm volatile ("jmp ." ::"a"(CKernel->boot_patch_table_base)); + CKernel->boot_patch_table_base -= (uintptr_t)kernel->address; + CKernel->boot_patch_table_base += final_address; CKernel->sys_run_level = RLF_VESA | RLF_16BIT; - CKernel->boot_base = (uintptr_t)&CKernel->jmp; - - CKernel->sys_gdt.boot_ds.lo = 0x00CF92000000FFFF; - CKernel->sys_gdt.boot_cs.lo = 0x00CF9A000000FFFF; - CKernel->sys_gdt.cs32.lo = 0x00CF9A000000FFFF; - CKernel->sys_gdt.cs64.lo = 0x00209A0000000000; - CKernel->sys_gdt.cs64_ring3.lo = 0x0020FA0000000000; - CKernel->sys_gdt.ds.lo = 0x00CF92000000FFFF; - CKernel->sys_gdt.ds_ring3.lo = 0x00CFF2000000FFFF; + CKernel->boot_base = (uintptr_t)&CKernel->jmp - (uintptr_t)kernel->address; + CKernel->boot_base += final_address; CKernel->sys_gdt_ptr.limit = sizeof(CKernel->sys_gdt) - 1; - CKernel->sys_gdt_ptr.base = (void *)&CKernel->sys_gdt; + CKernel->sys_gdt_ptr.base = (void *)&CKernel->sys_gdt - (uintptr_t)kernel->address; + CKernel->sys_gdt_ptr.base += final_address; + + CKernel->sys_pci_buses = 256; struct E801 E801 = get_E801(); CKernel->mem_E801[0] = E801.lowermem; @@ -239,13 +264,25 @@ void _start(void) { CKernel->mem_E820[i].type = our_type; } - struct limine_framebuffer *framebuffer = framebuffer_request.response->framebuffers[0]; - memcpy(&CKernel->limine_fb, framebuffer, sizeof(struct limine_framebuffer)); +// memcpy(&CKernel->limine_fb, framebuffer, sizeof(struct limine_framebuffer)); + void *sys_gdt_ptr = (void *)&CKernel->sys_gdt_ptr - (uintptr_t)kernel->address; + sys_gdt_ptr += final_address; - void *target_addr = (void *)lower - kernel_address_request.response->virtual_base; - target_addr += kernel_address_request.response->physical_base; + void *trampoline_phys = (void *)final_address + kernel->size; - asm volatile ("jmp *%0" :: "a"(target_addr), "b"(CORE0_32BIT_INIT), "c"(&CKernel->sys_gdt_ptr), "S"(CKernel->boot_patch_table_base), "D"(CKernel->boot_base) : "memory"); + uintptr_t boot_stack = ALIGN_UP(final_address + kernel->size + trampoline_size, 16) + boot_stack_size; + + memcpy(trampoline_phys, trampoline, trampoline_size); + memcpy((void *)final_address, CKernel, kernel->size); + + asm volatile ( + "mov %5, %%rsp;" + "jmp *%0" + : + : "a"(trampoline_phys), "b"(CORE0_32BIT_INIT), + "c"(sys_gdt_ptr), "S"(CKernel->boot_patch_table_base), + "D"(CKernel->boot_base), "r"(boot_stack) + : "memory"); __builtin_unreachable(); }