"Valid" kernel-space headers (split from Working on the OS F

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
paulbarker

"Valid" kernel-space headers (split from Working on the OS F

Post by paulbarker »

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
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

"Valid" kernel-space headers (split from Working on the OS F

Post by Solar »

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 ;) ).
Every good solution is obvious once you've found it.
paulbarker

"Valid" kernel-space headers (split from Working on the OS F

Post by paulbarker »

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.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

"Valid" kernel-space headers (split from Working on the OS F

Post by Solar »

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?
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.
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.
<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. ;)

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?
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.
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...
Every good solution is obvious once you've found it.
paulbarker

"Valid" kernel-space headers (split from Working on the OS F

Post by paulbarker »

<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.
Cross-compiling using any headers from the host system is asking for trouble :o.

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.
Rob

"Valid" kernel-space headers (split from Working on the OS F

Post by Rob »

Solar wrote:But there's no "law" that forbids you to use floating point maths in your kernel, for example (except, perhaps, common sense ;) ).
Why would that be common sense?
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:\

Post by Solar »

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.
Every good solution is obvious once you've found it.
Rob

Re:\

Post by Rob »

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".
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:\

Post by Candy »

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.
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).

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.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:\

Post by Solar »

@ 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.
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.
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...
Every good solution is obvious once you've found it.
Post Reply