fork() with higher half kernel

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
tkausl
Posts: 17
Joined: Tue Jul 14, 2015 9:54 pm

fork() with higher half kernel

Post by tkausl »

Hello,

i'm having a big problem at the moment, i don't know *anything* i could do about it.

I am using a higher half kernel, mapped at 3GB. Now i am implementing multithreading. Everything works really good at the moment, i can run two processes in kernel-space and i can even load my initrd elf file and start this one. But now i want to implement exec() and fork(). The thing is, for fork, i need to create a new page-directory and 'deep'-copy everything over. This means, new page-tables and everything that is mapped in process1's address-space needs to be copied. But, i don't see any possibility how i could copy the data in ram since there is 'no' way i can map in both directory's at the same time (Remember, after i've copied the page-directory and all tables, 0x10 in the first addressspace maps to another physical address then 0x10 in the second addressspace). I've seen in some tutorial that he disabled paging to copy everything over, but i just can't disable paging since my IP is at some high address >3GB. The only way i could think of is identity-map the kernel again, jump back to a ~1MB address, disable paging, copy everything over, enable paging again, jump back to higher half. But not even that is (easy) doable since the processes address-spaces are *not* necessarily a continuous block of *physical* memory.

Every bit of information could be helpful, i hope someone can give me a pointer :wink:
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: fork() with higher half kernel

Post by Combuster »

You can always map pages temporarily to write them.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
tkausl
Posts: 17
Joined: Tue Jul 14, 2015 9:54 pm

Re: fork() with higher half kernel

Post by tkausl »

Combuster wrote:You can always map pages temporarily to write them.
Yeah i thought the same, but this has to be a badass-logic to find free pages and don't overwrite the actual used pages...
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: fork() with higher half kernel

Post by iansjack »

You're not keeping track of which pages are in use and which aren't?
linguofreak
Member
Member
Posts: 510
Joined: Wed Mar 09, 2011 3:55 am

Re: fork() with higher half kernel

Post by linguofreak »

tkausl wrote:Hello,

i'm having a big problem at the moment, i don't know *anything* i could do about it.

I am using a higher half kernel, mapped at 3GB. Now i am implementing multithreading. Everything works really good at the moment, i can run two processes in kernel-space and i can even load my initrd elf file and start this one. But now i want to implement exec() and fork(). The thing is, for fork, i need to create a new page-directory and 'deep'-copy everything over. This means, new page-tables and everything that is mapped in process1's address-space needs to be copied. But, i don't see any possibility how i could copy the data in ram since there is 'no' way i can map in both directory's at the same time (Remember, after i've copied the page-directory and all tables, 0x10 in the first addressspace maps to another physical address then 0x10 in the second addressspace). I've seen in some tutorial that he disabled paging to copy everything over, but i just can't disable paging since my IP is at some high address >3GB. The only way i could think of is identity-map the kernel again, jump back to a ~1MB address, disable paging, copy everything over, enable paging again, jump back to higher half. But not even that is (easy) doable since the processes address-spaces are *not* necessarily a continuous block of *physical* memory.
Modern *nixes tend to implement fork() with a copy-on-write mechanism. The page table entries for the original process are marked as read-only and copy-on-write, then duplicated for the new process, so that not only are the content's of both processes' address spaces identical, but they're actually using the same physical memory. When one of the processes writes to a (virtual) page, it causes a page fault because the page is marked read only. The kernel then sees that the page is also marked copy-on-write, finds a free physical page, assigns that page to the virtual page slot in question for the process attempting to write, copies the data into it, leaves the original physical page assigned to the other process, and removes the copy-on-write and read only markings for the virtual page in both proceses. So no userspace data is actually copied at all during the original fork() call: data is only copied in small chunks, and only when one of the processes need to modify it. Data that both processes are reading from without writing to can be, and is, left uncopied.
Every bit of information could be helpful, i hope someone can give me a pointer :wink:
0x00FCDC9A :P
Post Reply