Page 1 of 1
Creating and running a process
Posted: Sun May 19, 2013 9:40 am
by jhunterd
I want to know how to create a new process in kernel land. Is it as simple as copying a bunch of opcodes to memory and jumping there, or is there an extra step that I have to take?
Re: Creating and running a process
Posted: Sun May 19, 2013 11:24 am
by iansjack
It rather depends upon the design of your OS. As well as the steps you mention you may have to:
Allocate some memory pages and intialize a page map.
Create a task structure to hold details of the process.
Save the details of the current process to it's task structure.
Load the opcodes, and initialized variables, from a storage device.
Switch the processor to user mode.
Almost any serious OS will require those steps; more may be necessary for a more advanced design.
Re: Creating and running a process
Posted: Sun May 19, 2013 1:10 pm
by sortie
If you copy code into memory and move the instruction pointer such that you execute it, then you will execute that code. This isn't enough to create processes, but it is an important part of it. You will like to check out user-mode and scheduling as well. I recommend making your kernel multithreaded early on.
Re: Creating and running a process
Posted: Sun May 19, 2013 1:20 pm
by jhunterd
If I wanted a monotasking OS, would it be possible that I could do something like the following to start a process:
Code: Select all
int new_proc(...)
{
switch_to_user_mode();
unsigned int * mem = find_free_memory();
set_up_paging(mem);
move_to_memory(mem, opcodes);
initialize_task_struct(pid, priority, mem, foo, bar);
jump_to_memory(mem);
return error_code;
}
Re: Creating and running a process
Posted: Mon May 20, 2013 1:26 pm
by bluemoon
For protection purpose, kernel code should not be accessible from user mode,
therefore it is better to do switch_to_user_mode after things has been setup, and do switch_to_user_mode(user_eip, user_stack);
Take my OS as example, to execute a program, I call this function:
Code: Select all
unsigned int process_create ( const char* file, unsigned int priority, unsigned int quantum );
This function create a process entry, which contain meta info, scheduling parameters and execution states (including paging structures).
It also fill the environment like executable filename, etc into a process header structure.
It then enqueue this struct into the process list.
The execution state is specially craft to "resume" into another kernel function:
process_stub.
So, when the newly process is scheduled, execution resume in its own address space and execution environment, and to this function:
Code: Select all
void process_stub ( PROCESS* process );
This function load the executable file, perform relocation and runtime linking, allocate user stack, then call:
Code: Select all
enter_ring3((unsigned long)prog.get_entry(), (unsigned long)APPADDR_PROCESS_STACK);
What enter_ring3 do is prepare register states and do IRETQ or SYSRET.
The application will be started in user mode, and upon it finish it must call _exit() since there is no return address on stack (and kernel code is protected anyway).
Re: Creating and running a process
Posted: Mon May 20, 2013 2:50 pm
by jhunterd
Also, about setting up paging for the processes: how would I go about this? Would I do the following:
Purposely skip setting up paging for the kernel,
jump to the address where I want my process to be, and
set up the page tables to map that page to 0x0 in virtual memory?
Re: Creating and running a process
Posted: Tue May 21, 2013 3:43 am
by bluemoon
Instead of spoon-feed you step by step how everything is done, I truly recommend you read the related materials, manuals, and the wiki.
Re: Creating and running a process
Posted: Tue May 21, 2013 5:27 am
by jhunterd
Yeah, that's probably a good idea.