Steps involved in compiling linux driver - linux

For an application to be compiled on Linux the steps involved are:
Pre-processing->Compilation->Assembly->Linking.
What are the steps involved in compiling a kernel driver? Are the steps different if I compile the driver as a built-in module vs a module vs using custom Makefile?

Right same steps are followed for device driver in Linux :-
Pre-processing->Compilation->Assembly->Linking.
These are basic steps need to followed every where , no matter how one follow.
Regarding built-in module vs a module vs using custom Makefile :: -
Device drivers can be compiled with whole kernel and device driver is part of kernel image means device driver is statically linked with the kernel. When device driver is statically linked with kernel and its loaded at boot up.
When device driver is compiled as module , then this module is not part of kernel image and can be loaded in system on the fly.
When device driver is part of kernel image , this device driver source files compiled as normal file of kernel source tree.
For example sample.c has device driver code and CONFIG_SAMPLE config macros controlling its compilation then include following line in Makefile
Config-($CONFIG_SAMPLE) = sample.o
When value of config macro is y , the driver gets compiled with kernel image and when its value is n then , then device driver don’t get compiled.
Device drivers as a module can be compiled using following commands.
make -C path/of/kernel path/of/driver/in/kernel/folder/module.ko

Related

Failed to load TPM device

I have a board from a no name manufacturer with a tpm 2.0 device LetsTrust but I am getting an error while trying to load the TPM.
The board has Ubuntu arm64 installed, the kernel version is 4.9.170.
I have added the following modules to be loaded on boot:
tpm_tis_spi
tpm_tis_core
tpm
but I still can't see the tpm on /dev, when I check the boot logs with dmesg I only see **fly error: tpm_tis_remove ** I am not sure what it means exactly but it seems the kernel couldn't recognize the TPM for some reason.
There is a way where I could get more information to understand why this is happening? we have no manual from the manufacturer so I can't ask them for help.
I have tried to compile a new kernel with TPM support to already load those drivers as modules but the OS disk is somehow embedded in the board and I couldn't find any bootloader to be able to tell it to boot from the new kernel.

ARM LINUX ":start_kernel is not calling after decompressing uImage"

The start_kernel() function is not calling after decompressing the kernel image (uImage) on an ARM board:
Why is the start_kernel() function is not calling? I know it should call from file arch/arm/kernel/head.s.
What are sequences happening after decompressing uImage and calling start_kernel()?
The most common cause of boot stopping after "Uncompressing Linux… Ok, booting the kernel" is that the console device in your kernel command line is not correct. For example, after upgrading from 2.6.35 to 3.19.5, the console device name could have changed from /dev/ttyAM0 to /dev/ttyAMA0 (on the i.MX23/28). You should also check that the serial port settings, if there are any, following the console device name in the kernel command line are correct.
Check that you are passing a valid ATAG array or device tree (*.dtb) file via your boot loader.
Another possible cause is incorrect entry point.
Try search engine phrase "ARM boot hangs after 'Uncompressing Linux....done, booting the kernel'"
The boot of Linux on embedded is done in 3 steps:
Bootloader
Low-level hardware initialization
Loads the Linux kernel in RAM and passes control to Linux
Bootstrap loader (inside the Linux kernel image):
Decompress and relocate the kernel
Pass control to it
Linux kernel:
Boot the system by running start_kernel() which, in the end, spawns the init process
Your output is between step 2 and step 3 (i.e., kernel decompressed).
You've probably not set all the things to have a working console:
Compile the target Linux kernel enabling through make menuconfig the serial console in
Device Drivers -> Character Devices -> Serial Drivers
Enable the specific driver for serial communications in the kernel configuration (i.e., through make menuconfig)
Set Linux console on the right device by setting option console=device,baudrate in the bootargs variable of U-Boot.

How to make a built-in device driver in linux

I know how to make loadable kernel modules in Linux.
But i want that loadable kernel module to be a part of the kernel , and after booting that driver should automatically load, like most of the other general driver.
How to do that?
There are two ways to do for your query
1) building your module as statically compiled along with kernel(your source code should reside in kernel tree ),so while building build it static which come as a part of kernel,
so when kernel boots your module will be loaded.
2)Same as above but while building build as dynamic loadable module so that wheneever required you can load it.
to illustrate above concept you can try below link for simple helloworld example.
http://www.agusbj.staff.ugm.ac.id/abjfile/Chap8.pdf
You have to configure modprobe to load automatically driver after kernel boot. Here an example of configuration.
If you want to a built-in module, you must re-compile the kernel, and set Y in the configuration file on all modules that you want inside the kernel

Cross compiling a driver writtten in c for linux that doesnt come with configure file

We are trying to cross compile a driver for TP-Link TG 3468 gigabit ethernet adapter. The vendor has a linux version of the driver but there is no configure file present. There is just the make files and the c files. Please suggest a way to cross compile the driver.
We are trying to compile it for an ARM processor based single board computer.
Most Linux kernel modules don't use autoconf, so have no configure files. Did you try to run make (perhaps with the appropriate CC= setting)?
See also this answer.

Using lirc for arm cortex A8

Neaded your help on lirc.
I want to use lirc for decoding of ir signals. I am using a custom board based on Cortex A8 with 2.6.37 kernel and IR is received thru’ serial port. I can see UART interrupts coming properly when I press the button of the IR remote.
But when I try to run the configure script with device=all or device=serial and run make and make install as mentioned in the installation page on lirc.org, It sends me an error that the kernel configuration is invalid.
But still I am able to generate the .ko files(lirc_dev and lirc_serial) needed for loading the kernel modules but not able to insert lirc_serial module as I am using a port having mmio and the port used by lirc is io mapped.
My virtual adddress is 0xfa022000 and physical address is 0x48022000(using ttyO1).
Can I use lirc for this address.
Do I need to make any change in the code?
Also I cannot install directly on the board I am using as I could not build the kernel source code on the board due to minimal things present on the board.So am running the setup on some other machine and cross compiling for arm.
So I could not have the configuration files placed at the right locations also the node(/dev/lirc0) is not made.
Shall I make the node manually or will inserting the modules do the work?
Also do I need to have the configuration files at proper location before inserting the modules?
Also does it have any dependency with the kernel version?
Please suggest me the steps for cross compiling and loading the kernel modules on my own and also let me know which all conf files or other files are required to be present for making the things work.
I would really be very thankful to you for the help.
I have been trying it for the past 2 weeks.
Regards
Harman.
/dev/lirc0 should be created automatically if lirc_serial is loaded successfully. If it's not created, module was not loaded correctly.
lirc_serial does work with mmio - see 'iommap' module's param. You'll need to set it to 1 for mmio to work.
You'll also need to use 'io' and 'irq' params to setup your address and irq.
I'm using UDOO board with Cortex A9 CPU and could get my mmio and irq information from /proc/tty/driver/IMX-uart.
My kernel is newer though - it's 3.0.35 and I'm not sure if all of that will work in your case.
I was eventually able to load lirc_serial, but it still didn't work, so I had to connect my IR receiver directly to GPIO and write my own kernel driver based on lirc_rpi to make it working: http://funny-embeddings.blogspot.com/2013/12/udoo-adding-ir-and-building-lirc-kernel.html

Resources