As some of you may already know, I've been trying to get paging going for a while. Here is the last thread I started on the subject. Many helpful comments there, especially from eryjus.
I think I may have actually done it this time! This has got to be too good to be true.
Anyway, I redid my paging initialization function, ran a couple of tests, and nearly shart myself when they seemed to work. I'm wondering if the kind users of the forum wouldn't mind doing some code review to make sure I'm not just deluding myself, please.
Here is my paging code.
Here's what I'm doing to attempt to trigger a read fault. (This is now out of date).
Here's what I'm doing to attempt to trigger a write fault. (This is now out of date.)
Here's a screen shot.
Right now I'm identity mapping all of the available system memory, and give all page directories, and page tables, the | 3 attributes. This seems to be allowing me to enable paging, and continue processing, but I'm not triggering any page faults. I'm hoping to go back through that, initialize only the page directories and tables that are needed to map the kernel, as well as use the proper attributes, so I can look into writing a proper page frame allocator, and see about swapping pages to a hard drive. I'd also like to start pushing towards user space, getting out of ring 0, and into task switching.
Any constructive criticisms, helpful hints, and suggestions would be very welcome.
[Paging, Code Review Request] Did I really do it?
[Paging, Code Review Request] Did I really do it?
Last edited by PatSanf on Mon Mar 02, 2015 5:28 pm, edited 1 time in total.
-
- Member
- Posts: 29
- Joined: Tue Jan 20, 2015 8:33 pm
Re: [Paging, Code Review Request] Did I really do it?
I'm pretty sure your read fault and write fault code don't actually trigger read faults or write faults...
Assuming 0xA0000000 points to unmapped memory (which probably isn't wrong, though I don't know exactly what your memory looks like), this still doesn't actually *read* from that location at all. This just sets a pointer equal to that location and then copies the pointer. You probably want:
Then:
This just sets a pointer to 0xA0000000, then immediately sets it to 0xDEADC0DE, which again doesn't actually write to the location at all. You probably want:
You appear to have a page fault handler set up properly - that *should* be getting called when you trigger a page fault the fact that you can run through your read fault and write fault tests without triggering a page fault would seem to be a problem in your paging code... but you can never know unless your tests are correct
Code: Select all
// Read fault
u32int *ptr = (u32int *) 0xA0000000;
u32int do_fault = (u32int) ptr;
Code: Select all
u32int do_fault = *ptr;
Code: Select all
// Write fault
u32int *ptr = (u32int *) 0xA0000000;
ptr = (u32int *) 0xDEADC0DE;
Code: Select all
*ptr = 0xDEADC0DE;
Re: [Paging, Code Review Request] Did I really do it?
Thanks for that. That's the way I was originally doing the fault tests, but I got boneheaded and changed it for some unknown reason. They're both triggering page faults now. One thing does concern me with the read fault test, however. It'll trigger a fault, but the error code I'm getting is 0x0. Is it supposed to be this way? EDIT: Just checked the wiki, it's supposed to be that way.
Here are a couple more screen shots.
This is the read fault error code I'm talking about.
This is my write fault test.
One thing that concerns me is how I set up the page directories, and tables. I identity mapped all available system memory. This means I have 32 page directories, and when I start writing my page fault interrupt handler there won't be any more memory to map in. Should I only be mapping enough memory to handle the kernel?
EDIT: Oh! What my memory looks like.
I have my low memory, then my kernel starting at 1M, then 32 page directories, and finally my page tables. I'm identity mapping all of the system memory.
0x0 - 0xFFFFF = low memory
0x100000 - 0x108D50 = my kernel
0x109000 = my first page directory
Here are a couple more screen shots.
This is the read fault error code I'm talking about.
This is my write fault test.
One thing that concerns me is how I set up the page directories, and tables. I identity mapped all available system memory. This means I have 32 page directories, and when I start writing my page fault interrupt handler there won't be any more memory to map in. Should I only be mapping enough memory to handle the kernel?
EDIT: Oh! What my memory looks like.
I have my low memory, then my kernel starting at 1M, then 32 page directories, and finally my page tables. I'm identity mapping all of the system memory.
0x0 - 0xFFFFF = low memory
0x100000 - 0x108D50 = my kernel
0x109000 = my first page directory
Last edited by PatSanf on Mon Mar 02, 2015 5:43 pm, edited 1 time in total.
Re: [Paging, Code Review Request] Did I really do it?
Well, your code is correct, but if your just going to identity map everything, what's the point in enabling paging?
You're paging code should expose three main functions for the rest of your kernel: map page, unmap page and clone a virtual address space. These will be used by your VMM probably, which will handle where things are located in each virtual address space and how page faults are responsded to (e.g. copying memory on write, allocating physical memory, etc.).
Also, I don't know how GRUB loads an ELF file since I wrote my own boot loader, but it's very likely it's enabling paging so that your kernel executable appears at the correct location in memory. If your kernel is in the higher half then you'll have to map it to there when you switch to your custom paging table.
Apologies for any mistakes I made, it's late here
You're paging code should expose three main functions for the rest of your kernel: map page, unmap page and clone a virtual address space. These will be used by your VMM probably, which will handle where things are located in each virtual address space and how page faults are responsded to (e.g. copying memory on write, allocating physical memory, etc.).
Also, I don't know how GRUB loads an ELF file since I wrote my own boot loader, but it's very likely it's enabling paging so that your kernel executable appears at the correct location in memory. If your kernel is in the higher half then you'll have to map it to there when you switch to your custom paging table.
Apologies for any mistakes I made, it's late here
"for example, turning off the system’s power through the movement of a large red switch" - the Advanced Configuration and Power Interface Specification
-
- Member
- Posts: 29
- Joined: Tue Jan 20, 2015 8:33 pm
Re: [Paging, Code Review Request] Did I really do it?
The wiki claims that error code 0 means 'Supervisory process tried to read a non-present page entry' - is that what you tried to do?PatSanf wrote:Thanks for that. That's the way I was originally doing the fault tests, but I got boneheaded and changed it for some unknown reason. They're both triggering page faults now. One thing does concern me with the read fault test, however. It'll trigger a fault, but the error code I'm getting is 0x0. Is it supposed to be this way?
Overall that looks like you're doing okay - you can still execute code so your kernel is mapped in properly, you can still use all your data... If you start getting page faults in strange places, then you'll know your paging code has a problem, but you seem to be getting the right errors for things and not getting errors when you shouldn't be, so congratulations!
I'll read through the code a little more later tonight and maybe give you a bit of feedback on that as well, no time meow though.
edit:
Untrue, GRUB doesn't enable pagingbace wrote: Also, I don't know how GRUB loads an ELF file since I wrote my own boot loader, but it's very likely it's enabling paging so that your kernel executable appears at the correct location in memory.
Re: [Paging, Code Review Request] Did I really do it?
I did it that way as a learning exercise. I'll be redoing, again, in the next couple of days so it doesn't map everything. I'm planning on writing my own page fault handler, and getting swapping set up. I went overboard, and mapped everything as a way of solidifying in my mind what I'm supposed to be doing with the page directories, and tables. I'm thinking that when I do my next implementation I'll just be mapping what's needed for the kernel. Should I also map what I'll be needing for that page directory?bace wrote:Well, your code is correct, but if your just going to identity map everything, what's the point in enabling paging?
You're paging code should expose three main functions for the rest of your kernel: map page, unmap page and clone a virtual address space. These will be used by your VMM probably, which will handle where things are located in each virtual address space and how page faults are responsded to (e.g. copying memory on write, allocating physical memory, etc.).
Also, I don't know how GRUB loads an ELF file since I wrote my own boot loader, but it's very likely it's enabling paging so that your kernel executable appears at the correct location in memory. If your kernel is in the higher half then you'll have to map it to there when you switch to your custom paging table.
Apologies for any mistakes I made, it's late here
I am using GRUB, but it isn't enabling paging for me.
-
- Member
- Posts: 29
- Joined: Tue Jan 20, 2015 8:33 pm
Re: [Paging, Code Review Request] Did I really do it?
Haha... this reminds me so much of me like six months ago it's unreal.PatSanf wrote:I did it that way as a learning exercise. I'll be redoing, again, in the next couple of days so it doesn't map everything. I'm planning on writing my own page fault handler, and getting swapping set up. I went overboard, and mapped everything as a way of solidifying in my mind what I'm supposed to be doing with the page directories, and tables. I'm thinking that when I do my next implementation I'll just be mapping what's needed for the kernel. Should I also map what I'll be needing for that page directory?bace wrote:Well, your code is correct, but if your just going to identity map everything, what's the point in enabling paging?
You're paging code should expose three main functions for the rest of your kernel: map page, unmap page and clone a virtual address space. These will be used by your VMM probably, which will handle where things are located in each virtual address space and how page faults are responsded to (e.g. copying memory on write, allocating physical memory, etc.).
Also, I don't know how GRUB loads an ELF file since I wrote my own boot loader, but it's very likely it's enabling paging so that your kernel executable appears at the correct location in memory. If your kernel is in the higher half then you'll have to map it to there when you switch to your custom paging table.
Apologies for any mistakes I made, it's late here
I am using GRUB, but it isn't enabling paging for me.
Re: [Paging, Code Review Request] Did I really do it?
The Multiboot spec says: "‘CR0’ - Bit 31 (PG) must be cleared. Bit 0 (PE) must be set. Other bits are all undefined."bace wrote:Also, I don't know how GRUB loads an ELF file since I wrote my own boot loader, but it's very likely it's enabling paging so that your kernel executable appears at the correct location in memory.