user programs
user programs
Hi, in my very short holiday time, I was thinking (just thinking ) about user side issues. I wonder how people are dealing with user programs, I mean do you link user programs within kernel? I think this is not a good idea because then user and kernel thingz might get corrputed. ( But I cannot immediately think of a good reason why thingz might get corrupted ;D) Anyway I am thinking of loading them externally using a loader but then another question would be where should I link user programs? A scenario might be like:
create_user_program() called:
OS loads user program's executable into memory. (or at this stage copy its executable but then how will we manage seperated address spaces?) Physical address of loaded file's buffer is important since we can correctly map user program's address space.
I think I can link all user programs programs to same virtual address, since mapping is done by memory manager after loading is done.
Well I know that there is currently nothing about protection stuff (i.e. the ringU, privileges) but they will be applied after loading is finished while mapping is done and also appropriate ldt or gdt is created for new user process.
How do you think is that start?
create_user_program() called:
OS loads user program's executable into memory. (or at this stage copy its executable but then how will we manage seperated address spaces?) Physical address of loaded file's buffer is important since we can correctly map user program's address space.
I think I can link all user programs programs to same virtual address, since mapping is done by memory manager after loading is done.
Well I know that there is currently nothing about protection stuff (i.e. the ringU, privileges) but they will be applied after loading is finished while mapping is done and also appropriate ldt or gdt is created for new user process.
How do you think is that start?
Re:user programs
Hey, searching for older threads, I found my this thread which is not really taken care of I think I want to make it more clear. I have a very simple question: we cannot jump to a ring3 procedure from a ring0 code right? Or did I miss something? Thanx. I am not very good at this protection stuff, I have currently started reeading and learning some things,..
One ring0 to find them, One ring0 to rule'em all...
One ring0 to find them, One ring0 to rule'em all...
Re:user programs
To run a user-mode process:
So starting a new program doesn't require any special behaviour as long as you already have multitasking implemented; just add the new program to the list of schedulable tasks and continue.
- Create a process (an object which contains an address space)
- Load an executable file into the process
- Create a thread within the process
- Add the thread to the ready list
- Switch threads
So starting a new program doesn't require any special behaviour as long as you already have multitasking implemented; just add the new program to the list of schedulable tasks and continue.
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:user programs
Nope, we cannot ... however, we can fool the CPU and make it believe we're returning to a caller at ring3 when we're at ring0 ...Ozgunh82 wrote: we cannot jump to a ring3 procedure from a ring0 code right? Or did I miss something?
... and with the Runtime Link them ;DOne ring0 to find them, One ring0 to rule'em all...
Re:user programs
OK, as far as I understand for decreasing the privilege level, you are doing software task switching, right? (I mean the iret way) so is there a way to decrease privilege level, in particular to switch from ring0 to ring3, using hardware task switching?
Re:user programs
Yes. To switch to a ring 3 task, switch to a TSS where the RPL of CS is 3. To return from a syscall, do an IRET.
Re:user programs
well, ok, I nearly got a user mode task added into the scheduler queue. I need one more _easy_answer: (Im sorry im another victim of intel manuals) ;D What is the real usage of rpl? I mean do we really need it? Is it not just for overriding the cpl so that a ring 0 process can be seen as a ring1 or ring 2 or etc. process? Do we have to set it same as cpl? When I first read about it I thought that we can just set rpl to 0 everywhere and forget about it. But that is appearently false, right? Or am I just confusing all the terminology? Thanx...
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:user programs
iirc, let's say you have a ring-3 data segment UDATA, a ring-3 code segment UCODE and a ring-0 code segment KCODE.
The Descriptor priviledge level of UDATA is 3: this is what is held in the LDT/GDT. It indicates that any level can access the data. When UCODE is running, the Current Priviledge level is 3 (this is equal to the DPL for the UCODE segment, and is stored in the RPL bits of the CS register).
Because the CPL is 3, when your user-level code tries to access the data segment, it must use a selector with the RPL bits both set, thus for user-level code the selector will be UDATA+3.
However, if UCODE makes a trap (system call, for instance) and if the kernel has to use the user-level segment, it should (iirc) load UDATA rather than UDATA+3 as selector.
The Descriptor priviledge level of UDATA is 3: this is what is held in the LDT/GDT. It indicates that any level can access the data. When UCODE is running, the Current Priviledge level is 3 (this is equal to the DPL for the UCODE segment, and is stored in the RPL bits of the CS register).
Because the CPL is 3, when your user-level code tries to access the data segment, it must use a selector with the RPL bits both set, thus for user-level code the selector will be UDATA+3.
However, if UCODE makes a trap (system call, for instance) and if the kernel has to use the user-level segment, it should (iirc) load UDATA rather than UDATA+3 as selector.
Re:user programs
Lots of thinking, I need some communication. Well, Ive been thinking about user mode programs for some time, Ive some questions:
- I am planning to use a call gate to pass the system calls to kernel. Is that a good idea? Can this have any security flaws? I mean since all operating systems are doing system calls through one interrupt or call gate or whatever, can somebody who understands the internal working of system calls do some bad things to the system?
- Why is there so much library files? I think standard library is just about passing system call to kernel by calling the call gate, and setting appropriate parameters of course. Aint one standard library file enough? There is nothing technically implemented in it at all, right?
- I am planning to use a call gate to pass the system calls to kernel. Is that a good idea? Can this have any security flaws? I mean since all operating systems are doing system calls through one interrupt or call gate or whatever, can somebody who understands the internal working of system calls do some bad things to the system?
- Why is there so much library files? I think standard library is just about passing system call to kernel by calling the call gate, and setting appropriate parameters of course. Aint one standard library file enough? There is nothing technically implemented in it at all, right?
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:user programs
well, there are more than passing args to syscall in the standard library. For instance, the 'FILE*' abstraction is specific to C language and not to the operating system. The stdio sub-library makes sure that you will be able to have FILE* using the OS system calls... Other things like gethostbyname() for instance even go further and read whole files, connect to servers and issue DNS request to have your preciousss data ...
And beyond standard libraries, you have 'helper' libraries like libjpeg, libsdl, and the like ...
At call gates versus interrupt gates, there's not much difference between the two except that the interrupt is in essence global (while a call gate may be local to a process) and can only receive args through registers (while the call gate may copy a portion of the user stack on the kernel stack and helps seing the system call as a regular function call).
However, issuing a 'int nn' is 2 byte long while the call gate is "<opcode><offset><segment>" (about 7 bytes)
Now if you really want to know, there's also the so-called "syscall" or "sysenter" (depending you're using Intel or AMD) extended instruction that provide a fast (though limited) system call mechanism ...
And beyond standard libraries, you have 'helper' libraries like libjpeg, libsdl, and the like ...
At call gates versus interrupt gates, there's not much difference between the two except that the interrupt is in essence global (while a call gate may be local to a process) and can only receive args through registers (while the call gate may copy a portion of the user stack on the kernel stack and helps seing the system call as a regular function call).
However, issuing a 'int nn' is 2 byte long while the call gate is "<opcode><offset><segment>" (about 7 bytes)
Now if you really want to know, there's also the so-called "syscall" or "sysenter" (depending you're using Intel or AMD) extended instruction that provide a fast (though limited) system call mechanism ...