Initrd & General

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
deleted
Member
Member
Posts: 82
Joined: Mon Jul 21, 2014 7:23 pm

Initrd & General

Post by deleted »

Hello!

So, I finally got somewhere, with a disk image, and an Initial Ramdisk. The problem is, when I boot up from the emulator (QEMU) (with grub), It says I have 0 files on the initrd.

Does anyone else have this issue? Any ideas?

Here's my grub.cfg file:

Code: Select all

set timeout=0
set default=0

menuentry "Yoda" {
    multiboot /kernel
    module /initrd /initrd
    boot
}
Yes: 1) I am a star wars junkie, 2) both /kernel and /initrd are binary files, the initrd is the initrd.img file without the .img extension.

Thanks!
User avatar
max
Member
Member
Posts: 616
Joined: Mon Mar 05, 2012 11:23 am
Libera.chat IRC: maxdev
Location: Germany
Contact:

Re: Initrd & General

Post by max »

Heyho,

in "It says I have 0 files on the initrd.", who is "it"? How do you use the initrd multiboot module that GRUB loads for you?

Greets,
Max
User avatar
deleted
Member
Member
Posts: 82
Joined: Mon Jul 21, 2014 7:23 pm

Re: Initrd & General

Post by deleted »

Thank for the reply.

I am trying to use James Malloy's tutorial on the VFS and InitRD. If you want, my code is at http://github.com/BiggerOnTheInside/Boom. I belive there is a binary file uploaded, and when run it shows what's happening (it doesn't use grub, but it does show the same thing).

Also, on a side note. I don't think my InitRD header is working. When I attempt to load it, i receive an ugly page fault from the isrs.

Thus, I currently have paging turned off (let me know if this is a problem). I have isolated the paging error, and it appears to be caused when the memory allocation method (for the InitRD root, I belive it is, file system header).

Thanks for any help!
User avatar
deleted
Member
Member
Posts: 82
Joined: Mon Jul 21, 2014 7:23 pm

Re: Initrd & General

Post by deleted »

But to answer your question, the "it" is my console, before it outputs the name and data of files, I set it to check if there were any files loaded, and if not to let me know.
User avatar
deleted
Member
Member
Posts: 82
Joined: Mon Jul 21, 2014 7:23 pm

Re: Initrd & General

Post by deleted »

Any ideas Max?
User avatar
iansjack
Member
Member
Posts: 4707
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Initrd & General

Post by iansjack »

I would say that it is a mistake to turn paging off to avoid the page error. It means that something is obviously not doing what you think it should; the exception allows you to locate this error. You should run the program under a debugger, single-step through the code in question and inspect the memory and registers to see what is happening.
User avatar
Roman
Member
Member
Posts: 568
Joined: Thu Mar 27, 2014 3:57 am
Location: Moscow, Russia
Contact:

Re: Initrd & General

Post by Roman »

Is it the failing line?

Code: Select all

ASSERT(mboot_ptr->mods_count > 0);
Are you sure, your MB header is correct?
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
- Alan Kay
User avatar
iansjack
Member
Member
Posts: 4707
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Initrd & General

Post by iansjack »

Surely an ASSERT can't fail, as such, presuming that the OS supports the concept of stderr. ASSERT tests whether the enclosed statement would fail and prints the appropriate error message if it would.

On the other hand, I can't see anywhere in the source where the OP has implemented the functions in stderr (but I may just not have looked closely enough).
User avatar
Roman
Member
Member
Posts: 568
Joined: Thu Mar 27, 2014 3:57 am
Location: Moscow, Russia
Contact:

Re: Initrd & General

Post by Roman »

iansjack wrote:Surely an ASSERT can't fail, as such, presuming that the OS supports the concept of stderr. ASSERT tests whether the enclosed statement would fail and prints the appropriate error message if it would.

On the other hand, I can't see anywhere in the source where the OP has implemented the functions in stderr (but I may just not have looked closely enough).
He said, "it" says, that mod_cnt is zero. I've asked, if it's the line reporting the problem.
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
- Alan Kay
User avatar
deleted
Member
Member
Posts: 82
Joined: Mon Jul 21, 2014 7:23 pm

Re: Initrd & General

Post by deleted »

Roman,

Here is my code so you can see what is happening with the "no files" alert:

Code: Select all

puts("Now starting 'Yoda' OS, Pre-Alpha 0.0.2. Copyright 2015 Walt Pach, all rights reserved.\n\n");
    
    PRINT("Setting up system boot information...");
    
    DEBUG("Checking multiboot header...");
    ASSERT(mboot_ptr->mods_count > 0);
    DEBUG("Multiboot header successfuly checked.");
    
    
    DEBUG("Allocating memory for Initial Ramdisk location object...");
    u32int initrd_location = mboot_ptr->mods_addr;//malloc(sizeof(mboot_ptr->mods_addr));
    DEBUG_HEX("Memory allocation successful. Location = ", initrd_location);
    
    DEBUG("Allocating memory for Initial Ramdisk end location object...");
    u32int initrd_end = mboot_ptr->mods_addr+4;//malloc(sizeof(mboot_ptr->mods_addr + 4));
    DEBUG_HEX("Memory allocation successful. End location = ", initrd_end);

   // initrd_location = mboot_ptr->mods_addr;
    DEBUG_HEX("Initial Ramdisk location (from multiboot) = ", initrd_location);
    
    //initrd_end = mboot_ptr->mods_addr+4;
    DEBUG_HEX("Initial Ramdisk end location (from algorithm) = ", initrd_end);
    
    // Don't trample our module with placement accesses, please!
    placement_address = initrd_end;
    DEBUG_HEX("Placement address = ", initrd_end);
    
    //initialise_paging();
    
    PRINT("Initialising filesystem root...");
    fs_root = initialise_initrd(initrd_location);
    PRINT("Done initialising filesystem root.");
    
    int i = 0;
    struct dirent *node = 0;
    while ( (node = readdir_fs(fs_root, i)) != 0)
    {
        puts("Found file ");
        puts(node->name);
        fs_node_t *fsnode = finddir_fs(fs_root, node->name);
        
        if ((fsnode->flags&0x7) == FS_DIRECTORY)
            puts("\n\t(directory)\n");
        else
        {
            puts("\n\t contents: \"");
            char buf[256];
            u32int sz = read_fs(fsnode, 0, 256, buf);
            int j;
            for (j = 0; j < sz; j++)
                putch(buf[j]);
            
            puts("\"\n");
        }
        i++;
    }
Here is my code for the initialise_initrd function (where it trips up and throws a page fault):

Code: Select all

fs_node_t *initialise_initrd(u32int location){
    PRINT("Starting initialisation of Initial Ramdisk...");
    
    PRINT("Setting Initial Ramdisk header and file headers.");
    initrd_header = (initrd_header_t *)location;
    PRINT_HEX("Initrd header at location: ", initrd_header);

    file_headers = (initrd_file_header_t *) (location + sizeof(initrd_header_t));
    PRINT_HEX("File headers at location: ", file_headers);
    
    PRINT("Setting initrd root.");
    initrd_root = (fs_node_t*)malloc(sizeof(fs_node_t));
    
    PRINT("Copying initrd name.");
    strcpy(initrd_root->name, "initrd");
    
    PRINT("Setting flags and operations of initrd_root.");
    initrd_root->mask = initrd_root->uid = initrd_root-> gid = initrd_root->inode = initrd_root->length = 0;
    initrd_root->flags = FS_DIRECTORY;
    initrd_root->read = 0;
    initrd_root->write = 0;
    initrd_root->open = 0;
    initrd_root->close = 0;
    initrd_root->readdir = &initrd_readdir;
    initrd_root->finddir = &initrd_finddir;
    initrd_root->ptr = 0;
    initrd_root->impl = 0;

    PRINT("Allocating memory for initrd_dev.");
    initrd_dev = (fs_node_t*)malloc(sizeof(fs_node_t));
    PRINT_HEX("Memory allocated to: ", initrd_dev);
    
    PRINT("Setting name of initrd_dev.");
    strcpy(initrd_dev->name, "dev");

    PRINT("Settings flags and operations of initrd_dev.");
    initrd_dev->mask = initrd_dev->uid = initrd_dev->gid = initrd_dev->inode = initrd_dev->length = 0;
    initrd_dev->flags = FS_DIRECTORY;
    initrd_dev->read = 0;
    initrd_dev->write = 0;
    initrd_dev->open = 0;
    initrd_dev->close = 0;
    initrd_dev->readdir = &initrd_readdir;
    initrd_dev->finddir = &initrd_finddir;
    initrd_dev->ptr = 0;
    initrd_dev->impl = 0;

    PRINT("Allocating memory for root nodes.");
    
    
    PRINT_DEC("Number of files: ", initrd_header->nfiles);
    
    root_nodes = (fs_node_t*)malloc(sizeof(fs_node_t) * initrd_header->nfiles);
    PRINT_HEX("Memory allocated to: ", initrd_dev);
    
    PRINT("Setting number of root nodes.");
    nroot_nodes = initrd_header->nfiles;

    int i;

    for(i = 0; i < initrd_header->nfiles; i++){
        file_headers[i].offset += location;
        
        strcpy(root_nodes[i].name, &file_headers[i].name);

        root_nodes[i].mask = root_nodes[i].uid = root_nodes[i].gid = 0;
        root_nodes[i].length = file_headers[i].length;
        root_nodes[i].inode = i;
        root_nodes[i].flags = FS_FILE;
        root_nodes[i].read = &initrd_read;
        root_nodes[i].write = 0;
        root_nodes[i].readdir = 0;
        root_nodes[i].finddir = 0;
        root_nodes[i].open = 0;
        root_nodes[i].close = 0;
        root_nodes[i].impl = 0;
    }

    return initrd_root;
As you can see from the screenshot, the page fault is happening when I try and access the initrd header. Now, I will make a new image and test it, but I didn't make any changes to the current build so all the code is the same.

And one more thing, I belive it has been stated that I should initialise paging after setting up the locations, why? Can't I just set the superglobal and then when the paging uses it it finds it set to a diffirent value?

When I say superglobal I mean the placement_address object.

Thanks!
Attachments
Screen shot.
Screen shot.
User avatar
Bender
Member
Member
Posts: 449
Joined: Wed Aug 21, 2013 3:53 am
Libera.chat IRC: bender|
Location: Asia, Singapore

Re: Initrd & General

Post by Bender »

Can you get the value of the "page fault linear address" (which is in CR2) and the instruction pointer which causes the actual fault (pushed to stack)? With that you'll know what memory address you were trying to access just before the page fault, and what part of your code is causing it.

I haven't checked your code properly but it could be that the address where your initrd is loaded is left unmapped?
"In a time of universal deceit - telling the truth is a revolutionary act." -- George Orwell
(R3X Runtime VM)(CHIP8 Interpreter OS)
User avatar
deleted
Member
Member
Posts: 82
Joined: Mon Jul 21, 2014 7:23 pm

Re: Initrd & General

Post by deleted »

Hello!

I have written a simple function to return the value of CR2, and it returns the same value as the memory location of the initrd_header. I have my linux machine up and running so and I made a new image and ran it. The only problem is, is that the kernel isn't recocnizing the test.txt file inside the inird. It just reads /dev...

Any ideas?

Am I doing this right?

PS: Heres the altered code: https://github.com/BiggerOnTheInside/Bo ... l/kernel.c

Thanks!
User avatar
iansjack
Member
Member
Posts: 4707
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Initrd & General

Post by iansjack »

wxwsk8er wrote:Hello!

I have written a simple function to return the value of CR2, and it returns the same value as the memory location of the initrd_header.
Well that makes debugging fairly easy. Set a breakpoint just before the code at which that address is checked, then walk through your page table to see what's wrong. A page fault is a very specific exception with a very limited range of causes. Obviously something is wrong with your page table. If you initially set it to the correct values then something is changing it - stack
errors often cause such unpredictable behaviour.

This sounds like a fairly simple debugging exercise.
User avatar
Bender
Member
Member
Posts: 449
Joined: Wed Aug 21, 2013 3:53 am
Libera.chat IRC: bender|
Location: Asia, Singapore

Re: Initrd & General

Post by Bender »

Code: Select all

42: u32int initrd_location = malloc(sizeof(mboot_ptr->mods_addr));  
...
46: u32int initrd_end = malloc(sizeof(mboot_ptr->mods_addr + 4));
...
62: fs_root = initialise_initrd(initrd_location);
Read that again, and see if it makes any sense at all. :)
"In a time of universal deceit - telling the truth is a revolutionary act." -- George Orwell
(R3X Runtime VM)(CHIP8 Interpreter OS)
User avatar
deleted
Member
Member
Posts: 82
Joined: Mon Jul 21, 2014 7:23 pm

Re: Initrd & General

Post by deleted »

Thanks!

I tried switching the names, but it didnt work (just a page fault). Then I tried to do the same using malloc, but it didn't change.
Post Reply