OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 4:23 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 3 posts ] 
Author Message
 Post subject: Paging: How to map new pages for usermode tasks?
PostPosted: Tue Oct 17, 2017 9:16 am 
Offline

Joined: Wed Dec 03, 2014 1:46 pm
Posts: 15
I struggle at finishing my paging code. I am not sure if I understood the complete concept of paging.
I have already the basic functionalities like allocating new page directories. Furthermore I can register kernel or user tasks and each task will allocate a new page directory. The directories will be switched if tasks are switched.

My problem is to fill the new allocated page directory of user tasks. Kernel tasks just get the kernel page directory, but I am not sure how to fill the user page directory right. I know that it needs the kernel to be mapped for Interrupts and so on, but how do I prevent accessing this memory. Or is it normal, that user tasks can modify kernel memory? And how can I map the user task code itself? E.g. my elf modules are loaded to 0x300000. How can I divide their memory so that they dont override each other? My test module should write "01234". If I excute it twice I get "012345689", because they seem to share the global variables.

As you can see at my README I know that just mapping the first 3 MB at the kernel page directory is not the best implementation. I will map the exact memory later. I also read that I have to change my phys memory allocation to return virtual memory addesses. But I am not sure how I could implement this.

Here is my code: https://gitlab.com/lolxdfly/kernel

I am grateful for any help.

_________________
My Code


Top
 Profile  
 
 Post subject: Re: Paging: How to map new pages for usermode tasks?
PostPosted: Wed Oct 18, 2017 1:05 am 
Offline
Member
Member
User avatar

Joined: Sat Jan 15, 2005 12:00 am
Posts: 8561
Location: At his keyboard!
Hi,

lolxdfly wrote:
I struggle at finishing my paging code. I am not sure if I understood the complete concept of paging.
I have already the basic functionalities like allocating new page directories. Furthermore I can register kernel or user tasks and each task will allocate a new page directory. The directories will be switched if tasks are switched.

My problem is to fill the new allocated page directory of user tasks. Kernel tasks just get the kernel page directory, but I am not sure how to fill the user page directory right.


Usually the kernel creates a new task with nothing in user-space; then switches to that task (still with nothing in user-space) and runs some sort of executable loader or a "mini loader" (that's built into the kernel). The executable loader looks at the executable file and figures out which pieces of the executable file get mapped where (from the executable's header). Once the executable file is mapped into user-space, kernel can "return" to user-space at the executable's entry point.

lolxdfly wrote:
I know that it needs the kernel to be mapped for Interrupts and so on, but how do I prevent accessing this memory. Or is it normal, that user tasks can modify kernel memory?


Usually there's 2 (or more) privilege levels, where the CPU is running in one (e.g. "CPL=3" or user) and all of the kernel's pages are marked as "supervisor only" so that if code running with user privileges tries to access those pages it causes a page fault (because supervisor access is needed), and kernel code (which has supervisor access - e.g. CPL=0) can access those pages.

lolxdfly wrote:
And how can I map the user task code itself? E.g. my elf modules are loaded to 0x300000. How can I divide their memory so that they dont override each other?


Normally every process is given its own private virtual address space (with "kernel space" mapped into it). For 80x86 this is mostly done by loading CR3 with a different value for each different process during task switches (unless the tasks are different threads in the same process). One process can use virtual address 0x12345678 in its own private virtual address space for something and this has nothing to do with address 0x12345678 in any other virtual address space (in the same way that I could write "Hello" on the third page of a book, and this wouldn't effect the third page of any other book).


Cheers,

Brendan

_________________
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.


Top
 Profile  
 
 Post subject: Re: Paging: How to map new pages for usermode tasks?
PostPosted: Wed Oct 18, 2017 11:50 am 
Offline

Joined: Wed Dec 03, 2014 1:46 pm
Posts: 15
Thanks for your answer.

Brendan wrote:
Usually the kernel creates a new task with nothing in user-space; then switches to that task (still with nothing in user-space) and runs some sort of executable loader or a "mini loader" (that's built into the kernel). The executable loader looks at the executable file and figures out which pieces of the executable file get mapped where (from the executable's header). Once the executable file is mapped into user-space, kernel can "return" to user-space at the executable's entry point.

I think I implemented the taskcreation a bit differrent to how you explained it. I have a loader function for elf images. This function checks the flags and move the code to my 0x300000 position. It returns the entry point which is passed to the register_task function. New created tasks have an initialized state, where I set the cs and ss registers to kernel or user mode.

Brendan wrote:
Usually there's 2 (or more) privilege levels, where the CPU is running in one (e.g. "CPL=3" or user) and all of the kernel's pages are marked as "supervisor only" so that if code running with user privileges tries to access those pages it causes a page fault (because supervisor access is needed), and kernel code (which has supervisor access - e.g. CPL=0) can access those pages.

You are right. I understand the privilege concept now :)

Brendan wrote:
Normally every process is given its own private virtual address space (with "kernel space" mapped into it). For 80x86 this is mostly done by loading CR3 with a different value for each different process during task switches (unless the tasks are different threads in the same process). One process can use virtual address 0x12345678 in its own private virtual address space for something and this has nothing to do with address 0x12345678 in any other virtual address space (in the same way that I could write "Hello" on the third page of a book, and this wouldn't effect the third page of any other book).

I have changed some of my code (it's not pushed on git yet) and it seems to work now. I had an issue at my loader not loading the images to new addresses. I noticed it while reading your answer. I will mark this solved if I am really sure that it works :D

_________________
My Code


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

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], DotBot [Bot] and 66 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