OSDev.org

The Place to Start for Operating System Developers
It is currently Mon Apr 29, 2024 7:33 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 10 posts ] 
Author Message
 Post subject: Problem with paging (Triple fault)
PostPosted: Sat Aug 12, 2023 2:22 am 
Offline
Member
Member

Joined: Sat Aug 12, 2023 1:48 am
Posts: 40
Location: Nizhny Novgorod, Russia
Hello forum!
I'm new to OS development and now I'm developing my first OS. I've already implemented simple exception handler and now I'm trying to implement paging. I have decided to start with Identity Paging but for all memory because I have to enable paging for future multitasking, but still want to control memory same as before. So I wrote a simple function for Identify Paging. Here is the code:
Code:
#define PAGE_SIZE 4 // given in kilobytes

extern void panic(char* error);

typedef struct {
    uint32_t address : 20; // 4 KiB aligned adress of PT
    uint16_t avl : 4; // available
    uint8_t flags : 8; // 5th bit is available
} __attribute__((packed)) pd_entry_t;

typedef struct {
    uint32_t address : 20; // 4 KiB aligned adress of PT
    uint8_t avl : 3; // available
    uint16_t flags : 9; // flags
} __attribute__((packed)) pt_entry_t;

uint32_t get_memory_size(multiboot_info_t* mbd) {
    uint32_t lower = mbd->mem_lower;
    uint32_t higher = mbd->mem_upper;
    return lower + higher;
}

void init_paging(multiboot_info_t* mbd) {
    uint32_t total_memory = get_memory_size(mbd);
    if (total_memory < 16384) {
        panic("At least 16Mb of RAM required to run operating system.");
    }

    if (total_memory > 4194303) {
        total_memory = 4194303;
    }
   
    /*extern uint32_t _end;
    uint32_t kernel_end_addr = (uint32_t)&_end;
    kernel_end_addr = (kernel_end_addr + 4095) & ~4095;*/

    pd_entry_t page_directory[1024] __attribute__((aligned(4096)));
    pt_entry_t page_table[(total_memory + PAGE_SIZE - 1) / PAGE_SIZE] __attribute__((aligned(4096)));
   
    uint16_t pd_index;
    uint16_t pt_index;
    uint32_t phys_addr;
    uint32_t pt_addr;

    for (uint32_t i = 0; i < total_memory; i += PAGE_SIZE)
    {
        phys_addr = i * 1024;
       
        pd_index = phys_addr >> 22;
        pt_index = phys_addr >> 12 & 0x03FF;

        if ((phys_addr & 0xFFF))
        {
            printf("0x%x ", phys_addr);
            panic("Adress cannot be aligned at 4 KB.");
        }
       
        pt_addr = (uint32_t)(&page_table[pd_index * 1024]);

        if ((pt_addr & 0xFFF))
        {
            printf("0x%x ", pt_addr);
            panic("Adress cannot be aligned at 4 KB.");
        }

        page_directory[pd_index].address = pt_addr >> 12;
        page_directory[pd_index].avl = 0;
        page_directory[pd_index].flags = 0b11010000;

        page_table[pd_index * 1024 + pt_index].address = phys_addr >> 12;
        page_table[pd_index * 1024 + pt_index].avl = 0;
        page_table[pd_index * 1024 + pt_index].flags = 0b110100000;
    }

    uint32_t pd_address = (uint32_t)page_directory;

    asm volatile ("mov %0, %%cr3" : : "r" (pd_address) : "memory");
    //asm volatile ("mov %%cr0, %%eax; or $0x80000000, %%eax; mov %%eax, %%cr0" : :);
    //for(;;);

    printf("Paging enabled (1:1, Page Directory = 0x%x)", pd_address);
}

:(
But... this function is not working properly. Once I write PG bit to CR0, I get a Triple Fault. GDB tells me that my code doesn't even switch to next instruction and instantly resets I also know that page fault happens before reset (CR2 register != 0) but have no idea why. Can someone help me with explanation about what happens here? Or maybe Identify Paging for all memory is not needed and different memory models can be used.
Thank you for your reply.


Top
 Profile  
 
 Post subject: Re: Problem with paging (Triple fault)
PostPosted: Sat Aug 12, 2023 9:58 pm 
Offline
Member
Member

Joined: Mon Jul 05, 2021 6:57 pm
Posts: 118
I have only given a quick glance. I doubt this is the only problem but:

Code:
uint32_t get_memory_size(multiboot_info_t* mbd) {
    uint32_t lower = mbd->mem_lower;
    uint32_t higher = mbd->mem_upper;
    return lower + higher;
}

That isn't right, if you're trying to calculate the highest possible address, which is what you appear to treat the returned value as. From the spec:
Quote:
Lower memory starts at address 0, and upper memory starts at address 1 megabyte

I.e. the return should be mem_upper + 1MB, the lower memory amount doesn't even enter the equation. However I should add that using these is over-simplistic anyway, you should really use the full memory map (although I guess you could use these values just to get started). Note that:
Quote:
The value returned for upper memory is maximally the address of the first upper memory hole minus 1 megabyte. It is not guaranteed to be this value.

I.e. mem_upper only goes so far as the first memory hole and might not even go that far, so it may report far less memory than is actually available.


Top
 Profile  
 
 Post subject: Re: Problem with paging (Triple fault)
PostPosted: Sat Aug 12, 2023 10:06 pm 
Offline
Member
Member

Joined: Mon Jul 05, 2021 6:57 pm
Posts: 118
Ok this is more likely to be the main problem:
Code:
    pt_entry_t page_table[(total_memory + PAGE_SIZE - 1) / PAGE_SIZE] __attribute__((aligned(4096)));

Your page table array is a local variable which means that (a) you're allocating the whole thing on the stack which is probably going to overflow it and (b) it will become invalid once you return from the function. Same issue with the page directory.


Top
 Profile  
 
 Post subject: Re: Problem with paging (Triple fault)
PostPosted: Sat Aug 12, 2023 10:15 pm 
Offline
Member
Member

Joined: Mon Jul 05, 2021 6:57 pm
Posts: 118
Oh and finally:
Code:
typedef struct {
    uint32_t address : 20; // 4 KiB aligned adress of PT
    uint16_t avl : 4; // available
    uint8_t flags : 8; // 5th bit is available
} __attribute__((packed)) pd_entry_t;

Isn't that back-to-front? The address should be the upper 20 bits IIRC.


Top
 Profile  
 
 Post subject: Re: Problem with paging (Triple fault)
PostPosted: Sun Aug 13, 2023 9:27 am 
Offline
Member
Member

Joined: Sat Aug 12, 2023 1:48 am
Posts: 40
Location: Nizhny Novgorod, Russia
I'm going to check later today. I'll notify you about the results. :)


Top
 Profile  
 
 Post subject: Re: Problem with paging (Triple fault)
PostPosted: Sun Aug 13, 2023 9:58 am 
Offline
Member
Member

Joined: Sat Aug 12, 2023 1:48 am
Posts: 40
Location: Nizhny Novgorod, Russia
Or maybe I don't have to use Identify Paging for all memory. Maybe I can do it only for first n megabytes and use remaining memory for heap and allocating programs and map them only in case of request or page fault.
What do you think is the best memory model?


Top
 Profile  
 
 Post subject: Re: Problem with paging (Triple fault)
PostPosted: Sun Aug 13, 2023 1:37 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5146
KrotovOSdev wrote:
What do you think is the best memory model?

"Best" is very subjective, but at least in my opinion, don't identity-map anything. Use paging to put your kernel somewhere in the upper half of the virtual address space and dynamically map memory as you need it.


Top
 Profile  
 
 Post subject: Re: Problem with paging (Triple fault)
PostPosted: Sun Aug 13, 2023 2:54 pm 
Offline
Member
Member

Joined: Sat Aug 12, 2023 1:48 am
Posts: 40
Location: Nizhny Novgorod, Russia
davmac314 wrote:
Oh and finally:
Code:
typedef struct {
    uint32_t address : 20; // 4 KiB aligned adress of PT
    uint16_t avl : 4; // available
    uint8_t flags : 8; // 5th bit is available
} __attribute__((packed)) pd_entry_t;

Isn't that back-to-front? The address should be the upper 20 bits IIRC.

Octocontrabass wrote:
KrotovOSdev wrote:
What do you think is the best memory model?

"Best" is very subjective, but at least in my opinion, don't identity-map anything. Use paging to put your kernel somewhere in the upper half of the virtual address space and dynamically map memory as you need it.


Thank you for your replies, I did everything that you recommended to do but I still get a Triple Fault.
According to you recommendations, I've deleted my old code and wrote a new one. I started with Setting Up Paging tutorial and everything worked fine until I changed int type of page_directory to my structure. Once I do that, problem returns. I think that array of structures != array of integers with same size. Am I right?

Code:
typedef struct {
    uint32_t present : 1; 
    uint32_t rw : 1;     
    uint32_t user : 1;   
    uint32_t pwt : 1; 
    uint32_t pcd : 1;
    uint32_t accessed : 1;     
    uint32_t unused : 1;
    uint32_t ps : 1;
    uint32_t unused2 : 4;
    uint32_t frame : 20;
} __attribute__((packed)) pd_entry_t;

This is a code for pd_entry.


Top
 Profile  
 
 Post subject: Re: Problem with paging (Triple fault)
PostPosted: Sun Aug 13, 2023 3:19 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5146
KrotovOSdev wrote:
I think that array of structures != array of integers with same size. Am I right?

No, they're the same. It sounds like the problem is the values you're placing in those structures. You're initializing every field, right?

Your virtual machine may be able to give you more information about the cause of the exception.


Top
 Profile  
 
 Post subject: Re: Problem with paging (Triple fault)
PostPosted: Mon Aug 14, 2023 6:55 am 
Offline
Member
Member

Joined: Sat Aug 12, 2023 1:48 am
Posts: 40
Location: Nizhny Novgorod, Russia
Octocontrabass wrote:
KrotovOSdev wrote:
I think that array of structures != array of integers with same size. Am I right?

No, they're the same. It sounds like the problem is the values you're placing in those structures. You're initializing every field, right?

Your virtual machine may be able to give you more information about the cause of the exception.

I found a problem. I forgot to do the rightshift >> for address.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], Google [Bot], SemrushBot [Bot] and 20 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group