0

I am writing an early kernel heap to manage some memory allocations before the final heap is operational. When I assign an address(not used by anything else) to my struct pointer it works, the problem comes when I try to assign values to the struct members.

Before you answer, take in mind that I do not have any kind of C library which I can use. Debugging was done with QEMU and gdb through remote.

//The struct
typedef struct mem_block{
    mblock_t *prev;
    boolean used;
    size_t size;
    mblock_t *next;
} mblock_t;

//The file-local pointer(before its init)
mblock_t *eheap=NULL;


//Function that assigns the values
mblock_t *init_early_heap(address_t start, size_t size){
    if(eheap==NULL){
        if(size < sizeof(mblock_t)){
            PANIC("Available memory below EHEAP requirement");
        }
        eheap = (mblock_t*)HEAP_START_ADDRESS;
        eheap->prev = NULL;
        eheap->next = NULL;
        eheap->size = (size_t)(size - sizeof(mblock_t));
        eheap->used = false;
        print("\nCreated Early Heap at ");
        print_hex_long(eheap);
        print("\nSize in bytes: ");
        print(itos(eheap->size));NL;
    }
    return eheap;
}

After the function returns, I get a pointer pointing at address 0xC0000000 and untouched members as eheap->size is 0(size parameter in the function is NOT 0).

Blackburn
  • 48
  • 4
  • Can you share self-contain program to demonstrate the problem ? – dash-o Oct 06 '19 at 18:54
  • No program, this is almost bare-metal code(and more than 10 files w/o headers only to serve this function). Can you be more specific please? Thank you. – Blackburn Oct 06 '19 at 18:59
  • Your C looks OK. Does it print correctly? If so, the problem is not where you think it is. BTW, you could use C11 designated initializers to make a single assignment to `*eheap`. – James K. Lowden Oct 06 '19 at 19:27
  • Would you consider putting your project on something like Github so I can look at it? – Michael Petch Oct 06 '19 at 19:30
  • My repo is not organized enough(bad idea for now). For @james-k-lowden the printing works ok, the whole trace to the problem was debugged. – Blackburn Oct 06 '19 at 19:43
  • Problem found: Cannot read whole address space (A20 on) in QEMU, works correctly with bit lower addresses. – Blackburn Oct 06 '19 at 19:45
  • Please make your finding an answer and mark it. This will save us all a lot of time. – the busybee Oct 06 '19 at 19:48

1 Answers1

0

Problem found: Cannot read whole address space (A20 on) in QEMU, works correctly with bit lower addresses. The C code above is correct, now the problem remains with QEMU/GRUB.

Blackburn
  • 48
  • 4
  • If you are using GRUB/Multiboot or QEMU's `-kernel` option then A20 is ON so the entire 4GiB address space is available (how much is usable is a different matter). Something else is likely wrong in your code. Are you using paging or not? I seem to recall that in QEMU that the PCI memory addresses start around physical address 0xc0000000. – Michael Petch Oct 06 '19 at 20:11
  • A20 is on because I use grub as a bootloader. No paging is being used at this time. I want to have a functional heap before I implement paging. – Blackburn Oct 07 '19 at 09:32
  • If you ever cleanup your project and add it to github (I'm not judgemental if you don't clean it up), I might be able to eyeball the problem. I suspect the problem is trivial although without seeing all the code / build process it is a guessing game. – Michael Petch Oct 07 '19 at 10:17
  • I was able to compile and build your kernel to the file ZBU_cmake.bin. When I run it in QEMU it does run. I'm wondering how I'd know if there was the problem you describe (I need to know how it is failing, and what you expected to happen). The last thing displayed on the screen is `Created Early Heap at 0x0012f5f8` `Size in bytes -1112716` and then the letter `v` alone on the next line by itself. – Michael Petch Oct 07 '19 at 15:07
  • I should let you know you don't need to enable A20 yourself if using Multiboot. Multiboot guarantees as part of the spec that A20 is enabled. – Michael Petch Oct 07 '19 at 15:08
  • The size was fixed(inverted difference). I know that grub enables a20 for me, that is old code from when i was making my own bootloader... Here is the last boot https://ibb.co/ncFBLz8 – Blackburn Oct 07 '19 at 19:07
  • Before I go looking at the code throughly what was the value of size you were expecting? – Michael Petch Oct 07 '19 at 19:18
  • The size always depends of the available upper memory: `size = size - (uint32) &end;` – Blackburn Oct 07 '19 at 19:23