Posts

Showing posts from May, 2019

Linux driver example for Per CPU Variable

Image
Per CPU Variables is an interesting feature available from Linux Kernel Version 2.6 When you define a Per CPU Variable, each processor in the system will have its own copy of the variable, hence no locking is required and better performance is achieved. Header File: <linux/percpu.h> To create a Per CPU Variable at compile time, use the macro: DEFINE_PER_CPU(type, name); E.g. DEFINE_PER_CPU(int, counter); As linux kernel is preemptible, you must use get_cpu_var macro to access the current processor's copy of a given variable And finally call put_cpu_var macro after you have completed using it. You can access another processor's copy of the variable with: per_cpu(variable, int cpu_id); Example: Output:

Installing Raspbian Lite on Raspberry pi3

Image
Raspbian Lite is the operating system you want to choose, when you want to use sensors or web based applications on RaspberryPi. Raspbian vs Raspbian Lite: Raspbian lite is a minimal version of Raspbian. Following software/packages are removed from raspbian lite: Wolfram Libre Office Xserver It’s ideal if you intend to run the Raspberry Pi as a headless server without a GUI. Download Raspbian Lite from the Raspberry Website: http://downloads.raspberrypi.org/raspbian_lite/images/ To install, you can use various softwares. I am using etcher. Connect the SD Card, and flash the image  After flashing on the SD Card, connect it to the Raspberry Pi 3, connect Display over HDMI and power the device. You will get a login screen. Login Details: User name: pi, Password: raspberrypi Complete Initial Setup without connecting monitor and keyboard 1. Mount the SD Card and change directory to 'boot' volume. 2. Create wpa-supplicant.conf file wit

Linux driver example to print the current running CPU - smp_processor_id()

Image
When you have multiple processors present in the system, and want to find out on which the processor your driver code is running, use smp_processor_id(). Header file: #include <linux/smp.h> Example: Output: You can see from the above screenshot, the init function of the driver was running on Processor 1 and Kernel thread was running on Processor 4

Single Linux Device Driver code for multiple Linux versions using LINUX_VERSION

Image
The arguments of the kernel functions changes with new releases. For example, Kernel versions > 3.10 use the below function to create a proc entry proc_file_entry = proc_create("proc_file_name", 0, NULL, &proc_file_fops); For kernel versions < 3.10, this API was proc_file_entry = create_proc_entry("proc_file_name", 0, NULL); If you want to have a Linux Device Driver which supports multiple Linux Versions, use the macro LINUX_VERSION_CODE This macro expands to the binary representation of the kernel version For example for Linux version 2.6.10, the value is 132618(0x02060a) There is another macro KERNEL_VERSION(major, minor, release). This builds up the version number from the individual numbers. For example KERNEL_VERSION(2,6,10) will return 132618 Sample Code: Output:

Linux module to convert virtual to physical and vice versa

Image
virt_to_phys: Function converts kernel virtual address to physical address. phys_to_virt: Function converts physical address to kernel virtual address. Code: Output:

Linux Device Driver code to load another module

Image
Linux Kernel code can load module whenever needed. int request_module(const char *module_name); Header File: <linux/kmod.h> Source Code: kernel/kmod.c request_module is synchronous, it will sleep until the attemp to load the module has been completed. When the kernel code calls request_mode(), a new kernel thread is created, which runs modprobe program in the user context. Code: Output:

Linux Module to print number of CPU's

Image
We can look at /proc/cpuinfo to find out the number of processors present in Linux from user space. What if we want to find out the number of cpus in kernel module. num_online_cpus() function can give the number of CPU's which are online. Code: Output: References: https://stackoverflow.com/questions/43171805/find-number-of-cpus-in-linux-kernel

Linux Device Driver example for dump_stack() to print the stack trace of module loading

Image
One of the useful options in debugging is to print the call trace/stack trace. Linux kernel provides a function to print the stack trace: dump_stack(). Calling dump_stack() function will print the stack trace at that point. Code: Output:

Enable/Disable pr_debug in Linux Device Driver

Image
By default, the pr_debug messages are disabled. Consider the below sample code: Output: You can see, pr_debug log was not displayed on the dmesg output. To enable debugging output, build the  appropriate file with -DDEBUG by adding CFLAGS_[filename].o := -DDEBUG to the Makefile

vermagic in Linux Device Driver

Image
Vermagic is a magic string present in the Linux Kernel and added into the .modinfo section of the Linux Kernel Modules. This is used to verify whether the kernel module was compiled for the particular kernel version or not. ‘VERMAGIC_STRING’ is generated by the kernel configuration. #define VERMAGIC_STRING                         \     UTS_RELEASE " "                         \     MODULE_VERMAGIC_SMP MODULE_VERMAGIC_PREEMPT             \     MODULE_VERMAGIC_MODULE_UNLOAD MODULE_VERMAGIC_MODVERSIONS   \     MODULE_ARCH_VERMAGIC                        \     MODULE_RANDSTRUCT_PLUGIN Code: Output: If we change the value of 'vermagic' string using 'MODULE_INFO', we will get the error while loading the module.

MODULE_INFO in Linux Device Driver

Image
'modinfo' section in the .ko (ELF) file stores the Module information. MODULE_INFO is the macro which can be used in the source code to add information to this section #define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info) #define __MODULE_INFO(tag, name, info)                    \ static const char __UNIQUE_ID(name)[]                     \   __used __attribute__((section(".modinfo"), unused, aligned(1)))     \   = __stringify(tag) "=" info MODULE_INFO is used in several places by other macros such as  license,  alias, author, vermagic. Some of the fields can be retrieved through the THIS_MODULE (struct module) Code: Output: modinfo utility lists each attribute of the module in form fieldname:value, for easy reading  from the Linux Kernel modules given on the command line In the above screenshot, we used readelf, to dump the contents of the modinfo section.