|
|
Subscribe / Log in / New account

Nolibc: a minimal C-library replacement shipped with the kernel

Nolibc: a minimal C-library replacement shipped with the kernel

Posted Jan 21, 2023 6:02 UTC (Sat) by wtarreau (subscriber, #51152)
Parent article: Nolibc: a minimal C-library replacement shipped with the kernel

It's excellent, I hoped that others would voice in suggesting related projects, and in 4 comments we discover 3 alternative projects. It definitely shows that there's an expressed need for a low-level stdlib, especially when it comes to embedded systems (like picolibc seems to address) or just early kernel. In all such environments the problem is the same, we have to reimplement everything before starting to have a usable main().

Based on previous discussions for splitting nolibc into multiple files, the point was raised a few times that what is desired is to have the OS-independent stuff being either self-sustaining (e.g. memcpy()) or relying on a portable syscall API and _start code, and that's why we split the code like this (probably far from being perfect yet). In a modern world we could imagine the stdlib being provided with the language (and toolchain) and the syscall with the OS and arch, both in source form so that they're built on the fly with the resulting program. Maybe building the high-level stuff would be slow once the lib becomes rich though.


to post comments

Nolibc: a minimal C-library replacement shipped with the kernel

Posted Jan 21, 2023 8:21 UTC (Sat) by WolfWings (subscriber, #56790) [Link] (5 responses)

Not even a need for a low-level stdlib always so much as a "Why do we require literally megabytes just to get Hello World to run?" situation. Even on a modern system with SSD's I was surprised how much of the boot time was waiting for ~50MB of initrd to be read off of the disk and decompressed.

In theory all the tools are there, libc.so could be a set of much smaller components that could be dlopen'ed transparently the first time any given families of functions are called and instrumented to let other software only copy over actually required components, but that's less "efficient" (performance hits, re-using mappings across processes, etc) for the normal system case where hundreds of tools will all be loading libc in parallel.

So instead they're even removing separate libraries and merging them into libc.so lately like pthreads and bulking up the single monolithic library even more.

Nolibc: a minimal C-library replacement shipped with the kernel

Posted Jan 22, 2023 2:19 UTC (Sun) by wahern (subscriber, #37304) [Link] (1 responses)

Keeping pthreads separate from glibc core is one of the major reasons glibc is so bloated and convoluted, as they basically had to duplicate 1/2 of it to support dynamic loading of libpthread, plus even more complexity so those internal pieces worked cleanly with the related pthreads primitives. In fact, dlopen and related interfaces are crazy complex because of this. Pthreads integration has made musl smaller and simpler, including dlopen and the dynamic linker. Fortunately, glibc recently merged libpthread into the core, though negative consequences of the separation may never be fully eliminated. Similarly, another source of bloat and headaches in glibc is NSS support, which was originally justified for much the same reasons as you propose: putting lesser used facilities behind dlopen'd modules. But abstraction invites complexity, especially when it prevents you from implementing a simple, 80% solution inline. Notably, musl rejected NSS support.

A major reason for musl's lighter footprint is eschewing locale support--the original idea was that simply being UTF-8 clean would suffice for a POSIX-compliant environment, though they eventually had to backtrack somewhat even after some concessions from [future] POSIX. glibc's locale support adds alot of weight, and significantly impacts performance. OTOH, this is probably one of the more justifiable features of glibc; at least, justifiable at a time when Unix environments, and libc specifically, were more often relied upon for higher-level application interfaces--timekeeping, I18N, string processing, etc. OTOOH, simply avoiding locale interfaces entirely, POSIX be damned, is one of the easiest choices to justify for a lightweight, embedded libc.

Nolibc: a minimal C-library replacement shipped with the kernel

Posted Jan 22, 2023 2:49 UTC (Sun) by Cyberax (✭ supporter ✭, #52523) [Link]

> this is probably one of the more justifiable features of glibc

No, it's not. It would have been justifiable if the interface were a little bit more thought out. But it's thread-unsafe and clunky.

Nolibc: a minimal C-library replacement shipped with the kernel

Posted Apr 11, 2023 22:38 UTC (Tue) by Phoenix591 (guest, #157780) [Link]

if you manually adjust your kernel config, depending on your disk layout, you can get down to no/ a nice small initrd. If not using lvm or raid or luks for / you can just build everything into the kernel and be fine without one. I use lvm for my / and have a 2.5 M initrd with static lvm, fsck, busybox, and microcode. to get root mounted.

boots faster than the autogenerated giant initrds too.

Nolibc: a minimal C-library replacement shipped with the kernel

Posted Apr 20, 2023 11:32 UTC (Thu) by anselm (subscriber, #2796) [Link] (1 responses)

In theory all the tools are there, libc.so could be a set of much smaller components that could be dlopen'ed transparently the first time any given families of functions are called and instrumented to let other software only copy over actually required components, but that's less "efficient" (performance hits, re-using mappings across processes, etc) for the normal system case where hundreds of tools will all be loading libc in parallel.

Systems like Linux already use “demand paging”, i.e., only those pages of libc.so (or any executable) that contain code which is actually being executed are fetched into memory (and evicted again if their code hasn't been executed in some time). Chances are that, with loads of different processes using libc.so simultaneously, almost all of it will be used by something, but in principle the system is pretty good at ignoring unneeded stuff, so the added complication of subdividing libc.so seems unnecessary.

Nolibc: a minimal C-library replacement shipped with the kernel

Posted Apr 21, 2023 10:20 UTC (Fri) by farnz (subscriber, #17727) [Link]

Rather than splitting libc.so, then, would a better option be to work out what pages of libc are commonly used together, and group things such that you don't page in the bits you're not going to use? That way, you need only build system changes to libc (possibly quite big ones), but then all applications benefit immediately (e.g. if you don't ever use the X/Open Message Catalog interface for message translation, you don't page in any of the functions involved in that interface).


Copyright © 2025, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds