Page 1 of 1

Should kernel code be readable from user space?

Posted: Tue Jul 10, 2012 11:47 pm
by Dominator
Hi all, I'm studying the JamesM kernel tutorials and adding functionality to my kernel. Right now I'm a bit confused by the following snippet in initialise_paging() in paging.c:

Code: Select all

while (i < placement_address + 0x1000) {
    // Kernel code is readable but not writeable from userspace.
    alloc_frame(get_page(i, TRUE, kernel_directory), FALSE /* is_kernel */, FALSE /* is_writable */);
    i += 0x1000;
}
The author mentioned in the last lines of the last tutorial that the kernel code needs to be accessible from user space, since the main() funciton in the kernel executes code (in the user space) after the

Code: Select all

// code
switch_to_user_mode();
// other code
line.

If I allocate frames with the supervisor (is_kernel) flag set to true (which I guess should be the correct way for protection), no other statement can be executed after that line. So I'm not sure how to make the switch and do some subsequent call to, say, spawn a shell in the user mode.

Any help would be appreciated. Thanks!

Re: Should kernel code be readable from user space?

Posted: Tue Jul 10, 2012 11:58 pm
by NickJohnson
That's just a stopgap solution that you'll want to replace once you get proper executable loading working. JamesM's tutorial is filled with issues like that.

If you want to run a real program, you need to get the executable into memory somewhere, then load it into userspace based on its headers (which depends on your executable format.) Then you can switch to usermode in a way that jumps to it. Since switching to usermode is only possible with an iret in the first place, that shouldn't be hard to do.

Re: Should kernel code be readable from user space?

Posted: Wed Jul 11, 2012 12:09 am
by Dominator
NickJohnson wrote:That's just a stopgap solution that you'll want to replace once you get proper executable loading working. JamesM's tutorial is filled with issues like that.

If you want to run a real program, you need to get the executable into memory somewhere, then load it into userspace based on its headers (which depends on your executable format.) Then you can switch to usermode in a way that jumps to it. Since switching to usermode is only possible with an iret in the first place, that shouldn't be hard to do.
Thanks for the answer. So I need to implement something like an exec() syscall, which allocates user mode pages for the executable, copies the content over, performs the switch_to_user_mode steps and pushes the EIP before the final IRET. Does that sound right?

Re: Should kernel code be readable from user space?

Posted: Wed Jul 11, 2012 12:19 am
by NickJohnson
That should work. Of course, the first exec() will have to be done from kernelspace, because there is no userspace program to call exec().

Re: Should kernel code be readable from user space?

Posted: Wed Jul 11, 2012 12:23 am
by Dominator
NickJohnson wrote:That should work. Of course, the first exec() will have to be done from kernelspace, because there is no userspace program to call exec().
Great. I will try to implement that. Thanks for your help!