Question

I wonder if it's possible to create a new thread from scratch. (Unlike fork() which gives me a copy of the memorymap and registerstate, etc.) Starting with an empty page-table, into which I can map code and data. I'd also need a way to place the instruction pointer.

Motivation: In hardware emulators I often find stuff like

uint32_t read32(uint32_t addr) {
    if (RAM1_BEGIN <= addr && addr < RAM1_END)
        return *(uint32_t*)(ram1 + (addr-RAM1_BEGIN));
    else if (RAM2_BEGIN <= addr && addr < RAM2_END)
        return *(uint32_t*)(ram2 + (addr-RAM2_BEGIN));
    ...
}

I thought it would be a waste of time to emulate an MMU when the host already has one.

I could just use mmap() to get free memory at the spots the hardware has, but I can't be 100% sure that it will be free. (Loader places binary and libraries arbitrarily.) That's why I concluded that I need a new empty thread (and address space).

Was it helpful?

Solution

As I commented, you should not consider starting threads from scratch without using a thread library (like pthreads)

You could use (and study the source code of) MUSL libc which is a lighter, and easier to read, libc library.

If you want to develop your own thread library, you'll need to use clone(2) & futex(2) and you'll have to code several things in assembler (see futex(7) which explains why, and also setcontext(3)).

If you want to develop your own thread library (I strongly recommend not going that route), be prepared to spend many months of work! You'll probably need to understand how the compiler works (it is related to the thread implementation), and perhaps to patch it.

addenda

For your particular problem of setting some specific address space, you could just use cleverly mmap(2) and munmap(2) (and disable ASLR), but don't forget before to relocate your code elsewhere and jump to it... (this is the tricky issue, perhaps linking statically and compiling with -fPIE could help; you'll need to understand precisely ELF and what your libc is doing...). If you know statically what address space you want -e.g. if RAM1_BEGIN etc are compile time literal constants- you could use specific ld directives or scripts to enforce it at link time.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top