- How to include math.h #include on kernel source file?
- Saved searches
- Use saved searches to filter your results more quickly
- License
- sysprog21/kcalc
- Name already in use
- Sign In Required
- Launching GitHub Desktop
- Launching GitHub Desktop
- Launching Xcode
- Launching Visual Studio Code
- Latest commit
- Git stats
- Files
- README.md
- About
How to include math.h #include on kernel source file?
You cannot use the C library in a kernel module, this is even more true for the math library part.
You can’t include a userspace C module in kernel space. Also are you sure that you want to be doing this? This thread may help http://kerneltrap.org/node/16570. You can do math functions inside the kernel, just search around on http://lxr.linux.no/ for the function you need.
Standard libraries are not available in the kernel. This includes libc, libm, etc. Although some of the functions in those libraries are implemented in kernel space, some are not. Without knowing what you’re trying to call, it’s impossible to say for sure whether or not you should be doing what you’re trying to do in kernel space.
I should further note that the kernel does NOT have access to the FPU. This is to save time when switching tasks (since saving the FPU registers would add unnecessary overhead when performing context switches). You can get access to the FPU from kernel space if you really want it, but you need to be really careful not to trash the user space’s FPU registers when doing so.
Edit: This summarizes the caveat about the FPU much better than I did.
Floating point operations is not supported in the kernel. This is because when switching from kernel context to user context, registers must be saved. If the kernel would make use of floating point, then also the floating point registers would have to be saved also, which would cause bad performance for each context switch. So because floating point is very rarely needed, especially in the kernel it is not supported.
- maybe you could compile your own kernel with floating point support
- you could block context switch within your floating point operations
- the best would be to use fixed point arithmetics.
AFAIK kernel space is separated from user space, and so should the source code. /usr/include is for general programming.
This suggests that doing floating point math in the kernel is not as simple is in user-space code. Another instance suggesting that this is hard.
Still looking for a more definitive answer.
well you cannot, you can rewrite functions you need in your module, it’s dirty but it should work.
Thanks a lot for your comments
Is it possiable to make a plane C application and pass variables from kernel source file. So the C Application will compute the variables and sends back the information .
Kernel source file (kernel space) —> C Application (user space)
Kernel source file
So we may include header file in kernel source code. In case of any event, it pass the values to a C application (user space)
Details: I am trying to modify my HID joystick events(absolute x, y) So It may only move to the improved location, which will be genarated by my application, with some math functions like (pow, tan,etc).
So I used hid-input.c to get raw events, and modify them. which will be used for input subsystem through hid kernel module –
Looking for your comments
My initial reaction: don’t do that. Can you? Probably. But the divide between kernel space and user space is there for a damn good reason. There’s no guarantee that by the time the kernel finishes doing what it needs to do that your application will be running, or even be alive. I think we need more detail about what you’re trying to do. Also, unrelated: StackOverflow isn’t a forum. if you need to add information to your question, please edit your original question.
Can’t you just make your changes in your user-space application? I.e. if you get an event which moves to a bad location, you detect it in user-space?
You cannot (often, without lots of kernel know-how to lock and preserve these registers while not impacting other critical sections) use floating point registers in the kernel, and besides it is of course inappropriate to do «processing» in the kernel. Many others have mentioned this. Performance will be terrible. Thus, math.h is not provided for kernel modules. We accept this and move on.
However, as I am also a victim of crazy requirements and completely insane designs forced on us by others, this is a legitimate question. After reducing the usage of the math.h API to minimize the performance impact, you can use floating point emulation (soft-float) via correct compiler settings to implement your required functions without using floating point registers. Kernel code should already compile with these soft-float settings.
In order to implement math.h functionality, you can look at glibc or uClibc and perhaps others. Both of these libraries have generic «C» implementations of libm which implement math.h without the use of special intrinsics or platform specific types and should therefore compile just fine in the kernel.
uClibc: The above link takes you directly to the libm section of uClibc.
glibc: After «git»-ing glibc, you’ll find what you’re looking for in glibc/sysdeps/ieee754/flt-32.
glibc may be more difficult to understand because it is more sophisticated and has more inter-dependencies within itself, but uClibc only provides (at the moment) C89 math.h. If you want single precision (read: faster) or complex math functionality as in C99+, you’ll have to look at glibc.
Saved searches
Use saved searches to filter your results more quickly
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.
Math expression evaluation as Linux kernel module
License
sysprog21/kcalc
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Sign In Required
Please sign in to use Codespaces.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching Xcode
If nothing happens, download Xcode and try again.
Launching Visual Studio Code
Your codespace will open once ready.
There was a problem preparing your codespace, please try again.
Latest commit
Git stats
Files
Failed to load latest commit information.
README.md
kcalc: in-kernel math expression evaluation for Linux
kcalc is a mathematical expression evaluator and takes string as input, returning fixed-point numbers.
- Arithmetic, bitwise and logical operators;
- Flexible variables;
- Customized functions;
kcalc introduces a fixed-point number representation for fractional values: one 32-bit size is divided into mantissa (28 bits), sign (1 bit) and exponent (3 bits).
MSB 31 4 3 2 1 0 LSB +----------------------------------+------+----------+ | mantissa | sign | exponent | +----------------------------------+------+----------+
Build and install the module
$ make $ sudo insmod calc.ko $ sudo chmod 0666 /dev/calc
Then simply send the expression to the module
The expected output in dmesg should be:
calc: Received 3 -> 3*5 Result: 240
The result seems incorrect because we did not transform the value to normal representation. You can use the utlity to convert values into human readable form:
$ source scripts/eval.sh $ fromfixed 240
Then, you can get 15 , which is the exact result for expression 3*5 .
You can check file scripts/test.sh for more examples about the expressions. Alteratively, execue make check for the same script.
$ scripts/test.sh . Information generated by modinfo . Testing 6*7 . 42 Testing 1980+1 . 1981 Testing 2019-1 . 2018 Testing 42/6 . 7 Testing 1/3 . .33333330000000000000 Testing 1/3*6+2/4 . 2.49999980000000000000 Testing (1/3)+(2/3) . .99999990000000000000 Testing (2145%31)+23 . 29
struct expr *expr_create(const char *s, size_t len, struct expr_var_list *vars, struct expr_func *funcs) — returns compiled expression from the given string. If expression uses variables — they are bound to vars , so you can modify values before evaluation or check the results after the evaluation.
int expr_eval(struct expr *e) — evaluates compiled expression.
void expr_destroy(struct expr *e, struct expr_var_list *vars) — cleans up memory. Parameters can be NULL (e.g. if you want to clean up expression, but reuse variables for another expression).
struct expr_var *expr_var(struct expr_var *vars, const char *s, size_t len) — returns/creates variable of the given name in the given list. This can be used to get variable references to get/set them manually.
- Arithmetics: + , — , * , / , % (remainder), ** (power)
- Bitwise: > , & , | , ^ (xor or unary bitwise negation)
- Logical: < , >, == , != , = , && , || , ! (unary not)
- Other: = (assignment, e.g. x=y=5 ), , (separates expressions or function parameters)
kcalc is released under the MIT License. Use of this source code is governed by a MIT License that can be found in the LICENSE file.
About
Math expression evaluation as Linux kernel module