Printk not printing in spite of properly set loglevel - linux

my problem is, I am trying to build a driver into the kernel. I decided to test my code with a simple Hello World program. The code looks like:
#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/printk.h>
int __init my_init(void)
{
printk(KERN_ALERT "Hello world\n");
return 0;
}
device_initcall(my_init);
//subsys_initcall(my_init);
Also, cat /proc/sys/kernel/printk shows
7 4 1 7
From the .config file, I find "CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4"
I am making the file using obj-y += in the Makefile. I find that 'make' can build the module, but no printk outputs are appearing in dmesg or under /var/log/ after boot.
I am wondering if the driver is not being built at all into the kernel. Is there any way of checking that?
Thanks,
D.

You can use
lsmod command
OR
cat /proc/modules
command to check if your driver is loaded.
Looking at your code I feel __init should be replaced with module_init or __initcall.
These kernel signatures ensure that the module init is called at insertion time.
You can test your driver by using insmod and check if it logs the message by calling dmesg.

I solved the problem. I found out that the printk statements were actually getting printed on the console, but got wiped out from dmesg due to the large number of other messages getting printed. I increased the size of dmesg, and now it stores the printk statements.

Related

how to get process descriptor given a pid in user space Linux

how to get process descriptor given a pid in user space Linux.
We are doing a porting project from OS900 to Linux, converting all system calls.
I tried using find_task_by_pid() in a test code
#include <stdio.h>
#include <stdlib.h>
//#include <include/linux/sched.h>
//#include <Linux/include/linux/pid.h>
//find_task_by_pid(getpid());
pid_task(find_vpid(getpid()), PIDTYPE_PID);
but it is not compiling
error: ‘PIDTYPE_PID’ undeclared (first use in this function)

Can't compile kernel module for BeagleBone Debian

I'm following Derek Molloys guide to building loadable kernel modules, but get stuct at some points.
I have the kernel code in a .c-file:
hello.c
#include <linux/init.h> // Macros used to mark up functions e.g., __init __exit
#include <linux/module.h> // Core header for loading LKMs into the kernel
#include <linux/kernel.h> // Contains types, macros, functions for the kernel
MODULE_LICENSE("GPL"); ///< The license type -- this affects runtime behavior
MODULE_AUTHOR("Derek Molloy"); ///< The author -- visible when you use modinfo
MODULE_DESCRIPTION("A simple Linux driver for the BBB."); ///< The description -- see modinfo
MODULE_VERSION("0.1"); ///< The version of the module
static char *name = "world"; ///< An example LKM argument -- default value is "world"
module_param(name, charp, S_IRUGO); ///< Param desc. charp = char ptr, S_IRUGO can be read/not changed
MODULE_PARM_DESC(name, "The name to display in /var/log/kern.log"); ///< parameter description
/** #brief The LKM initialization function
* The static keyword restricts the visibility of the function to within this C file. The __init
* macro means that for a built-in driver (not a LKM) the function is only used at initialization
* time and that it can be discarded and its memory freed up after that point.
* #return returns 0 if successful
*/
static int __init helloBBB_init(void){
printk(KERN_INFO "EBB: Hello %s from the BBB LKM!\n", name);
return 0;
}
/** #brief The LKM cleanup function
* Similar to the initialization function, it is static. The __exit macro notifies that if this
* code is used for a built-in driver (not a LKM) that this function is not required.
*/
static void __exit helloBBB_exit(void){
printk(KERN_INFO "EBB: Goodbye %s from the BBB LKM!\n", name);
}
/** #brief A module must use the module_init() module_exit() macros from linux/init.h, which
* identify the initialization function at insertion time and the cleanup function (as
* listed above)
*/
module_init(helloBBB_init);
module_exit(helloBBB_exit);
and the makefile as this:
Makefile
obj-m+=hello.o
all:
make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) clean
when I try to run make in a directory with onl the two above files, i get
Make: Nothing to be done for all
I'm running 3.8.13-bone47, but I wasn't able to find the exact header files matching on this link that Derek recommended, so I downloaded 3.8.13-bone71 instead. Could that be the problem? Do I have to download the headers, when I'm compiling in directly on the BeagleBone? I have also tried change the lines in the Makefile to a hardcoded distribution name that matches mine (3.8.13-bone47), doesn't work either.
Thank you very much guys!
I solved my question. I had two problems:
Missing Tabs in Makefile
I added a tab to the beginning of each line with a make statement. It has to be an actually tab, the <\t> didn't work for me.
Wrong Header files
It turns out that the proper version of the header files is quite important :) I got the ones from http://rcn-ee.net/deb/trusty-armhf/v3.8.13-bone47/ and added the mach/timex.h file, and was the able to follow Derek's guide from then on.

Linux. SOL_NETLINK not defined

I was trying to use SOL_NETLINK in setsockopt in Linux, and got an error saying that SOL_NETLINK is not defined although in included the socket.h file.
Googled for some answers and saw people redefine SOL_NETLINK in their own files due to "Linux header file confusion".
Any explanation for that?
This may be a workaround, but if you see the Linux kernel SOL_NETLINK is always defined as 270:
#define SOL_NETLINK 270
You can just replace the constant with the value and it should work without any issue.
I just compile-checked this code on a raspbian PI, and it compiles without any warnings.
#include <sys/socket.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
printf ("SOL_SOCKET=%d\n", SOL_SOCKET);
return 0;
}

Compiling module with external toolchain

I created the make file
obj-m += hello.o
all:
make -C /home/developer/Desktop/xukr-20120201-omap3/linux-2.6.37-tn M=/home/developer/Desktop/module_test modules
clean:
make -C /home/developer/Desktop/xukr-20120201-omap3/linux-2.6.37-tn M=/home/developer/Desktop/module_test clean
Then, i found a simple hello program
#define __KERNEL__ /* We're part of the kernel */
#define MODULE /* Not a permanent part, though. */
/* Standard headers for LKMs */
#include <linux/modversions.h>
#include <linux/module.h>
#include <linux/tty.h> /* console_print() interface */
/* Initialize the LKM */
int init_module()
{
console_print("Hello, world - this is the kernel speaking\n");
/* More normal is printk(), but there's less that can go wrong with
console_print(), so let's start simple.
*/
/* If we return a non zero value, it means that
* init_module failed and the LKM can't be loaded
*/
return 0;
}
/* Cleanup - undo whatever init_module did */
void cleanup_module()
{
console_print("Short is the life of an LKM\n");
}
And i tried to compile on command line with this
make ARCH=arm CROSS_COMPILE=angstrom-linux-gnueabi-
And i get this error
/bin/sh: angstrom-linux-gnueabi-gcc: not found
What is wrong with this? i am really new at this.
Thanks in advance,
You could use remake to debug and understand your Makefile. Invoke it as remake -x -d it will give you a lot of debugging output, while behaving otherwise as GNU make.
As I commented, don't forget to use $(MAKE) instead of make inside your Makefile.
Regarding the error: angstrom-linux-gnueabi-gcc: not found you need to install the appropriate cross-compiler (and cross-linker) toolchain on your system (or perhaps set appropriately your PATH environment variable, so that it would be found).
All this won't solve your problem, but will help you understanding it

Hook file saving in Linux

How can i hook file saving in Linux systems (to show my programm dialog, opearting with them then)?
Just use the inotify interface to get notification of file system changes. See: http://linux.die.net/man/7/inotify
You can try FILE_PRELOAD utility which generate C++ code with hooks, compile and LD_PRELOAD it. After short look at it you can feel how easy to hook linux. Start point is this tutorial.
For example, if you want to change 'open call' of file /tmp/some with /tmp/replace_with:
#: FILE_PRELOAD -C "A+f:/tmp/some:/tmp/replace_with" -- bash
#: echo "HaHa" >> /tmp/some
#: ll /tmp/some
ls: cannot access /tmp/some: No such file or directory
#: cat /tmp/replace_with
HaHa
If you want to see the source of generated code just add "-p" to options.
#: FILE_PRELOAD -p -C "A+f:/tmp/some:/tmp/replace_with" -- bash
In additional all generated.cpp files you can find in /tmp/$USER/FILE_PRELOAD/cpp.
Have a nice play with linux hooks)
Generated code looks like this:
#include <sys/types.h>
#include <dlfcn.h>
#include <stdio.h>
#include <map>
#include <string>
#define I int
#define C char
#define S string
#define P printf
#define R return
using std::map;
using std::string;
typedef map<S,S> MAP;
static I (*old_open)(const C *p, I flags, mode_t mode);
extern "C"
I open (const C *p, I flags, mode_t mode){
old_open = dlsym(RTLD_NEXT, "open");
P("open hook\n");
MAP files;
files[p]=p;
files["/tmp/some"]="/tmp/replace_with";
S newpath = files[S(p)];
R old_open(newpath.c_str(), flags, mode);
}
# &compile
gcc -w -fpermissive -fPIC -c -Wall file.cpp
gcc -shared file.o -ldl -lstdc++ -o wrap_loadfile.so
LD_PRELOAD=./wrap_loadfile.so bash
nm -D /lib/libc.so.6 | grep open # we hook this syscall
If you can compile them you can link first against a custom library that provides open().
There's a stock way of doing it.
If you can't compile it, this works most of the time:
Write function _open_posthook that does syscall(NR_OPEN, ...)
Provide shared library libopenhook that provides your new open. Rembember you renamed open to _open_posthook() here unless you want recursion. Don't forget to also provide creat().
Load this library with LD_PRELOAD.
EDIT: if you're trying for security this won't work. You might be able to get away with using strace() but unless you are very careful a determined programmer can overcome that too.

Resources