Hi,
actually i'm trying to develop simple os with multitasking on UEFI(EDK2) device and I have few questions.
1) How do protocols works? For example, I need to load kernel by LoadImage but that function needs EFI_DEVICE_PATH_PROTOCOL, how i can get it?
2) LoadImage is a Boot Service. After ExitBootServices I lost that, so is there a simple way to load PE file to memmory or keep Boot Services functions?
Own OS UEFI
Re: Own OS UEFI
The documentation is good enough, and there are plenty of working examples on this. Pick one. In short you have a UUID for a service, you locate it's handler. Using that handler you can reference the service's properties and call it's methods.adsko wrote:Hi,
actually i'm trying to develop simple os with multitasking on UEFI(EDK2) device and I have few questions.
1) How do protocols works? For example, I need to load kernel by LoadImage but that function needs EFI_DEVICE_PATH_PROTOCOL, how i can get it?
Code: Select all
EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;
EFI_STATUS status = EFI_SUCCESS;
status = LibLocateProtocol(&GraphicsOutputProtocolUUID, (void **)&gop);
if (EFI_ERROR(status))
return NULL;
// get framebuffer address from GOP property
ptr=(void*)gop->Mode->FrameBufferBase;
No. The sole purpose of ExitBootServices is to free resources allocated by Boot Services. But why do you need LoadImage in your kernel? You should have your own disk and filesystem driver.adsko wrote: 2) LoadImage is a Boot Service. After ExitBootServices I lost that, so is there a simple way to load PE file to memmory or keep Boot Services functions?
Re: Own OS UEFI
Thanks for response.
Probably yes, but I dont have so much time to write own filesystem driver so i think about keep LoadImage after ExitBootServices.bzt wrote:No. The sole purpose of ExitBootServices is to free resources allocated by Boot Services. But why do you need LoadImage in your kernel? You should have your own disk and filesystem driver.
Re: Own OS UEFI
Well, you cannot do that. After ExitBootServices no UEFI memory allocation will be done, which is (obviously) a requirement for LoadImage.adsko wrote: Probably yes, but I dont have so much time to write own filesystem driver so i think about keep LoadImage after ExitBootServices.
Btw, it does not require much time to write a very simple filesystem driver (3 minutes if I'm tired). I'd suggest to put all of your files in an archive (cpio or tar), load that with LoadImage and later in your kernel look up files in the archive.
Code: Select all
unsigned char *tar_getfile(unsigned char *ptr, char *filename)
{
int k=strlen((unsigned char*)filename);
while(!memcmp(ptr+257,"ustar",5)){
int fs=oct2bin(ptr+0x7c,11);
if(!memcmp(ptr, kernel, k+1)){
return (unsigned char*)(ptr+512);
}
ptr+=(((fs+511)/512)+1)*512;
}
return NULL;
}
Re: Own OS UEFI
I have another problem.
After ExitBootServices, I want to set my own GDT, so I've crated a simple array with five descriptors and 4gb limit for each. After that I've created 48bit GDTR where I've set a limit and an address, finally I've called asm code which should set GDTR and make a long jump. But after a long jump QEMU throw error.
My asm code:
where gp is:
After ExitBootServices, I want to set my own GDT, so I've crated a simple array with five descriptors and 4gb limit for each. After that I've created 48bit GDTR where I've set a limit and an address, finally I've called asm code which should set GDTR and make a long jump. But after a long jump QEMU throw error.
Code: Select all
qemu: fatal: Trying to execute code outside RAM or ROM at 0x000b0000
EAX=065859a0 EBX=065859a0 ECX=00000092 EDX=00000002
ESI=0705ea90 EDI=00000000 EBP=07fafd3c ESP=07fafce4
EIP=000affde EFL=00000086 [--S--P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0008 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0008 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
DS =0008 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
FS =0008 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
GS =0008 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT= 065859a8 00000017
IDT= 07c5d010 000007ff
CR0=40000033 CR2=00000000 CR3=00000000 CR4=00000648
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=065859a0 CCD=065859b7 CCO=ADDB
EFER=0000000000000000
FCW=027f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000
XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000
XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000
XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000
Code: Select all
__asm__ (
"cli \n"
"lgdt (%0) \n"
"ljmp $0x08, $complete_flush \n"
"complete_flush: \n"
"movw $0x10, %%ax \n"
"movw %%ax, %%ds \n"
"movw %%ax, %%es \n"
"movw %%ax, %%fs \n"
"movw %%ax, %%gs \n"
"movw %%ax, %%ss \n"
"ret\n\t"
:
: "b" (&gp), "i"(0x08)
);
Code: Select all
struct gdt_ptr
{
unsigned short limit;
unsigned int base;
} __attribute__((packed));
Re: Own OS UEFI
I would also interested in the get question, i me too try to install get and idt based on uefi but with no success yet.
But in my case I have three loader one that is the main uefi loader that load another uefi program that set up different think and than load and start the kernel that is in a DLL.
But in my case I have three loader one that is the main uefi loader that load another uefi program that set up different think and than load and start the kernel that is in a DLL.
- crunch
- Member
- Posts: 81
- Joined: Wed Aug 31, 2016 9:53 pm
- Libera.chat IRC: crunch
- Location: San Diego, CA
Re: Own OS UEFI
The GDT base address looks bogus to me. However the limit appears to be the correct value. Is your GDT aligned to a 16 byte boundary?adsko wrote:I have another problem.
After ExitBootServices, I want to set my own GDT, so I've crated a simple array with five descriptors and 4gb limit for each. After that I've created 48bit GDTR where I've set a limit and an address, finally I've called asm code which should set GDTR and make a long jump. But after a long jump QEMU throw error.Code: Select all
qemu: fatal: Trying to execute code outside RAM or ROM at 0x000b0000 EAX=065859a0 EBX=065859a0 ECX=00000092 EDX=00000002 ESI=0705ea90 EDI=00000000 EBP=07fafd3c ESP=07fafce4 EIP=000affde EFL=00000086 [--S--P-] CPL=0 II=0 A20=1 SMM=0 HLT=0 ES =0008 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-] SS =0008 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] DS =0008 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] FS =0008 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] GS =0008 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy GDT= 065859a8 00000017
EDIT: just saw you wrote that you have 5 descriptors. Which means the limit is also wrong.
I haven't written any UEFI code so I'm out of my depth here. Try doing lgdt and then just hlt'ing, and check the GDTR value qemu
Some of my open-source projects:
Ext2/ELF32 bootloader
Lightweight x86 assembler, designed to be portable for osdev
Scheme in under 1000 lines of C
Ext2/ELF32 bootloader
Lightweight x86 assembler, designed to be portable for osdev
Scheme in under 1000 lines of C
- dchapiesky
- Member
- Posts: 204
- Joined: Sun Dec 25, 2016 1:54 am
- Libera.chat IRC: dchapiesky
Re: Own OS UEFI
Plagiarize. Plagiarize. Let not one line escape thine eyes...