Page 1 of 1

Problem with multiboot module

Posted: Fri Apr 03, 2020 6:21 pm
by nexos
Hello,
Currently I am working on an ELF loader for a POSIX compliant operating system named NexNix. I am loading the file as a module with GRUB. However, the e_ident member of the ELF header is 0 for some reason. This is also just a prototype loader and will be greatly improved on. Here is the code for the loader:

Code: Select all

void create_test_process(multiboot_info* bootinfo)
{
    elf32_hdr* p_hdr;
    elf32_hdr* buffer = (elf32_hdr*)bootinfo->moduleAddress;
    p_hdr = (elf32_hdr*)buffer;
    if(p_hdr->e_ident[EI_MAG0] == ELFMAG0)
    {
        int size = 8192;
        int entry = p_hdr->e_entry;
        for(int i = 0; i < size; i += 4096)
        {
            void* block = alloc_block();
            map_address(get_directory(), 0x08048000 + i, block, PTE_PRESENT | PTE_WRITEABLE | PTE_USER);
            memcpy(buffer, 0x08048000 + i, 4096);
        }
        void (*entry_point) () = (entry);
        entry_point();
    }
}
Thank you for your help

Re: Problem with multiboot module

Posted: Fri Apr 03, 2020 10:30 pm
by bzt
Hi,

I believe bootinfo does not contain the address of the module but a pointer to an array of modules (pointer, size and name) triplets. But I'm not very fond of Grub, so maybe someone can correct me on this. From the spec:

Code: Select all

  /* Are mods_* valid? */
  if (CHECK_FLAG (mbi->flags, 3))
    {
      multiboot_module_t *mod;
      int i;
      
      printf ("mods_count = %d, mods_addr = 0x%x\n",
              (int) mbi->mods_count, (int) mbi->mods_addr);
      for (i = 0, mod = (multiboot_module_t *) mbi->mods_addr;
           i < mbi->mods_count;
           i++, mod++)
        printf (" mod_start = 0x%x, mod_end = 0x%x, cmdline = %s\n",
                (unsigned) mod->mod_start,
                (unsigned) mod->mod_end,
                (char *) mod->cmdline);
    }
Second, why do you copy the module? Why don't you simply map the memory where it's already located? If it's aligned on frame boundary, I see no reason why to copy it.

Code: Select all

map_address(get_directory(), 0x08048000 + i, (char*)p_hdr + i, PTE_PRESENT | PTE_WRITEABLE | PTE_USER);
Cheers,
bzt

Re: Problem with multiboot module

Posted: Sat Apr 04, 2020 1:00 am
by kzinti
bzt is correct on both accounts:

1) "Module address" points to a "multiboot_module" or a "multiboot2_module" structure depending on which version of multiboot you are using:

Code: Select all

struct multiboot_module
{
    uint32_t mod_start;
    uint32_t mod_end;
    const char* string;
    uint32_t reserved;
};

struct multiboot2_module
{
    multiboot2_header_tag tag;
    uint32_t mod_start;
    uint32_t mod_end;
    char     string[];
};
2) There is no need to allocate memory and copy the modules. Assuming they are ELF files and each program segment is page-aligned, you can just map them directly (but you will have to allocate some extra pages if "memory size" > "file size" for some program headers. This typically happens for BSS data).

Re: Problem with multiboot module

Posted: Sat Apr 04, 2020 5:54 am
by nexos
I have tried changing it to use a structure, and that structure is valid, but the entry point address is 0xF0F0F0F, when it should be 0x8048060 according to readelf. That part looks like

Code: Select all

multiboot_module* modules = (multiboot_module*)bootinfo->moduleAddress;
    elf32_hdr* p_hdr = (elf32_hdr*)modules->mod_start;
    printf("%x\n",p_hdr->e_entry);
Thank you for your help

Re: Problem with multiboot module

Posted: Sat Apr 04, 2020 7:06 am
by nexos
I also tried loading a text file as a module, and that didn't work.

Re: Problem with multiboot module

Posted: Sat Apr 04, 2020 12:05 pm
by kzinti
Given the limited information you are providing us with, it's hard to give you more help.

If you are unable to read a text file loaded as a module at the expected location, start by debugging why this is so.