"Valid" kernel-space headers (split from Working on the OS F
"Valid" kernel-space headers (split from Working on the OS F
Here's a suggestion I have after reading the thread about NULL not being defined:
We could add the list of standard headers that are valid as part of a kernel (eg. stdint.h is good, stdio.h is not), along with some info on what parts of c you should avoid in a kernel (eg. floating point).
If that sounds like a good idea I'll take a bash at the first version, and if it's already there, sorry I can't find it.
Cheers,
Paul
We could add the list of standard headers that are valid as part of a kernel (eg. stdint.h is good, stdio.h is not), along with some info on what parts of c you should avoid in a kernel (eg. floating point).
If that sounds like a good idea I'll take a bash at the first version, and if it's already there, sorry I can't find it.
Cheers,
Paul
"Valid" kernel-space headers (split from Working on the OS F
There is no distinction between headers that are "valid" in a kernel and those that aren't. There is a collection of headers required to be present in a "freestanding environment", being: <float.h>, <iso646.h>, <limits.h>, <stdarg.h>, <stdbool.h>, <stddef.h> and <stdint.h>. They are special because they do not include any code, only typedefs and defines, so they don't hurt even the most paranoid embedded-systems programmer. Some compilers even come with them included, whereas the other parts of the lib (the so-called "hosted environment") is usually provided by your C lib of choice.
But that does not mean that these other headers are "invalid" in kernel space. Whatever you port or implement yourself is "valid". My PDCLib, when finished, will provide everything the standard defines, for both kernel and user space. Some is easier and with very little dependencies on the underlying platform (<string.h>), some depends on the OS (<stdio.h>), some depends on the hardware (<math.h>). But there's no "law" that forbids you to use floating point maths in your kernel, for example (except, perhaps, common sense ).
But that does not mean that these other headers are "invalid" in kernel space. Whatever you port or implement yourself is "valid". My PDCLib, when finished, will provide everything the standard defines, for both kernel and user space. Some is easier and with very little dependencies on the underlying platform (<string.h>), some depends on the OS (<stdio.h>), some depends on the hardware (<math.h>). But there's no "law" that forbids you to use floating point maths in your kernel, for example (except, perhaps, common sense ).
Every good solution is obvious once you've found it.
"Valid" kernel-space headers (split from Working on the OS F
If you implement stdio yourself, can you use the header <stdio.h> provided by the C library of the host/build system or do you have to write your own? Thats what I'm really thinking. You can use <stddef.h> with no special effort required, but using <stdio.h> in you're kernel won't work unless you implement the functions you use, and if you do things radically different from the host system, you'll need your own header.
As far as floating point is concerned, I'm thinking about the noobies reading the FAQ. To my knowledge, floating point stuff needs some basic support code to setup the FPU and save the data during task switches. That might catch some people out.
As far as floating point is concerned, I'm thinking about the noobies reading the FAQ. To my knowledge, floating point stuff needs some basic support code to setup the FPU and save the data during task switches. That might catch some people out.
"Valid" kernel-space headers (split from Working on the OS F
One thing defined by <stdio.h> is the [tt]FILE[/tt] object, which holds position information, error and EOF flag, buffer-pointer etc. in some black box. You could use the <stdio.h> provided by the C library of the host system, but only if you know that library's way to do things, and agree to do them the same way in your system.paulbarker wrote: If you implement stdio yourself, can you use the header <stdio.h> provided by the C library of the host/build system or do you have to write your own?
<stddef.h> defines, among others, the type [tt]size_t[/tt] and the macro [tt]offsetof[/tt]. If you mix a 32bit host/build system and, say, a 16bit embedded processor or a 64bit server for a target, you'll be in for a rude surprise.You can use <stddef.h> with no special effort required, but using <stdio.h> in you're kernel won't work unless you implement the functions you use, and if you do things radically different from the host system, you'll need your own header.
That being said, "special effort" is a bit shades of grey. The functions in <string.h> are rather primitive, and you could use those provided by your host library unchanged in 99% of cases without a second thought. But maybe you'd like to balance code size vs. code speed a bit different? Perhaps you'd like to utilize the string operations your target CPU provides in hardware?
You need to save registers on task switches anyway. As far as the Intel speciality of register precision is concerned, I'm pretty sure it's in the FAQ already somewhere, but I'll check...As far as floating point is concerned, I'm thinking about the noobies reading the FAQ. To my knowledge, floating point stuff needs some basic support code to setup the FPU and save the data during task switches. That might catch some people out.
Every good solution is obvious once you've found it.
"Valid" kernel-space headers (split from Working on the OS F
Cross-compiling using any headers from the host system is asking for trouble .<stddef.h> defines, among others, the type size_t and the macro offsetof. If you mix a 32bit host/build system and, say, a 16bit embedded processor or a 64bit server for a target, you'll be in for a rude surprise.
But I understand what you mean, there isn't really a clear cut case of when and what headers you can use, so maybe it shouldn't be in the FAQ.
"Valid" kernel-space headers (split from Working on the OS F
Why would that be common sense?Solar wrote:But there's no "law" that forbids you to use floating point maths in your kernel, for example (except, perhaps, common sense ).
Re:\
1) If you are not using FP in kernel space, you don't have to save the FPU registers on a userland / kernel switch (only on task switches) - saving lots of clock cycles.
2) FP is very slow compared to integer, and not necessary for anything the kernel has to do.
2) FP is very slow compared to integer, and not necessary for anything the kernel has to do.
Every good solution is obvious once you've found it.
Re:\
What about, for example, copying / moving a block of memory? I can probably do that a whole lot faster through MMX / SSE2. However, if I'm not mistaken, that uses the FP stuff and you will need to save state.
But isn't that why we have FXSAVE/FXRSTOR these days?
I was also thinking about graphics card drivers that could really use MMX/SSE technology well. But while that will probably be in ring 0 it of course is not "in the kernel".
But isn't that why we have FXSAVE/FXRSTOR these days?
I was also thinking about graphics card drivers that could really use MMX/SSE technology well. But while that will probably be in ring 0 it of course is not "in the kernel".
Re:\
That would be "anything the kernel generally does". We allow very different designs, which include doing lots of FP stuff in the kernel. It's just quite different from the generic kernel (which in common speak has started to mean something like the linux kernel).Solar wrote: 1) If you are not using FP in kernel space, you don't have to save the FPU registers on a userland / kernel switch (only on task switches) - saving lots of clock cycles.
2) FP is very slow compared to integer, and not necessary for anything the kernel has to do.
In my design, the actual displaying of stuff will be in kernel mode and in a way a part of the kernel. If that needs FP parameters (doubt it, but if it does) I won't hesitate to add it. Neither should you. Common logic (not common sense) is more of a force of habit than what's actually best. It does have its points, if you're different we can't follow what you're doing as easily as we otherwise could. For a small test, try to imagine how a blind person would use a computer and how he could surf the web. That kicks out all your common ideas on ways to solve stuff since you can't display a red box for a warning etc.
Generically speaking though, it's not useful to have FP or SSE (or anything near it) in your kernel, since you'll have to save/restore the registers and there's not much you'll gain by it. A simple syscall should not take more than a few dozen cycles in task switching or the kernel boundary will become something to design around.
Re:\
@ Candy:
You're correct. Right meaning, wrong wording. Of course your kernel might actually need FP stuff in it, but usually you can live quite nicely without.
You're correct. Right meaning, wrong wording. Of course your kernel might actually need FP stuff in it, but usually you can live quite nicely without.
And is having to save state every time worth the speed benefit MMX / SSE2 gives you sometimes? FXSAVE / FXRSTOR work - according to the Intel docs - on a 512 byte data block. If you don't have to move more than 1024 bytes on average per kernel entry, you're making a loss even if MMX / SSE would move your data in zero time...Rob wrote: What about, for example, copying / moving a block of memory? I can probably do that a whole lot faster through MMX / SSE2. However, if I'm not mistaken, that uses the FP stuff and you will need to save state.
Every good solution is obvious once you've found it.