I cloned your repository. I had to rebuild gnu-efi first (the files you had didn't work on my system). I made the bootloader after that without a problem. When I went to build your kernel I got linker errors because memcpy and memzero were defined more than once. There was a reason for this since you defined them in memory.h. I modified memory.h to be:
Code:
#ifndef _MEMORY_H
#define _MEMORY_H
#include "stddef.h"
#include "stdint.h"
#include "efimem.h"
#define UEFI_MMAP_SIZE 0x4000
typedef struct _mmap {
uint64_t nbytes;
uint8_t buffer[UEFI_MMAP_SIZE];
uint64_t mapkey;
uint64_t descsize;
uint32_t desc_version;
} MEMORY_MAP;
extern uint64_t getmemsize(EFI_MEMORY_DESCRIPTOR* mmap, uint64_t mmapentries, uint64_t mmapdescsize);
extern void memzero(void* s, uint64_t n);
extern void memcpy(void *dest, void *src, size_t n);
#endif
I then moved the functions to memory.c:
Code:
#include "memory.h"
uint64_t getmemsize(EFI_MEMORY_DESCRIPTOR* mmap, uint64_t mmapentries, uint64_t mmapdescsize) {
static uint64_t memsizebytes = 0;
if (memsizebytes > 0) return memsizebytes;
for (int i = 0; i < mmapentries; i++) {
EFI_MEMORY_DESCRIPTOR* desc = (EFI_MEMORY_DESCRIPTOR*)((uint64_t)mmap + (i * mmapdescsize));
memsizebytes += desc->numpages * 4096;
}
return memsizebytes;
}
void memzero(void* s, uint64_t n) {
for (int i = 0; i < n; i++) {
((uint8_t*)s)[i] = 0;
}
}
void memcpy(void *dest, void *src, size_t n) {
uint8_t *pdest = (uint8_t*) dest;
uint8_t *psrc = (uint8_t*) src;
for (unsigned int i = 0; i < n; i++) {
pdest[i] = psrc[i];
}
}
I also had an error in the Makefile while using mformat. I had to change:
Code:
mformat -i $(BUILDDIR)/$(OSNAME).img -f 1440 ::
to:
Code:
mformat -i $(BUILDDIR)/$(OSNAME).img ::
Once I was able to build up everything and run it, it worked fine. In fact I went back and modified gdt.h with the 0x1000 alignment and old GDT you had and it still worked. I modified kernel.c and put an `asm("hlt")` right after the load_gdt . Ran it and went into the QEMU monitor and all the segment registers were loaded correctly (including CS).
I'm curious what environment you build all this in. Your Makefile suggest it it being done in some kind of Linux/Unix type environment but when you run QEMU you are doing it from Windows.
The build I made was on WSL2 (Windows Subsystem for Linux v2) using Ubuntu 22.04 using GCC 11.4.0 and QEMU 7.2.0. I run QEMU from inside WSL2 as well.