klange / toaruos

A completely-from-scratch hobby operating system: bootloader, kernel, drivers, C library, and userspace including a composited graphical UI, dynamic linker, syntax-highlighting text editor, network stack, etc.
https://toaruos.org/
University of Illinois/NCSA Open Source License
6.13k stars 487 forks source link

Error in mem.c/task.h #85

Closed cycl0ne closed 9 years ago

cycl0ne commented 9 years ago

In Task.h:

typedef struct page {
    unsigned int present:1;
    unsigned int rw:1;
    unsigned int user:1;
    unsigned int accessed:1;
    unsigned int dirty:1;
    unsigned int unused:7;
    unsigned int frame:20;
} __attribute__((packed)) page_t;

accessed and dirty are in the wrong location. at this point you have writeback/cachedisable. So the structure should look like this:

typedef struct page {
    unsigned int present:1;
    unsigned int rw:1;
    unsigned int user:1;
    unsigned int writethrough:1;
    unsigned int cachedisable:1;
    unsigned int accessed:1;
    unsigned int dirty:1;
    unsigned int unused:1;
    unsigned int global:1;
    unsigned int available:3;
    unsigned int frame:20;
} __attribute__((packed)) page_t;

In file mem.c under function alloc_frame we find the following error:

} else {
    spin_lock(&frame_alloc_lock);
    uint32_t index = first_frame();
    assert(index != (uint32_t)-1 && "Out of frames.");
    set_frame(index * 0x1000);
    page->frame   = index; 

the last entry should be : page->frame = index * 0x1000 since we need the adress and not an index;

This error could be hard to find, because normaly you call alloc_frame(get_page(...,1,..)); so get_page already allocated it for you, but in some code (shm.c) you are relying directly on the allocation.

One thing i dont understand:

void paging_install(uint32_t memsize) 
{
    nframes = memsize  / 4;
    frames  = (uint32_t *)kmalloc(INDEX_FROM_BIT(nframes * 8));
....
}

here you divide memsize / 4.. and then you call your malloc with (nframes8)/32 ... Why the 8 ?

Another "bug" ?

void dma_frame(
        page_t *page,
        int is_kernel,
        int is_writeable,
        uintptr_t address
        ) {
    /* Page this address directly */
    page->present = 1;
    page->rw      = (is_writeable) ? 1 : 0;
    page->user    = (is_kernel)    ? 0 : 1;
    page->frame   = address / 0x1000;

shouldnt the last line be: page->frame = address & FFFFF000;

Cheers C.

klange commented 9 years ago

You have several different things in this report, at least one of which is definitely not an issue.

cycl0ne commented 9 years ago

Hey,

sorry.. you are right! damn.. i saw the bitfield and ignored it later :dizzy_face:

for the dirty flag.. this is not so important maybe for you, but the other two which are located there: Cachedisable should be your DMA Pages flagged Writethrough should be your framebuffer flagged