When loading a platform driver for an I2C device does the device need to be present? - linux-device-driver

I am experimenting with building an I2C platform device driver for raspberrypi. The device is being registered as a misc device. My understanding is that when i load the driver via insmod, the probe function should be called, and at the very least should print the message I have in there. Instead I get a message about the kernel being tainted. As far as I know, even if my module taints the kernel, it should still run. MY question then is, does the device need to be physically connected to the raspberrypi in order to even call the probe function of my driver? Or is there some other issue?

The device doesn't have to be pysically plugged in to call the probe function. Most of the implemented probe functions even check if the device is plugged in or not. The warning with the tainted kernel can also be ignored, your driver still should be able to run.
I think you missed to add your driver to the device tree.
You can find a good explanaition here LWN.net
Without more informations it is hard for us to guess some other possible problems.

Related

How to receive CAN data in a linux device driver?

I want to read the CAN bus and get the data from a specific device on the CAN bus. I have implemented this previously using the Socket communication api that is available in the user space (sys/socket).
I now have a similar requirement but this time working on device drivers which work in the kernel space. The same socket communication is i suppose not available in the kernel space which is why i guess i am not able to compile the kernel module with #include .
An approach i have come up to is to create a device driver for device creation and a supporting user-space program to interact it and provide CAN data by using socket communication. If there is any better approach please suggest me.

How to test the actual presence of platform i2c device in driver's probe() function

I am writing an I2C bus driver. I have tested it on one external module I have plugged in my system (video card module) and it works. I have specified the i2c device (frequency, registers etc.) in device tree.
I would like to specify the rest of devices which will be using the driver in device tree as well. However, if I do that and the device is currently not present in the system, kernel fails to initialize. I guess this happens because in my probe function, I am setting up the frequency (which gets set up by writing to I2C register of that device - FPGA) and since the device isn't there - it just fails.
How should I solve this issue. Is there a way to check the actual physical presence in probe function without kernel failing? Or should I move the code that sets up frequency in another function that happens after ".master_xfer" when I'm reading/writing. The second option just seems like waste of resources. Another thing I had in mind was after I use open() to access the device in user-space, I should set the frequency in user-space as well. But I would really like all of this to happen inside the driver if possible. I'd like the frequency to be set after open() happens in userspace but for the code to execute in device driver code because there I access the register range specified in device tree. Maybe I could find where open() happens, check the ID of I2C device, than get the registers and do it there?

Do platform device drivers have to be registered with a major and minor number.?

I am new to device driver writing and I need to write a SPI driver to access flash memory for a embedded linux running on ARM.
What I don't understand is, do I need to register the driver with a major and minor number? Or do platform device drivers also need a major and minor number?
If yes, When and How to assign it?
I guess, I'll be using platform_driver_register() for registering the driver.
You don't have to register major or minor numbers. Your question is actually not precise enough. Do you want to write a driver for a specific SPI flash or a driver for an SPI host?
If this is an SPI flash, what you want is to register your driver using a struct spi_driver with module_spi_driver() then in the probe, register your device in the MTD susbsystem using mtd_device_parse_register. The MTD susbsystem will register the major and minors for you.
If you need to write a driver for the host, then you will register your driver using a struct platform_driver and module_platform_driver(). In your probee you will register your hosts using spi_register_master
You should probably read a bit about the Linux device model for further explanations.

At boot time how OS determines all the hardware?

I have these related questions:
Does anybody know how an OS gets to know all hardware connected on the motherboard? (I guess this is called "Hardware Enumeration").
How does it determine what kind of hardware is residing at an specific IO address (i.e.: serial or parallel or whatever controller)?
How to code a system module which will do this job? (Assuming no OS loaded yet, just BIOS).
I know BIOS is just a validation and an user friendly interface to configure hardware at boot time with no real use after that for most modern OS's (win, Linux, etc). Besides I know that for the BIOS it should not be difficult to find all hardware because it is specifically tuned by the board manufacturer (who knows everything about it!). But for an OS or an application above BIOS that is a complete different story. Right?
Pre-PCI this was much more difficult, you needed a trick for each product, and even with that it was difficult to figure everything out. With usb and pci you can scan the busses to find a vendor and product id, from that you go into a product specific discovery (like the old days this can be difficult). Sometimes the details for that board are protected by NDA or worse you just dont get to know unless you work there on the right team.
The general approach is either based on detection (usb, pcie, etc vendor/product ids) you load a driver or write a driver for that family of product based on the documentation for that family of product. Since you mentioned BIOS, win, linux that implies X86 or a PC, and that pretty much covers the autodetectable. Beyond that you rely on the user who knows what hardware was installed in the system and a driver that came with it. or in some way you ask them what is installed (the specific printer at the end of a cable or out on the network if not auto detectable is an easy to understand example).
In short you take decades of experience in trying to succeed at this and apply it, and still fail from time to time since you are not in 100% control of all the hardware in the system, there are hundreds of vendors out there each doing their own thing.
BIOS enumerates the pci(e) for an x86 pc, for other platforms the OS might do it. The enumeration includes allocating address space for the device based on pci compliant rules. but within that address space you have to know how to program that specific board from vendor documentation if available.
Sorry my English is not very good.
Responding questions 1 and 2:
During the boot process, only the hardware modules strictly necessary to find and start the OS are loaded.
These hardware modules are: motherboard, hard drive, RAM, graphics card, keyboard, mouse, screen (that is detected by the graphics card), network card, CD / DVD, and a few extra peripherals such as USB units.
Each hardware module you connect to a computer has a controller that is like a small BIOS with all the information of the stored device: manufacturer, device type, protocols, etc
The detection process is very simple: the BIOS has hardcoded all the information about the motherboard, with all communication ports. At startup, the BIOS sends a signal to all system ports asking the questions "Who are you? What are you? How do you function?" and all attached devices answers by sending their information. In this way the computer knows how much RAM you have, if there is present a keyboard or a mouse, which storage devices are available, screen resolution, etc ...
Obviously, this process only works with the basic modules needed to boot the system, and does not work with complex peripherals that require specific drivers: printers, scanners, webcams ... all these complex peripherals are loaded by software once the OS has been charged.
Responding question 3:
If you wants to load a specific module during the boot, you must:
- Create a controller for this module.
- If the peripheral is too complex to load everything from the controller, you must to write all the proccess to control that module directly in the BIOS module, or reprogram the IPL to manage that specific module.
I hope I've helped
Actually, when you turn on your system, the BIOS starts the IPL (Initial program load) from ROM. For check the all connected devices are working good and also check the mandatory devices such as keyboard, CMOS, Hard disk and so on. If it is not success, it gives an error flag to the BIOS. The BIOS shows us the error through video devices.
If it is success, the control of boot is transferred to BIOS for further process.
The above all process are called POST (Power On Self Test).
Now the BIOS have the control. It checks all secondary memory devices for boot loader of the OS. If it hit, the bootloader's memory address is transferred to RAM.
The Ram started to execute the bootloader. Here only the os starts to run.
If the bootloader not hit, the bios shows us the boot failure error.
I hope your doubt clarified...

How does the OS interact with peripherals like sound cards/ video cards etc

As far as I understand it, any program gets compiled to a series of assembly instructions for the architecture it is running on. What I fail to understand is how the operating system interacts with peripherals such as a video card. Isn't the driver itself a series of assembly instructions for the CPU?
The only thing I can think think of is that it uses regions of memory that is then monitored by the peripheral or it uses the BUS to communicate operations and receive results. Is there a simple explanation to this process.
Sorry if this question is too general, it's something that's been bothering me.
You're basically right in your guess. Depending on the CPU architecture, peripherals might respond to "memory-mapped I/O" (where they watch for reads and writes to specific memory addresses), or to other specific I/O instructions (such as the x86 IN and OUT instructions).
Device drivers are OS-specific software, and provide an interface between the OS and the hardware.
A specific physical device either has hardware that knows how to respond to whatever signals from the CPU it monitors, or it has its own CPU and software that is often called firmware. The firmware of a device is not specific to any operating system and is usually stored in persistent memory on the device even after it is powered off. However, some peripherals might have firmware that is loaded by the device driver when the OS boots.
There are simple explanations and there are truthfull explanations - choose one!
I'll try a simple one: Along the assembly instructions, there are some, that are specialized to talk to peripherials. The hardware interprets them not by e.g. adding values in registers oder writing something to RAM, but by moving some data from a register or a region in RAM to a peripherial (or the other way round).
Inside the OS, the e.g. the sound driver is responsible for assembling some sound data along with some command data in RAM, and the OS then invokes the bus driver to issue these special instructions to move the command and data to the soundcard. The soundcard hardware will (hopefully) understand the command and interpret the data as sound it should play.