#UEFI Heap allocation seems not to work anymore

1 messages ยท Page 1 of 1 (latest)

royal cave
#

line 32 is empty and I don't see anything egregiously wrong

tall sun
#

ooops, forgot to push... ๐Ÿ˜… . Now it's there.

royal cave
#

Ah, I see. uefi.pool_allocator is only allowed when boot services are enabled because it's implemented with boot_services.AllocatePool()

#

when you call exitBootServices you're leaving the environment where most of std.os.uefi is allowed

#

after you call exitBootServices you're intended to take the memory map and create your own allocator

tall sun
#

Ah, now I understand! Thank you very much!

open barn
#

yeah usually you take from UEFI what you want (files, GOP, RSDP, memory map, etc) and you get out. I prefer to use AllocatePages instead so it's aligned to 0x1000 and you can manage it really easy in your kernel afterwards

tall sun
#

Oh thank you, I'll try that.

tall sun
#

Now when I try to allocate a page (line 32 of https://codeberg.org/hi7/lunaos-zig/src/branch/main/src/main.zig):

    var mem: [*]align(4096) u8 = undefined;
    var status = boot_services.allocatePages(uefi.tables.AllocateType.AllocateAnyPages, uefi.tables.MemoryType.LoaderData, 1, &mem);

Status is not showing me what went wrong. QEMU shows me this, from which I can not infer the cause:

KVM internal error. Suberror: 1
extra data[0]: 0x0000000000000001
extra data[1]: 0x9090909090900001
extra data[2]: 0x9090909090909090
extra data[3]: 0x0000000000000400
extra data[4]: 0x0000000100000014
extra data[5]: 0x00000000000b0000
extra data[6]: 0x0000000000000000
extra data[7]: 0x0000000000000000
emulation failure
RAX=000000004743759e RBX=000000000629b1c8 RCX=0000000000000000 RDX=0000000000000002
RSI=0000000006958018 RDI=0000000006958018 RBP=0000000007f106f0 RSP=0000000007f10668
R8 =0000000000000001 R9 =0000000007f107c8 R10=0000000000000000 R11=0000000007f107d0
R12=0000000000000000 R13=0000000006e79be0 R14=0000000006e787bc R15=0000000006957f98
RIP=00000000000affff RFL=00000003 [------C] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0030 0000000000000000 ffffffff 00c09300 DPL=0 DS   [-WA]
CS =0038 0000000000000000 ffffffff 00a09b00 DPL=0 CS64 [-RA]
SS =0030 0000000000000000 ffffffff 00c09300 DPL=0 DS   [-WA]
DS =0030 0000000000000000 ffffffff 00c09300 DPL=0 DS   [-WA]
FS =0030 0000000000000000 ffffffff 00c09300 DPL=0 DS   [-WA]
GS =0030 0000000000000000 ffffffff 00c09300 DPL=0 DS   [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT=     00000000079de000 00000047
IDT=     0000000007471018 00000fff
CR0=80010033 CR2=0000000000000000 CR3=0000000007c01000 CR4=00000668
DR3=0000000000000000 
DR6=00000000ffff0ff0 DR7=0000000000000400
EFER=0000000000000d00
Code=00 01 00 21 00 01 00 22 00 01 00 22 00 01 00 22 00 01 00 22 <00> ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
open barn
#

can you try without KVM?

#

or not faulting at all?

#

I suggest you start using serial 0xE9 to debug, it's more useful

tall sun
#

Ok, without KVM and serial to stdio I got:

BdsDxe: failed to load Boot0001 "UEFI QEMU DVD-ROM QM00003 " from PciRoot(0x0)/Pci(0x1,0x1)/Ata(Secondary,Master,0x0): Not Found
BdsDxe: loading Boot0002 "UEFI QEMU HARDDISK QM00001 " from PciRoot(0x0)/Pci(0x1,0x1)/Ata(Primary,Master,0x0)
BdsDxe: starting Boot0002 "UEFI QEMU HARDDISK QM00001 " from PciRoot(0x0)/Pci(0x1,0x1)/Ata(Primary,Master,0x0)
!!!! X64 Exception Type - 06(#UD - Invalid Opcode)  CPU Apic ID - 00000000 !!!!
RIP  - 00000000000B0001, CS  - 0000000000000038, RFLAGS - 0000000000000803
RAX  - 000000004743759E, RCX - 0000000000000000, RDX - 0000000000000002
RBX  - 00000000062962C8, RSP - 0000000007F10668, RBP - 0000000007F106F0
RSI  - 000000000695A018, RDI - 000000000695A018
R8   - 0000000000000001, R9  - 0000000007F107C8, R10 - 0000000000000000
R11  - 0000000007F107D0, R12 - 0000000000000000, R13 - 0000000006E79BE0
R14  - 0000000006E787BC, R15 - 0000000006957F98
DS   - 0000000000000030, ES  - 0000000000000030, FS  - 0000000000000030
GS   - 0000000000000030, SS  - 0000000000000030
CR0  - 0000000080010033, CR2 - 0000000000000000, CR3 - 0000000007C01000
CR4  - 0000000000000668, CR8 - 0000000000000000
DR0  - 0000000000000000, DR1 - 0000000000000000, DR2 - 0000000000000000
DR3  - 0000000000000000, DR6 - 00000000FFFF0FF0, DR7 - 0000000000000400
GDTR - 00000000079DE000 0000000000000047, LDTR - 0000000000000000
IDTR - 0000000007471018 0000000000000FFF,   TR - 0000000000000000
FXSAVE_STATE - 0000000007F102C0
!!!! Can't find image information. !!!!

Invalid Opcode is a little surprising...

open barn
#

are you using -dint?

#

-d int sorry

#

qemu-system-x86_64: -drive format=raw,file=fat:rw:esp: Could not read directory esp

#

I am trying to run the project but this error pops @tall sun

#

is there any way to get the whole running workflow automatized?

tall sun
#

Oh esp/efi/boot folders are not in the repository. If your create them with mkdir and make a symbolic link (see README) it
should work.

#

I run it with zig build run

#

I've pushed the QEMU parameter updates.

#

When I run it with -d int I got a lot of output... but the last is still Invalid Opcode

open barn
#

yeah

#

you have to check for the first check_exception

#

I'd suggest using 0xE9 for debugging

#

it's way more comfortable than drawing to the screen

#

you can't use gdb yet because the UEFI executable is PE, unless you like debugging asm

#

instead of -serial stdio, you have to use -debugcon stdio

#

then write a writer

#
    const bytes_left = asm volatile (
        \\rep outsb
        : [ret] "={rcx}" (-> usize),
        : [dest] "{dx}" (port),
          [src] "{rsi}" (bytes.ptr),
          [len] "{rcx}" (bytes.len),
        : "rsi", "rcx"
    );

    return bytes.len - bytes_left;
}
#
pub const E9Writer = std.io.Writer(void, E9WriterError, writeToE9);
pub const writer = E9Writer{ .context = {} };

fn writeToE9(_: void, bytes: []const u8) E9WriterError!usize {
    return arch.io.writeBytes(0xe9, bytes);
}
#

and you can use writer.print like if it were std.io.getStdout().writer().print

#

way easier ๐Ÿ™‚

#

arch.io.writeBytes is the writeBytes function I pasted earlier

#

-debugcon stdio is a magic thing which will tell qemu to write to stdio every byte you send to the 0xe9 port

tall sun
#

Cool I try that! Thank you so much!

open barn
#

no problem, happy to help

#

also come to #os-dev ๐Ÿ™‚ we're happy to answer questions like that