I think something close to what I am trying to propose has been discussed here - https://groups.google.com/g/osv-dev/c/DI6FBYHYNdQ/m/OU6kcZuYAwAJ. And I think some of the things discussed there were addressed by the ability to build the kernel with most non-libc symbols and STD C++ hidden, enabling garbage collection (see 730fd82ef76d7f4d201fe60960c31fa8d3766371), extracting ZFS as a separate library, conditionally adding drivers using a concept of "profiles" and finally supporting building version of the kernel with only symbols needed by specific app (see d19ccb1cde100ab4a5c8e6db9a0d69560cabbd04).
But I think we can go one step further and allow linking some apps with the kernel into a single elf - say loader_with_app.elf and the hello world would not be difficult I think. The initial and naive prototype would simply involve calling main directly from loader.cc and linking with apps/native-example/hello.o. Now the kernel is compiled as position-dependent executable and correct compiler options would need to be used when compiling the app object files. This is where I am not sure how it would "scale" beyond a single-object file case of the "hello world" example. Also, how would it work for non-C apps - C++ or things like Rust? And most likely this would not ever work for things like Golang. But for some cases - say Redis or Nginx it might make perfect sense.
Obviously in such a case kernel would expose 0 symbols and ideally do not even need most of its dynamic linker, right? From the security perspective, it would be a total "closed world" appliance. Would we benefit from a performance perspective? Possibly.
I think something close to what I am trying to propose has been discussed here - https://groups.google.com/g/osv-dev/c/DI6FBYHYNdQ/m/OU6kcZuYAwAJ. And I think some of the things discussed there were addressed by the ability to build the kernel with most non-libc symbols and STD C++ hidden, enabling garbage collection (see 730fd82ef76d7f4d201fe60960c31fa8d3766371), extracting ZFS as a separate library, conditionally adding drivers using a concept of "profiles" and finally supporting building version of the kernel with only symbols needed by specific app (see d19ccb1cde100ab4a5c8e6db9a0d69560cabbd04).
But I think we can go one step further and allow linking some apps with the kernel into a single elf - say
loader_with_app.elf
and thehello world
would not be difficult I think. The initial and naive prototype would simply involve calling main directly fromloader.cc
and linking withapps/native-example/hello.o
. Now the kernel is compiled as position-dependent executable and correct compiler options would need to be used when compiling the app object files. This is where I am not sure how it would "scale" beyond a single-object file case of the "hello world" example. Also, how would it work for non-C apps - C++ or things like Rust? And most likely this would not ever work for things like Golang. But for some cases - say Redis or Nginx it might make perfect sense.Obviously in such a case kernel would expose 0 symbols and ideally do not even need most of its dynamic linker, right? From the security perspective, it would be a total "closed world" appliance. Would we benefit from a performance perspective? Possibly.