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.