I'm testing a driver that I've built into the kernel and would like to verify that my DRIVER_exit command functions as expected. The DRIVER_init command executes automatically during boot, I assume the exit command does the same on shutdown. When testing the driver as a module I utilized insmod and rmmod to execute _init and _exit functions. Is there any command to trigger the exit function prematurely similar to rmmod? Alternatively is there a system log I can look at to see how my last shutdown sequence went?
If your driver is compiled statically in the kernel, it is not possible to call the exit function of your module because it is will be excluded from the kernel at linking time. Have a look at the __exit and __exitused definitions in include/linux/init.h
Related
I'm currently trying to debug my kernel. My goal is to put a breakpoint in a new syscall that I am implementing. The kernel runs on a remote Imx6q board. I've setup the JTAG debugger and I can connect GDB to it and pause the execution.
My issue is whith debug symbols.
I've added those properties to my defconfig :
CONFIG_GDB_SCRIPTS=y
CONFIG_DEBUG_KERNEL=y
CONFIG_RANDOMIZE_BASE=n
CONFIG_FRAME_POINTER=y
CONFIG_KGDB=y
CONFIG_DEBUG_INFO=y
When I start a session :
(gdb) tar ext :3333
Remote debugging using :3333
warning: No executable has been specified and target does not support
determining executable automatically. Try using the "file" command.
0xa7780ef0 in ?? ()
(gdb) c
Continuing.
I can attach a symbol file by hand, but it is required to provide an address to attach it.
(gdb) add-symbol-file /home/tlavocat/development/android/out/target/product/wandboard_qca/kernel-imx/kernel/sys.o
The address where /home/tlavocat/development/android/out/target/product/wandboard_qca/kernel-imx/kernel/sys.o has been loaded is missing
The function I want to stop in is this one :
wandboard_qca:/ # cat /proc/kallsyms | grep sys_keeper_get_state
c003e0ac T sys_keeper_get_state
And it is implemented in kernel/sys.c.
My question is, how can I attach my symbols correctly to the right address ?
Thank's for your answers
I simply needed to load le kernel binary.
file .out/target/product/wandboard_qca/kernel-imx/vmlinux
And then connect to the remote target.
My desktop is Intel x86_64 processor with Ubuntu operating system.
I know there is perf tool to get a list of statistics of a program.
But what I am trying to do is read performance counter directly without using the perf tool.
First Question
First Questions is I downloaded this code from Github: Github Code Reference.
It compiled successfully with linux-headers-5.3.0-40-generic kernel without any errors. Once I use "insmod" the .ko file, the system hangs. The .ko file is not inserted when I checked the dmesg, so I have to cease it after I do "insmod" the .ko file. Does it happen because I attempted unauthorized access? If there are suggestions that I can try, I am glad to hear that.
The corresponding code is below.
static void set_pce(void *arg)
{
int to_val = (arg != 0);
u_int64_t cr4_val;
cr4_val = __read_cr4();
if (to_val) {
cr4_val |= X86_CR4_PCE;
} else {
cr4_val &= ~X86_CR4_PCE;
}
__write_cr4(cr4_val);
}
static int __init user_rdpmc_init(void){
int cpu;
num_cpus = num_online_cpus();
printk(KERN_INFO "Enabling RDPMC from ring 3 for %d CPUs\n", num_cpus);
for (cpu = 0; cpu < num_cpus; cpu++) {
smp_call_function_single(cpu, set_pce, (void *) 1, 1);
}
return 0;
}
Second Question
Second question is I am using linux-headers-5.3.0-40-generic kernel version in my Ubuntu desktop. I downloaded kernel code version 5.5.3 from kernel.org. I followed the perf code given in the 5.5.3 kernel code thoroughly and discovered that core.c file under linux-5.5.3/arch/x86/events/intel directory actually does setting and reading the performance counters. I used the core.c file contents to make it as a module to read the performance counter. When I compile it, it creates a bunch of errors because I use linux-headers-5.3.0-40-generic to build the module but my ubuntu kernel doesn't have all header files linked to the core.c file from kernel code from kernel.org.
How can I make my Ubuntu kernel use all the files linked to core.c from kernel.org and build the .ko file?
Or Is there any module source code that has x86 performance counter reading that I can use as a reference?
Thank you for your help in advance.
I know there is perf tool to get a list of statistics of a program. But what I am trying to do is read performance counter directly without using the perf tool.
If you do not want to use perf tool, you can try to use oprofile tool or intel vtune or https://github.com/RRZE-HPC/likwid or https://github.com/opcm/pcm. Or you can use perf_event_open syscall which is how perf tool works (you can study or modify perf tool sources from https://mirrors.edge.kernel.org/pub/linux/kernel/tools/perf/ - and perf tool version may not be equal to kernel version).
If you want to access msr registers as root, use modprobe msr (this is standard kernel module, already compiled for your kernel in ubuntu) and wrmsr and rdmsr tools (msr-tools deb/ubuntu package, by intel), like in slide 27 of Performance Monitoring Chris Dahnken Intel SSG EMEA HPCTC presentation.
I don't understand why do you want to work with performance counters without perf tool. If you want to get counter readings from inside of your program, for example before and after some loops, you can use perf_event_open syscall (with specific ioctls) directly. (Or try to use perf stat + same ioctls PERF_EVENT_IOC_* or try to learn perf + JIT integration)
Or you can use existing kernel module which will export msr register access to root user - the msr.ko. And msr tools - https://01.org/msr-tools. Or with this msr+pmc example https://technicalandstuff.wordpress.com/2015/05/15/using-intels-pcm-in-linux-and-inside-c/ + https://software.intel.com/en-us/articles/intel-performance-counter-monitor (https://github.com/opcm/pcm)
There are also some examples of perf counters usage in https://github.com/RRZE-HPC/likwid.
You can also use PAPI library to access counters from your code, it will handle most of perf_event_open stuff for you. http://icl.cs.utk.edu/projects/papi/wiki/PAPITopics:Getting_Started
First Questions is I downloaded this code https://github.com/softdevteam/user_rdpmc ... "insmod" the .ko file, the system hangs.
There are too low "Stars" rating and the code is too old (2016) to really doing any investigations on the hang. Direct access of PMC may interfere with NMI watchdog (do echo 0 > /proc/sys/kernel/nmi_watchdog as root) or other perf session. It is safer to use perf_event_open syscall.
Second question ... discovered that core.c file under linux-5.5.3/arch/x86/events/intel directory actually does setting and reading the performance counters
This file is part of perf_event_open syscall implementation (perf_events subsystem of the kernel, https://github.com/torvalds/linux/tree/master/kernel/events + https://github.com/torvalds/linux/tree/master/arch/x86/events).
To use this code you can use the perf tool or perf_event_open syscall.
You should not compile the perf_events subsystem of the kernel as separate module because it is already compiled into your kernel (intel/amd specific part can be partially ko) and the Subsystem itself does not support compilation as module:
https://github.com/torvalds/linux/tree/master/kernel/events
Makefile: obj-y := core.o ring_buffer.o callchain.o
How can I make my Ubuntu kernel use all the files linked to core.c from kernel.org and build the .ko file?
Your ubuntu kernel already have all perf_events subsystem files compiled, some are linked into the kernel image and other are .ko files already installed like intel-rapl-perf.ko
$ grep _PERF_ /boot/config-`uname -r`
$ ls -l /lib/modules/`uname -r`/kernel/arch/x86/events/intel
Linux kernel version: 4.18.0-17
I am porting some 4.15 kernel customizations to 4.18, but my 4.18 kernel does not boot. A stock 4.18 kernel (i.e. the starting point before merging the 4.15 modifications) boots and runs.
The error message is:
Failed to execute /init (error -7)
Starting init: /bin/sh exists but couldn't execute it (error -7)
"errno 7" is "E2BIG 7 Argument list too long"
What does that mean in the context of the kernel starting the init process?
If the kernel command line and root file systems is exactly the same as the one you are giving to the kernel version that does boot than the most likely cause is that get_user_pages_remote() is failing here: https://elixir.bootlin.com/linux/v4.18/source/fs/exec.c#L194
Which would imply one of your changes broke memory management.
To get here, just track from try_to_run_init_process() which runs init to all the functions called from it which can return E2BIG. This is the only call site that does not depend on init argument list or environment size - https://elixir.bootlin.com/linux/v4.18/source/init/main.c#L1001
Having said that, I would first make VERY sure that the kernel command line and root file system are the same.
Normally, if I use rmmod to remove a kernel module, the function specified by module_exit is run. Is there some way to rmmod without having this function invoked?
In case you're curious, the reason is that I have written and insmod'ed a module whose exit method is buggy and I'd prefer not to reboot the remote machine manually when it causes the kernel to hang.
I have looked at man rmmod, but it does not seem to have such an option.
It is not possible to avoid unloading your module when rmmod is executed because there is some cleanup activity required when your module unloads, which if not done, you 'll not be able to reload your module again by executing insmod, as it will again call module_init() where you would have functions to registered (alloc_chrdev_region() or register_chrdev()) your driver. Re-registering it without un-registering it will result in a failure to load your module.
I'm not sure if this does what you are asking, but the next time you recompile the kernel you can enable the MODULE_FORCE_UNLOAD option and try rmmod -f
https://lwn.net/Articles/15571/
I am trying to use GDB to debug a Linux kernel zImage before it is decompressed. The kernel is running on an ARM target and I have a JTAG debugger connected to it with a GDB server stub. The target has to load a boot loader. The boot loader reads the kernel image from flash and puts it in RAM at 0x20008000, then branches to that location.
I have started GDB and connected to the remote target, then I use GDB's add-symbol-file command like so:
add-symbol-file arch/arm/boot/compressed/vmlinux 0x20008000 -readnow
When I set a breakpoint for that address, it does trap at the correct place - right when it branches to the kernel. However, GDB shows the wrong line from the source of arch/arm/boot/compressed/head.S. It's 4 lines behind. How can I fix this?
I also have tried adding the -s section addr option to add-symbol-file with -s .start 0x20008000; this results in exactly the same problem.
There are assembler macros that print out stuff when compiling with low level debug. You have to make sure the macros are appropriate for your board.
linux-latest/arch/arm$ find . -name debug-macro.S | wc
56 56 2306
Find the file for your board and ensure the correct serial port registers are hit. You can instrument the code with out using JTAG. These macros are used in the decompress code. Of course configure with *CONFIG_DEBUG_LL*.
Most likely the ATAGs are not correct or one of the other requirements. Checkout Documentation/arm/Booting to make sure you have registers set properly. Note there is a new requirement with recent kernels to send a dt list.