Agreed, it is not clear to me either
The last time I was developing stuff this low level was 68000 on the Amiga, so please forgive my ignorance. But your post gave some good entry points for further research which is really helpful, thanks!
So I was thinking I already have an āOSā, but now I think the term I was looking for is possibly Microkernel, and Iām not even sure I have that yet 
But if we take something simple, like plot(x,y). My microkernel holds an implementation of that which includes access to the SoC/hardware. Above the hardware layer I have generated some more user-friendly API for things like line() which delegate to plot().
Currently, the built in apps are part of my microkenel, and have simple easy access to that API. Now I try to imagine how an 2nd Zig binary (objcopy bin) loaded at runtime is going to work. We can ignore the portability ELF would offer, and assume it is just a blob of arm assembly with a known entry point. Maybe this is what you mean by position-independent code?
One solution is to just build each app as a complete microkernel, if that is the right term here, but this obviously leads to complexity accessing shared hardware resources.
Another idea, which I portrayed badly, was that my microkernel somehow has a table of pointers to the implementations of this API. Maybe I can use the linker file to fix the location. But that table would be at a fixed publicly known location in RAM. So for shared hardware resources I can manage concurrency more easily, since every access goes via these system? calls. I think DOS VGA programming worked something like this.
What I cant get my head around is how the 2nd binary can make a call to these addresses/function pointers. It is something like an @extern? but without the implementation in the compile unit. So here I was thinking Iād probably need some assembly to do a āBLā. Then my line() API for the 2nd binary would wrap a bit of assembly that would prepare registers and goto/gosub the fixed address for the correct function. I hope that makes more sense now?
And callbacks maybe work in a similar way, a RAM address of a fn is passed to the microkernel, and that uses some assembly to call back to the 2nd app.
So I think Iām asking how to do āexternā without the symbol known to the compiler? Is assembly the right way to go here?