How would mov %rax,%rsp corrupt the stack pointer, and how would I fix it?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 to make a GDT?
Re: How to make a GDT?
-
- Member
- Posts: 5562
- Joined: Mon Mar 25, 2013 7:01 pm
Re: How to make a GDT?
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.
I suspect you can fix it by removing that instruction.
Re: How to make a GDT?
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?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.
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
Re: How to make a GDT?
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?
Re: How to make a GDT?
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;
}
}
- AndrewAPrice
- Member
- Posts: 2300
- Joined: Mon Jun 05, 2006 11:00 pm
- Location: USA (and Australia)
Re: How to make a GDT?
Close but you want:
You want to return a pointer to the old value of freebase.
Code: Select all
ptr = freebase;
My OS is Perception.
Re: How to make a GDT?
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.AndrewAPrice wrote:Close but you want:You want to return a pointer to the old value of freebase.Code: Select all
ptr = freebase;
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;
| ^
- AndrewAPrice
- Member
- Posts: 2300
- Joined: Mon Jun 05, 2006 11:00 pm
- Location: USA (and Australia)
Re: How to make a GDT?
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.
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.
Re: How to make a GDT?
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.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.
- AndrewAPrice
- Member
- Posts: 2300
- Joined: Mon Jun 05, 2006 11:00 pm
- Location: USA (and Australia)
Re: How to make a GDT?
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.zap8600 wrote:Should I continue making my own memory manager, or should I use an existing one?
My OS is Perception.
Re: How to make a GDT?
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?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.
Re: How to make a GDT?
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.
-
- Member
- Posts: 5562
- Joined: Mon Mar 25, 2013 7:01 pm
Re: How to make a GDT?
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:I'm attempting to add the code to handle the page fault to my ISR handler.
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 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?
Re: How to make a GDT?
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 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.
-
- Member
- Posts: 5562
- Joined: Mon Mar 25, 2013 7:01 pm
Re: How to make a GDT?
CR2 contains the address of the most recent access that caused a page fault.zap8600 wrote:Does cr2 return just the address for what caused the problem?
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.zap8600 wrote:Also, I have finally realized that my memory code doesn't use paging, so I can just fix the page fault.
How does your OS manage memory without using paging? That's a very unusual design choice.
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.)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?