How to make a GDT?

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.
zap8600
Member
Member
Posts: 195
Joined: Tue Nov 02, 2021 11:26 am
Libera.chat IRC: zap8600

Re: How to make a GDT?

Post by zap8600 »

Octocontrabass wrote:The exception is happening at the IRETQ instruction, but usually that means there's a problem somewhere else that causes stack corruption.

For example, the instruction at ffffffff800001eb might be corrupting the stack pointer.
How would mov %rax,%rsp corrupt the stack pointer, and how would I fix it?
Octocontrabass
Member
Member
Posts: 5562
Joined: Mon Mar 25, 2013 7:01 pm

Re: How to make a GDT?

Post by Octocontrabass »

It replaces the stack pointer with whatever value is in RAX. Will RAX contain a valid stack pointer there?

I suspect you can fix it by removing that instruction.
zap8600
Member
Member
Posts: 195
Joined: Tue Nov 02, 2021 11:26 am
Libera.chat IRC: zap8600

Re: How to make a GDT?

Post by zap8600 »

Octocontrabass wrote:It replaces the stack pointer with whatever value is in RAX. Will RAX contain a valid stack pointer there?

I suspect you can fix it by removing that instruction.
It worked. Now interrupts are finally working. I do want to add the mini debugger to my OS. I believe I need to replace all of the push instructions in my int.S file with call dbg_saveregs, add dbg_main(r->int_no); to my isr_handler function, and replace all of the pop instructions in my int.S file. I also plan on adding aarch64 support to my OS. Would this be a valid boot.S file for aarch64?

Code: Select all

.section .bss 
 .align 16 
 stack_bottom: 
 .skip 16384 # 16 KiB 
 .globl stack_top 
 stack_top: 
  
 .section text 
 .globl _start 
 .type _start @function 
 _start: 
     ldr x30, =stack_top 
     mov sp, x30 
     bl kmain 
 hang: 
     b hang
zap8600
Member
Member
Posts: 195
Joined: Tue Nov 02, 2021 11:26 am
Libera.chat IRC: zap8600

Re: How to make a GDT?

Post by zap8600 »

I believe that I should next set up a physical memory allocator. I think that I will use the Bucket allocator. I'm not the best with memory, though. I don't need to add a spinlock mechanism, and I don't plan to have a physical or virtual memory system yet, so all that my mmap() function needs to do is set-aside a region of physical memory. I don't know how to do this though. How do I do this?
zap8600
Member
Member
Posts: 195
Joined: Tue Nov 02, 2021 11:26 am
Libera.chat IRC: zap8600

Re: How to make a GDT?

Post by zap8600 »

I think I may of made a malloc() command, but I don't think it'll work. I'm using a WaterMark allocator. I'll leave my code here and get back to it in the morning.

Code: Select all

#include <stdint.h>
#include <stddef.h>

#include <kernel/string.h>
#include <kernel/stdio.h>
#include <kernel/mem.h>

uintptr_t freebase;
uintptr_t freetop;
extern uintptr_t _kernel_end;

void init_mem()
{
    freebase = _kernel_end;
    freetop = 0xffffffffffe09000;
}

void *malloc(size_t size)
{
    void *ptr;

    if((freetop - freebase) < size) {
        printf("Error! Not enough memory avalible to allocate memory!");
        return -1;
    } else {
        ptr = freebase + size;
        freebase = freebase + size;
        printf("ptr = %x", ptr);
        return ptr;
    }
}
User avatar
AndrewAPrice
Member
Member
Posts: 2300
Joined: Mon Jun 05, 2006 11:00 pm
Location: USA (and Australia)

Re: How to make a GDT?

Post by AndrewAPrice »

Close but you want:

Code: Select all

ptr = freebase;
You want to return a pointer to the old value of freebase.
My OS is Perception.
zap8600
Member
Member
Posts: 195
Joined: Tue Nov 02, 2021 11:26 am
Libera.chat IRC: zap8600

Re: How to make a GDT?

Post by zap8600 »

AndrewAPrice wrote:Close but you want:

Code: Select all

ptr = freebase;
You want to return a pointer to the old value of freebase.
What type does freebase, freetop, and _kernel_end need to be? I keep getting the warning below, and I am unsure how to fix it.

Code: Select all

kernel/mem.c: In function 'malloc':
kernel/mem.c:27:13: warning: assignment to 'void *' from 'uint64_t' {aka 'long unsigned int'} makes pointer from integer without a cast [-Wint-conversion]
   27 |         ptr = freebase;
      |             ^
User avatar
AndrewAPrice
Member
Member
Posts: 2300
Joined: Mon Jun 05, 2006 11:00 pm
Location: USA (and Australia)

Re: How to make a GDT?

Post by AndrewAPrice »

Judging by your code, _kernel_end would be the end of the Kernel's code and static data. Your kernel linker script would populate this value for you.

freetop would be the point at which you run out of memory.

freebase is the next location to allocate memory. It would start at _kernel_end and increment as you locate memory.
My OS is Perception.
zap8600
Member
Member
Posts: 195
Joined: Tue Nov 02, 2021 11:26 am
Libera.chat IRC: zap8600

Re: How to make a GDT?

Post by zap8600 »

AndrewAPrice wrote:Judging by your code, _kernel_end would be the end of the Kernel's code and static data. Your kernel linker script would populate this value for you.

freetop would be the point at which you run out of memory.

freebase is the next location to allocate memory. It would start at _kernel_end and increment as you locate memory.
Should I continue making my own memory manager, or should I use an existing one? I have tried this one, but it gives me a page fault.
User avatar
AndrewAPrice
Member
Member
Posts: 2300
Joined: Mon Jun 05, 2006 11:00 pm
Location: USA (and Australia)

Re: How to make a GDT?

Post by AndrewAPrice »

zap8600 wrote:Should I continue making my own memory manager, or should I use an existing one?
I use liballoc in my kernel. But, these allocators still need you to provide it large chunks of memory (e.g. "Give me a 4KiB page.") and then the allocator worries about efficiently dividing and recycling this memory. But, I still have to provide some memory management: keeping a stack of free memory pages I can pass to the allocator, keeping up with what range of virtual address spaces are free, and mapping physical memory to virtual memory addresses.
My OS is Perception.
zap8600
Member
Member
Posts: 195
Joined: Tue Nov 02, 2021 11:26 am
Libera.chat IRC: zap8600

Re: How to make a GDT?

Post by zap8600 »

AndrewAPrice wrote: I use liballoc in my kernel. But, these allocators still need you to provide it large chunks of memory (e.g. "Give me a 4KiB page.") and then the allocator worries about efficiently dividing and recycling this memory. But, I still have to provide some memory management: keeping a stack of free memory pages I can pass to the allocator, keeping up with what range of virtual address spaces are free, and mapping physical memory to virtual memory addresses.
I have taken a look at your code,and I sort of understand what I need to do. However, I still need to make the pages, which I don't know how to do. How would I do so?
zap8600
Member
Member
Posts: 195
Joined: Tue Nov 02, 2021 11:26 am
Libera.chat IRC: zap8600

Re: How to make a GDT?

Post by zap8600 »

I understand what I need to do now. I'm attempting to add the code to handle the page fault to my ISR handler. The only thing I don't know how to do is how to get the upper and middle 10 bits of the address. How do I do this? Right now, the faulting address is 0xFFFFFFF80409000.
Octocontrabass
Member
Member
Posts: 5562
Joined: Mon Mar 25, 2013 7:01 pm

Re: How to make a GDT?

Post by Octocontrabass »

zap8600 wrote:I'm attempting to add the code to handle the page fault to my ISR handler.
You shouldn't be getting page faults in the first place. You should know which addresses you're going to access before you access them, so you can map memory to those addresses.
zap8600 wrote:The only thing I don't know how to do is how to get the upper and middle 10 bits of the address. How do I do this?
You're trying to follow instructions for 2-level paging, but you're using 4-level paging. You need to find four groups of 9 bits instead of two groups of 10 bits. The Intel and AMD manuals have excellent diagrams that show exactly how to find those groups of 9 bits.
zap8600
Member
Member
Posts: 195
Joined: Tue Nov 02, 2021 11:26 am
Libera.chat IRC: zap8600

Re: How to make a GDT?

Post by zap8600 »

Octocontrabass wrote: You're trying to follow instructions for 2-level paging, but you're using 4-level paging. You need to find four groups of 9 bits instead of two groups of 10 bits. The Intel and AMD manuals have excellent diagrams that show exactly how to find those groups of 9 bits.
Does cr2 return just the address for what caused the problem? Also, I have finally realized that my memory code doesn't use paging, so I can just fix the page fault. I don't know how Limine sets up paging, so I'm not sure how to create, would I just make my own PTE and align pages to 4092?
Octocontrabass
Member
Member
Posts: 5562
Joined: Mon Mar 25, 2013 7:01 pm

Re: How to make a GDT?

Post by Octocontrabass »

zap8600 wrote:Does cr2 return just the address for what caused the problem?
CR2 contains the address of the most recent access that caused a page fault.
zap8600 wrote:Also, I have finally realized that my memory code doesn't use paging, so I can just fix the page fault.
Limine provides direct access to all memory with either identity mapping or a fixed offset in the higher half. If you're not going to use paging, you can use one of these ranges to access memory and you won't have any page faults unless there's a problem with your code.

How does your OS manage memory without using paging? That's a very unusual design choice.
zap8600 wrote:I don't know how Limine sets up paging, so I'm not sure how to create, would I just make my own PTE and align pages to 4092?
If you want to set up your own paging structures, you would probably need to create all four levels from scratch. In theory you could use Limine's paging structures, but Limine doesn't make any promises about their contents beyond the attributes and address ranges. (Paging structures have 4096-byte alignment.)
Post Reply