My teacher gives me a linux kernel vmlinuz-3.17.2 and a rootfs.ext2 which can be loaded to qemu. And he asks me to build a simplest kernel module which prints a hello world as homework.
Firstly, I download the kernel source and run make oldconfig
Secondly, I make the config to be PREEMPT and without modversions
(according to uname -a of vmlinuz running in qemu) , then make prepare
Thirdly, I compile the kernel mod and copy hello.ko in rootfs.ext2
Finally, In qemu, I run insmod hello.ko which exit without any prompt
and echo $? returns 0.
However, I can't see anything in dmesg or /var/log/messages
Is there anything wrong? How can I do with this?
There is also nothing to be printed when I run rmmod hello.ko successfully.
My log level is 7 4 1 7
I have make my hello.c as follows:
#include <linux/init.h>
#include <linux/module.h>
static int __init hello_init(void)
{
pr_info("Hello World");
return -1;
// I changed this to -1 deliberately, Because It seems that the code is not executed.
}
static void __exit hello_exit(void)
{
printk(KERN_ERR "Goodbye, cruel world\n");
}
MODULE_LICENSE("GPL");
module_init(hello_init);
module_exit(hello_exit);
Buildroot
Buildroot is the easiest way to do it:
minimal out-of-tree example: How to add a Linux kernel driver module as a Buildroot package?
minimal in-tree example: https://github.com/cirosantilli/buildroot/tree/kernel-module-2016.05
how to debug the module with GDB: How to debug Linux kernel modules with QEMU?
Tested on Ubuntu 16.04.
Related
I'm trying to learn how to build a minimal initramfs for Linux. I set CONFIG_INITRAMFS_SOURCE="asd", created asd directory, inside there's an init file compiled using gcc -fpic -static main.c -o init. In the kernel log I'm getting the following error:
Run /init as init process
Failed to execute /init (error -8)
Here's the input source code:
int main() {
printf("Hello, world!\n");
for(;;);
}
What am I doing wrong?
It works with a defconfig kernel and CONFIG_INITRAMFS_SOURCE set. In the directory I had to make the node dev/console.
mkdir dev
sudo mknod --mode=0600 dev/console c 5 1
After running -kernel linux*/arch/x86_64/boot/bzImage in qemu Hello, world! is shown after calling init.
What methods or tools can I use to help figure out the below issue?
I'd like to use CosmoNim on Solus Linux. It works on other linux distributions, but produces executables that segfault when built on Solus Linux. CosmoNim works for me on Ubuntu just fine.
CosmoNim is a Nim wrapper to use Cosmopolitan
Cosmopolitan is a library and method to produce universal binaries built with GCC
Nim is a transpiler to C (auto compiling with GCC)
So CosmoNim should work out of the box on many linux distros (and does indeed work on Ubuntu)
However, CosmoNim fails to make a functioning executable on Solus (the executable segfaults when run) before doing the objcopy to make the full universal executable.
But! Cosmopolitan (directly using GCC) HelloWorld does work on Solus
So Nim is either missing some compile or link flags for GCC or it's doing something it shouldn't for this process
How can I make progress on figuring this out?
Upon using GDB, it reports the main() function for the segfault:
$ gdb hello.elf ...
Program received signal SIGSEGV, Segmentation fault.
0x0000000000413005 in NimMain ()
121 N_CDECL(void, NimMain)(void) {
This is starting at that line 121 in the source file:
N_CDECL(void, NimMain)(void) {
void (*volatile inner)(void);
PreMain();
inner = NimMainInner;
initStackBottomWith((void *)&inner);
(*inner)();
}
int main(int argc, char** args, char** env) {
cmdLine = args;
cmdCount = argc;
gEnv = env;
NimMain();
return nim_program_result;
}
$ (gdb) info functions
121: void NimMain(void);
117: void NimMainInner(void);
137: void NimMainModule(void);
108: void PreMain(void);
102: void PreMainInner(void);
129: int main(int, char **, char **);
Any GDB/compiler utils wizards out there know how to introspect this?
I'm working on a linux kernel driver and need access to the kmalloc and kfree functions. From my research these should be available in the slab.h header, but that file doesn't exist in my filesystem.
I tried updating my includes using this solution: https://askubuntu.com/questions/75709/how-do-i-install-kernel-header-files but it shows that I already have all relevant files.
My system is a VMWare Ubuntu 16.04 installation running kernel 4.15.0.
Any ideas?
Here is a very simple demo module that calls kmalloc and kfree:
demo.c:
#define pr_fmt(fmt) "demo: " fmt
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
MODULE_LICENSE("GPL");
static int __init demo_init(void) {
void *buf;
buf = kmalloc(1000, GFP_KERNEL);
pr_info("kmalloc returned %p\n", buf);
kfree(buf);
return 0;
}
static void __exit demo_exit(void) {
}
module_init(demo_init);
module_exit(demo_exit);
Makefile:
ifneq ($(KERNELRELEASE),)
# KBuild part of Makefile
obj-m += demo.o
else
# Normal part of Makefile
#
# Kernel build directory specified by KDIR variable
# Default to running kernel's build directory if KDIR not set externally
KDIR ?= "/lib/modules/`uname -r`/build"
all:
$(MAKE) -C "$(KDIR)" M=`pwd` modules
clean:
$(MAKE) -C "$(KDIR)" M=`pwd` clean
endif
You can just run make to build the module for the currently running kernel version:
$ make
Or you can set KDIR to build the module for an arbitrary kernel version (defined by ${KERNELVER} in the following example):
$ make KDIR="/lib/modules/${KERNELVER}/build"
(If KDIR is unspecified, the Makefile sets it to the build path for the currently running kernel: "/lib/modules/`uname -r`/build".)
If it builds successfully, then you definitely have the kernel headers installed!
To test the module, run:
$ sudo /sbin/insmod demo.ko
$ sudo /sbin/rmmod demo
$ sudo dmesg
There should be a message on the kernel log similar to this showing the return value from the kmalloc() call:
[TIMESTAMP] demo: kmalloc returned xxxxxxxxxxxxxxx
The module also calls kfree() to free the allocated block.
For my thesis I am creating a Manet using the protocol ARAN. To install the protocol I'm using this manual, but the first step, the creation of trace_route, I received errors such as:
-linux/module.h: No such file or directory
-linux/procs_Fs: No such file or directory
-linux/skbuff: No such file or directory
I searched the web and found out that the problem is in the headers, but I do not find the solution ...
P.S. I am using Ubuntu 10.04 LTS Kernel 2.6.33 recompiled
You're missing the Linux kernel headers which allow you to compile code against the Linux kernel.
To install just the headers in Ubuntu:
$ sudo apt-get install linux-headers-$(uname -r)
To install the entire Linux kernel source in Ubuntu:
$ sudo apt-get install linux-source
Note that you should use the kernel headers that match the kernel you are running.
**/*source file name is basic.c */**
#include <linux/init.h>
#include <linux/module.h>
/*MODULE_LICENSE("Dual BSD/GPL");*/
static int hello_init(void)
{
printk(KERN_ALERT "Hello, world\n");
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT "Goodbye, cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);
=====================================
now make file for ubuntu
/*at first type on ur terminal that $(uname -r) then u will get the version..
that is using on ur system */
obj-m +=basic.o
KDIR =//usr/src/linux-headers-3.13.0-44-generic
all:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
rm -rf *.o *.ko *.mod.* *.symvers *.order
================================================
To run the code
$sudo insmode basic.ko
$dmesg
u will get the output
$sudo rmmod basic.ko
$dmesg
I cross-compiled a Helloworld executable for ARM. It worked well on my friend's development board, but failed with a " segmentation fault " on my board. The two boards are slightly different in both hardware and software.
My question is, how can I debug in my board? Is it relatively easy to debug such a simple program? Does it indicate that there's nothing wrong with the executable and the problem most probably lies in the filesystem of my board?
Below is the code:
#include <QApplication>
#include <QPushButton>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QPushButton hello("Hello world");
hello.resize(100, 30);
hello.show();
return app.exec();
}
And the executable is generated by the following commands:
qmake -project
qmake
make
most probably gdb is ported to be run on ARM target but in case lack of that or for easy debugging, you should use gdb remote debugging.
http://sourceware.org/gdb/onlinedocs/gdb/Remote-Debugging.html#Remote-Debugging
Gdbserver is the application should be run on target. the following is demonstration howto use it. (copied from wikipedia)
Target settings:
remote$ gdbserver :2345 hello_world
Process hello_world created; pid = 2509
Listening on port 2345
Host settings:
local$ gdb -q hello_world
Reading symbols from /home/user/hello_world...done.
(gdb) target remote 192.168.0.11:2345
Remote debugging using 192.168.0.11:2345
0x002f3850 in ?? () from /lib/ld-linux.so.2
(gdb) continue
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0x08048414 in main () at hello_world.c:10
10 printf("x[%d] = %g\n", i, x[i]);
(gdb)
So you mentioned after LD_LIBRARY_PATH your issue was resolved. And before setting the LD_LIBRARY_PATH if your application gives error can not find libQt then it means you do not have Qt, but your application is giving this Seg Fault that mean you have library but not the right one so we can say you have multiple installations of Qt on your filesystem.
The one to which you have pointed now is correctly compiled for your current hardware but the other one is not compiled for your hardware causing the Segfault and this installation is in your library search path.
One possible reason of this seg fault can be determined from below.
Following are some CFLAGS which if not set correctly for any particular hardware, the compiled application / library causes Seg faults at run time.
-march
-mtune
-mfpu
So if your binary / library is compiled with say -march=armv5a and you are running it on ARM9 then it will crash like this.
Also note that not all application uses these flags, usually these flags are optimization flags and are used by base system libraries (i.e Qt, Glib, bison, Gtk etc....).
Even if you write a simple C based hello world application and your glibc is not compiled for your hardware you will get the Seg fault.
Answer from Author:
What caused this "segmentation fault" is exactly the software difference of the board. Specifically, the environmenat variable LD_LIBRARY_PATH was predefined in the failed board. And I added my path by the command
export LD_LIBRARY_PATH=$LD_LIBRARAY_PATH:/my/qt/path
Thus the predefined paths caused the problem ( still don't know in what way ).
If I change the command to
export LD_LIBRARY_PATH=/my/qt/path
the executable works.
As a general rule you shouldn't create objects derived from QObject on the stack as the QMetaObject system manages the life-time of objects with a parent-child relationship, and will therefore risk free()ing memory on the stack.