Minimalist libc/STL implementations?
Minimalist libc/STL implementations?
Hi, are there any partial implementations of libc or the STL that would be good for using in a kernel? Maybe something developed with that use in mind? (Yeah, I know, that's quite unlikely, but I'm asking anyway because it's possible someone here has developed such a thing themselves.) Mainly, I just want robust implementations of the more basic C headers that don't need OS support (like stdint, stddef, stdarg, etc.) but are useful to have in generally any situation and the STL (that is, just the STL, not all the other stuff that is now part of the standard C++ library). I realize these things are nothing but a lot of #defines (in the case of the libc headers I want) or simple classes (in the case of the STL) that I could write naive implementations of in a few days, but there is apparently a lot that goes into them and I would rather use well tested code written by people better than myself as the library for my kernel.
Re: Minimalist libc/STL implementations?
It depends on what you want to do and how much effort you wish to invest:
1) Your cross-compiler comes with freestanding headers like stdarg.h, stddef.h, stdint.h, and a bunch more. You can literally just use them out of the box when you have installed your cross-compiler. This is the zero effort, the problem is already solved solution.
2) You may wish to look into http://pdclib.e43.eu/, which aims to be a minimal standard C implementation. It doesn't implement POSIX, just standard C and a few extensions in spirit with the C standard.
3) You may wish to look into an existing libc you can port. Popular choices include newlib or pdclib (mentioned above), I have heard people have ported glibc (though that is supposedly considerably harder). There are also musl, but I am not sure how portable that is to non-Linux.
4) You can write your own libc implementation! That's what I did (although I didn't fully intend on that to happen, it kinda just did). It will likely take a long time to finish, years in my case to get to it to a somewhat complete point, but it is worth it as you control the quality and can make sure it integrates perfectly into your project (unlike the other `ports' that are kinda alien unless you use considerable effort). Fortunately, the core parts of a libc isn't too terribly hard to write and you can get far in little time, though stuff like stdio is surprisingly tricky.
As for a C++ standard library implementation, you can port libstdc++ that comes with GCC without too much effort when you have a proper libc for your user-space. I'm not too sure on kernel usage, however, I am yet to really research that. I know clang also has libc++. I'm not sure to which degree you can mix and match components. I'd almost argue against using the C++ standard library in a kernel because things seem to be nasty in the examples I have seen, but that just means I don't know the proper way.
1) Your cross-compiler comes with freestanding headers like stdarg.h, stddef.h, stdint.h, and a bunch more. You can literally just use them out of the box when you have installed your cross-compiler. This is the zero effort, the problem is already solved solution.
2) You may wish to look into http://pdclib.e43.eu/, which aims to be a minimal standard C implementation. It doesn't implement POSIX, just standard C and a few extensions in spirit with the C standard.
3) You may wish to look into an existing libc you can port. Popular choices include newlib or pdclib (mentioned above), I have heard people have ported glibc (though that is supposedly considerably harder). There are also musl, but I am not sure how portable that is to non-Linux.
4) You can write your own libc implementation! That's what I did (although I didn't fully intend on that to happen, it kinda just did). It will likely take a long time to finish, years in my case to get to it to a somewhat complete point, but it is worth it as you control the quality and can make sure it integrates perfectly into your project (unlike the other `ports' that are kinda alien unless you use considerable effort). Fortunately, the core parts of a libc isn't too terribly hard to write and you can get far in little time, though stuff like stdio is surprisingly tricky.
As for a C++ standard library implementation, you can port libstdc++ that comes with GCC without too much effort when you have a proper libc for your user-space. I'm not too sure on kernel usage, however, I am yet to really research that. I know clang also has libc++. I'm not sure to which degree you can mix and match components. I'd almost argue against using the C++ standard library in a kernel because things seem to be nasty in the examples I have seen, but that just means I don't know the proper way.
Re: Minimalist libc/STL implementations?
Firstly, thanks for the quality answer and the time it took to produce.
Since I have all the C headers I wanted, I think what I will do is simply write the STL classes as I need them. They shouldn't be too hard or time consuming. And, to be frank, if they turn out to be challenging, then I'm obviously wasting my time with OS dev anyway. But I doubt that will be the case.
Oh, yeah, I had a vague memory of this and was surprised when my old C++ kernel failed to compile with my new cross compiler. It's been a while, needless to say. The problem is simply that I'm including cstd* instead of std*.h, since it is C++. Of course, I can (and will) just include the std*.h version, I just made a point of including the others because I was being a pedant.sortie wrote:It depends on what you want to do and how much effort you wish to invest:
1) Your cross-compiler comes with freestanding headers like stdarg.h, stddef.h, stdint.h, and a bunch more. You can literally just use them out of the box when you have installed your cross-compiler. This is the zero effort, the problem is already solved solution.
Other that 4, and that's too much startup overhead, these all have a problem that I forgot to mention. The main criterion (and again, I should have been more explicit, in terms of what I actually asked for, your answer is spot on), is that I do not want the OS-dependent headers/classes. I simply don't want iostream/fstream/stdio.h/etc to even be there. Having that in a library included (or that can be included) by a kernel just seems so dirty and wrong to me.sortie wrote:2) You may wish to look into http://pdclib.e43.eu/, which aims to be a minimal standard C implementation. It doesn't implement POSIX, just standard C and a few extensions in spirit with the C standard.
3) You may wish to look into an existing libc you can port. Popular choices include newlib or pdclib (mentioned above), I have heard people have ported glibc (though that is supposedly considerably harder). There are also musl, but I am not sure how portable that is to non-Linux.
4) You can write your own libc implementation! That's what I did (although I didn't fully intend on that to happen, it kinda just did). It will likely take a long time to finish, years in my case to get to it to a somewhat complete point, but it is worth it as you control the quality and can make sure it integrates perfectly into your project (unlike the other `ports' that are kinda alien unless you use considerable effort). Fortunately, the core parts of a libc isn't too terribly hard to write and you can get far in little time, though stuff like stdio is surprisingly tricky.
As for a C++ standard library implementation, you can port libstdc++ that comes with GCC without too much effort when you have a proper libc for your user-space. I'm not too sure on kernel usage, however, I am yet to really research that. I know clang also has libc++. I'm not sure to which degree you can mix and match components. I'd almost argue against using the C++ standard library in a kernel because things seem to be nasty in the examples I have seen, but that just means I don't know the proper way.
Since I have all the C headers I wanted, I think what I will do is simply write the STL classes as I need them. They shouldn't be too hard or time consuming. And, to be frank, if they turn out to be challenging, then I'm obviously wasting my time with OS dev anyway. But I doubt that will be the case.
Re: Minimalist libc/STL implementations?
Ah, good, I think I understand your motivation, then.
There is nothing wrong with using the C or C++ standard library in a kernel. It is however crucial to distinguish between `Freestanding functions' and `Hosted functions' (this is not an entirely accurate use of the terms, but bear with me) in standard libraries. For instance, the function strlen is completely standalone, while a function like printf relies on an stdout object, which in return relies on the concept of a standard output device. As such, you can split a standard library like libc into two sets of functions: The functions that are freestanding and can be used in a kernel without issue, and functions that directly or indirectly relies on system calls or other hosted services. In my operating system, I deliberately designed my libc implementation in this manner from day one, with a libc for user-space use and a reduced libk for kernel use. My kernel is able to use functions like snprintf and fprintf as the stdio backend uses function pointers (the FILE* backend interface can be implemented in multiple ways); while the stdout FILE* is absent from the libk as stdout uses the file descriptor backend that relies on the write(2) system call. Naturally, it would be a considerable effort to change an existing library in this manner so it can be used in freestanding settings.
There is nothing wrong with using the C or C++ standard library in a kernel. It is however crucial to distinguish between `Freestanding functions' and `Hosted functions' (this is not an entirely accurate use of the terms, but bear with me) in standard libraries. For instance, the function strlen is completely standalone, while a function like printf relies on an stdout object, which in return relies on the concept of a standard output device. As such, you can split a standard library like libc into two sets of functions: The functions that are freestanding and can be used in a kernel without issue, and functions that directly or indirectly relies on system calls or other hosted services. In my operating system, I deliberately designed my libc implementation in this manner from day one, with a libc for user-space use and a reduced libk for kernel use. My kernel is able to use functions like snprintf and fprintf as the stdio backend uses function pointers (the FILE* backend interface can be implemented in multiple ways); while the stdout FILE* is absent from the libk as stdout uses the file descriptor backend that relies on the write(2) system call. Naturally, it would be a considerable effort to change an existing library in this manner so it can be used in freestanding settings.
- Bender
- Member
- Posts: 449
- Joined: Wed Aug 21, 2013 3:53 am
- Libera.chat IRC: bender|
- Location: Asia, Singapore
Re: Minimalist libc/STL implementations?
If you ever try to write your own C library (as sortie said), I'd also add that "The C Programming Language, 2nd Edition (idk if it's there in the first one) by K&R" Chapter 7 and 8 has been an assistant for me (lol), IIRC Chapter 7 deals with standard I/O while Chapter 8 deals with File Access, which should be a good start.
"In a time of universal deceit - telling the truth is a revolutionary act." -- George Orwell
(R3X Runtime VM)(CHIP8 Interpreter OS)
(R3X Runtime VM)(CHIP8 Interpreter OS)
Re: Minimalist libc/STL implementations?
Uh... "shouldn't be much trouble" to implement the STL containers as you need them?
Well, it depends. Are you going to implement your own STL-alike or are you actually going to implement a proper STL?
If you can't implement an entire STL, I wouldn't say you should say good-bye to kernel development. To build a true STL, you really need to know the whole deal about metaprogramming in C++. It's taken a lot of talented people a lot of time to create the various implementations of the STL.
You could, of course, check out STLport, RogueWave STL, Apache STL, uSTL or EASTL. Maybe there's something there you can utilize.
ALSO! Keep in mind that the STL isn't exactly built with being integrated into a kernel in mind. I.e. allocation failures, etc, are signaled via exceptions. EASTL may give you ways to handle or otherwise signal allocation failures without exceptions but I'm not sure.
~K
Well, it depends. Are you going to implement your own STL-alike or are you actually going to implement a proper STL?
If you can't implement an entire STL, I wouldn't say you should say good-bye to kernel development. To build a true STL, you really need to know the whole deal about metaprogramming in C++. It's taken a lot of talented people a lot of time to create the various implementations of the STL.
You could, of course, check out STLport, RogueWave STL, Apache STL, uSTL or EASTL. Maybe there's something there you can utilize.
ALSO! Keep in mind that the STL isn't exactly built with being integrated into a kernel in mind. I.e. allocation failures, etc, are signaled via exceptions. EASTL may give you ways to handle or otherwise signal allocation failures without exceptions but I'm not sure.
~K