Page 1 of 1

Paging done.. how to start a monotasking.

Posted: Fri Jul 29, 2005 1:55 pm
by viral
Hello...
My kernel ("asm" + "C++") is now having following features:
1. Memory management (kmalloc, kfree).
2. GDT
3. IDT
4. Paging (pageallocate, pagefree, pagebind, pageunbind, createpagetable, createcontext)
5. Floppy driver.

Now i need to start a monotasking system (as i cant go directly to multitasking, i guess).I want to create a user task (for that i must have two entries in GDT user code+data, i guess). And remaining things like :

1. Create a pagedirectory.
2. Create page tabe for CODE
3. Create page table for DATA
4. Bind these pagetables to pagedirectory.
5. Load user code (may be binary file) into CODE page.
6. Load CR3 reg with pagedirectory address.
7. Jump to the starting of CODE.

Now this is what i know all about creating a task, but now really stuck. How to do these things? Please give me spoonfeeding.

Re:Paging done.. how to start a monotasking.

Posted: Fri Jul 29, 2005 3:10 pm
by GLneo
well i dont know much about paging yet but to jump to code:

Code: Select all

void call(void *code)
{
    void(*func)();
    func = code;
    func();
}

Re:Paging done.. how to start a monotasking.

Posted: Mon Aug 01, 2005 11:51 am
by viral
Hello...
Thanx for it but presently I am using this only, I guess it works only when our task have all previleges of ring 0, as we are not executing a task but just calling a function in kernel. So I need a way of Loading different CS, SS and PageDirectory and then "call MyTask" so that this task executes at ring 3.

Re:Paging done.. how to start a monotasking.

Posted: Mon Aug 01, 2005 9:15 pm
by AR
If you support a binary format the page directory part is a bit easier (but you have to write the interpreter for the binary's headers), if you want something simple then a.out should be easy IIRC.

All you really need to do is follow the files instrucions on how to create the image in memory (Code goes at X, read Y bytes into memory at virtual address X. Data goes at Z, read W bytes into memory at virtual address Z. BSS goes at B, zero C bytes and map the pages at virtual address B.) then you can just pack the stack with PUSH and use IRET to switch to user space at the programs entrypoint.

For something simpler that just shows you that it works you can simply create a program that fits entirely on one page, like:

Code: Select all

mov eax, 1
mov ebx, msg
int $0x80 ;System Call (Function 1 - Print Text)
jmp $

msg: db 'Hello', 0

Re:Paging done.. how to start a monotasking.

Posted: Fri Aug 05, 2005 1:08 pm
by viral
Thanx buddy...
I got you. You r saying that i must place :

Programs DATA => My Virtual DATA
Programs CODE => My Virtual CODE
Programs BSS => My Virtual BSS

Thats right, but how i will get that which part of the executable is code,data or bss. I mean if my executable (binary or elf or exe whatsoever) is of 100 bytes then which chunk is CODE & which is DATA?

Re:Paging done.. how to start a monotasking.

Posted: Fri Aug 05, 2005 3:50 pm
by AR
You have to read the headers, the headers tell you what part of the file is which and where to put it. Flat binary obviously doesn't have headers though.

Re:Paging done.. how to start a monotasking.

Posted: Tue Aug 09, 2005 12:27 pm
by viral
Hello...
Lets load a flat binary into memory and run it. For that i have to do following steps i guess:
1. Allocate memory for binary and copy it into ram.
2. Make a page directory for the new process.
3. Make a page table and bind all allocated memory into it.
4. Mark the space as code and data (as flat binary doesnt have different segments).
5. Load page directory.
6. Run the program.


I can get only this much. is this right? Why people are not replying? Is running a simple task is boring?

Re:Paging done.. how to start a monotasking.

Posted: Tue Aug 09, 2005 6:42 pm
by Brendan
Hi,
viral wrote: Lets load a flat binary into memory and run it. For that i have to do following steps i guess:
1. Allocate memory for binary and copy it into ram.
2. Make a page directory for the new process.
3. Make a page table and bind all allocated memory into it.
4. Mark the space as code and data (as flat binary doesnt have different segments).
5. Load page directory.
6. Run the program.
Perhaps, but where in RAM will you load the flat binary, and what will it be loaded from?

How about:
1. Make the process control data
2. Make a page directory for the new process
3. Spawn a kernel thread for the new process
4. Switch to the new kernel thread
5. Open the binary file and load the header
6. Check where it should be loaded, if it's compatible, it's size, etc
7a. Allocate user-level pages and load the binary into the address space
-OR-
7b. Memory map the binary file into the address space
8. Do an IRET to enter CPL=3 and start running the new binary code (the spawned kernel thread becomes the new process's first thread).

Of course this assumes that you've already got multi-tasking, device drivers, file systems, etc.


Cheers,

Brendan

Re:Paging done.. how to start a monotasking.

Posted: Wed Aug 10, 2005 3:24 pm
by Crazed123
Why an IRET? Is there some guarantee we're loading the process during an interrupt?

Re:Paging done.. how to start a monotasking.

Posted: Wed Aug 10, 2005 3:40 pm
by JoeKayzA
Crazed123 wrote: Why an IRET? Is there some guarantee we're loading the process during an interrupt?
An IRET is not limited to be used within an ISR. You can use it anywhere when you have the appropriate values on the stack. But when you jump to user space code, it's probably the best solution (or even the only? is there an alternative without hardware task switching?) because you can set EIP, SS, ESP and CS with only one instruction.

cheers Joe

Re:Paging done.. how to start a monotasking.

Posted: Wed Aug 10, 2005 10:10 pm
by Brendan
Hi,
JoeKayzA wrote:But when you jump to user space code, it's probably the best solution (or even the only? is there an alternative without hardware task switching?) because you can set EIP, SS, ESP and CS with only one instruction.
IIRC you could also use a RETF and pretend you're returning from a call gate - it's mostly the same except it doesn't set EFLAGS like an IRET would. I like starting a new thread/process with a clean state, so I prefer to set EFLAGS :).


Cheers,

Brendan