Hi.
I want to start engaging in user space and implement multitasking and multiprocessing.
I need to know if I'm ready for this...
Now I have a virtual memory Manager, interrupts and exceptions. Is this enough to move on?
I have a couple more questions:
1. How do I switch between kernel mode and user mode? I didn't find any clear information about it.
2. How to load a program into memory? To a certain place? For now, I think I should compile the programs into separate ones .o files and link to the core, but how do I load them to a specific location in virtual memory?
3. If I set a flag for the virtual page where the program is located indicating that this page is a user page (PAGE_SUPERVISOR is 1), then when I try to access the page marked as for the kernel(PAGE_SUPERVISOR is 0), page_fault will occur?
Implementation user space and multitasking
Re: Implementation user space and multitasking
1. You can do a sysret or an iret to switch to user mode. You don't need a preceding syscall or int before doing this but you need to put the correct information into registers, or onto the stack, to fool the processor into thinking that this is a return from a system call.
2. Just parse the executable file and read it from disk into the appropriate memory location. It's really easy to parse elf files. Ensure that you handle initialized and uninitialized data as well as the program text. At this stage you want to confine yourself to statically linked programs - relocation adds an additional layer of complication.
Linking your programs into the kernel, other than perhaps the initial task, is a really bad idea. If you link an initial task in you'll need to move it to the location that user programs are normally expected to occupy. With paging, all of them can have the same address ranges for text, data, and stack.
3. Why would you try and allocate a page reserved for the kernel in user mode? Such an access would indeed result in a page fault. Any such access is done via a system call. That's what they are for.
2. Just parse the executable file and read it from disk into the appropriate memory location. It's really easy to parse elf files. Ensure that you handle initialized and uninitialized data as well as the program text. At this stage you want to confine yourself to statically linked programs - relocation adds an additional layer of complication.
Linking your programs into the kernel, other than perhaps the initial task, is a really bad idea. If you link an initial task in you'll need to move it to the location that user programs are normally expected to occupy. With paging, all of them can have the same address ranges for text, data, and stack.
3. Why would you try and allocate a page reserved for the kernel in user mode? Such an access would indeed result in a page fault. Any such access is done via a system call. That's what they are for.
Re: Implementation user space and multitasking
You'll need to tweak these a bit, but essentially yes.mrjbom wrote:Hi.
I want to start engaging in user space and implement multitasking and multiprocessing.
I need to know if I'm ready for this...
Now I have a virtual memory Manager, interrupts and exceptions. Is this enough to move on?
You fake an interrupt handler return. You push the required registers (with ring 3 selectors for segment registers) on the stack, and you issue an iret.mrjbom wrote:1. How do I switch between kernel mode and user mode? I didn't find any clear information about it.
This is a bit more complicated. You'll need a storage device driver, which can load one sector at a time. Then you set the starting address, call that read sector function, increase the address by 512, and repeat until you have bytes remaining. For virtual memory, there's an extra step, you need to allocate physical pages in the address space. You can do that in advance, or you could write the page fault handler in a way to allocate a page and just let that do the work for the loader.mrjbom wrote:2. How to load a program into memory? To a certain place? For now, I think I should compile the programs into separate ones .o files and link to the core, but how do I load them to a specific location in virtual memory?
User mode can only access pages that are marked user pages in paging table attributes. From kernel, you could access both user and kernel pages, or you could only access only kernel pages (there's a switch for that, I have to look up it in the spec which one, but I'm sure there is one). If you write your code in a way that the kernel only accesses pages that are marked as kernel page, your code will work for sure.mrjbom wrote:3. If I set a flag for the virtual page where the program is located indicating that this page is a user page (PAGE_SUPERVISOR is 1), then when I try to access the page marked as for the kernel(PAGE_SUPERVISOR is 0), page_fault will occur?
Cheers,
bzt
Re: Implementation user space and multitasking
Where can I read more about this? To see examples of code implementation?
I didn't find a wiki article about it.
I didn't find a wiki article about it.
iansjack wrote:1. You can do a sysret or an iret to switch to user mode. You don't need a preceding syscall or int before doing this but you need to put the correct information into registers, or onto the stack, to fool the processor into thinking that this is a return from a system call.
bzt wrote:You fake an interrupt handler return. You push the required registers (with ring 3 selectors for segment registers) on the stack, and you issue an iret.
Re: Implementation user space and multitasking
A great series of articles, I will definitely read them. Thanks a lot.nexos wrote:Look at http://www.brokenthorn.com/Resources/OSDev23.html
Re: Implementation user space and multitasking
I've no idea if this wiki article is any good or not as I haven't studied it in detail.
https://wiki.osdev.org/Getting_to_Ring_3
Basically, if you understand how interrupts work (or how syscall works) then it should be easy to figure it out for yourself with the aid of the Intel manuals. And if you don't have that understanding, I'd recommend that you research it and do a few experiments as it's going to be nearly impossible to debug any errors if you don't understand what should be happening.
I favour syscall/sysret for system calls rather than an interrupt (apart from anything else, I believe it's more efficient), but it's a matter of personal choice.
https://wiki.osdev.org/Getting_to_Ring_3
Basically, if you understand how interrupts work (or how syscall works) then it should be easy to figure it out for yourself with the aid of the Intel manuals. And if you don't have that understanding, I'd recommend that you research it and do a few experiments as it's going to be nearly impossible to debug any errors if you don't understand what should be happening.
I favour syscall/sysret for system calls rather than an interrupt (apart from anything else, I believe it's more efficient), but it's a matter of personal choice.