<div dir="ltr"><div dir="ltr">On Sun, Aug 1, 2021 at 8:19 PM John Cowan <<a href="mailto:cowan@ccil.org">cowan@ccil.org</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr"><div style="font-family:"times new roman",serif;font-size:large"><span style="font-family:Arial,Helvetica,sans-serif;font-size:small">On Sun, Aug 1, 2021 at 8:13 PM Andrew Warkentin <</span><a href="mailto:andreww591@gmail.com" target="_blank" style="font-family:Arial,Helvetica,sans-serif;font-size:small">andreww591@gmail.com</a><span style="font-family:Arial,Helvetica,sans-serif;font-size:small">> wrote</span><br></div></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">To start the child the parent would either<br>
call exec() to start the child running a different program, or call a<br>
new function that starts the child with a parent-provided entry point<br>
and whatever memory mappings the parent set up. </blockquote><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">This is what I plan to do on the OS I'm writing<br>
(manipulating the child's state won't require any additional<br>
primitives beyond regular file I/O since literally all process state<br>
will have a file-based interface).<br></blockquote><div><br></div><div style="font-family:"times new roman",serif;font-size:large">In that case you don't need *any* primitive except create_empty_process(): you can do exec() by opening the file, writing to /proc/<child>/mem and then to <proc/<child>/pc-and-go.</div></div></div></blockquote><div><br></div><div>Sadly, that's not _quite_ true. You still need some primordial way to get the system going.</div><div><br></div><div>Once you have a proc_create and a make_proc_runnable system call, it seems like it opens the door to doing all kinds of cool things like moving binary parsers out of the kernel and into user space, but consider how `init` gets bootstrapped: often, there's a handful of instructions that basically invoke `execl("/bin/init", "init", 0);` that you compile into the kernel; on creation of process 1, the kernel copies those instructions into a page somewhere in user portion of the address space and "returns" to it; the process then invokes /bin/init which carries on with bringing up the rest of the system.</div><div><br></div><div>Now you're confronted with two choices: you either put a much more elaborate bootstrap into the kernel (in this day and age, probably not that hard), or you have a minimal bootstrap that's smart enough to load a smarter bootstrap that in turn can load something like init. I suppose a third option is to compile `init` in some dead simple way that you can load in the kernel as a special case, and invoke that. This problem isn't insurmountable, but it's a wide design space, and it's not quite as straight-forward as it first appears.</div><div><br></div><div>As I mentioned in the email I linked to earlier, Akaros implemented the proc_create/proc_run model. It really was superior to fork()/exec() and I would argue superior to spawn() as well.</div><div><br></div><div>        - Dan C.</div><div><br></div></div></div>