questions about embedded linux device driver by linux newbie - linux

I have been studying linux driver recently,
as those articles I read said, the device driver modules are likely to be automatically loaded on demand by kernel, I am therefore wondering about the recipe how kernel figures out which module to load for a specific device(sound card, I2C/spi device, etc), I also cannot thoroughly imagine how the kernel detects each hardware device while boot-time .
answers relevant to embedded linux are prefered , PC linux are also welcome !
3Q

I think you are mixing two different things, which is hardware detection, and on demand module loading.
In some cases, the kernel is explicitely doing a module request. However, in most cases, the kernel itself does not do any "on demand loading".
But wait, you must be mistaken, if I plug my shiny new webcam, isn't
the module automagically loaded ?
Yes it is, but not by the kernel. All the kernel does is calling a userspace program with so called "hotplug event" or "uevent" as arguments. On Linux PC, this userspace program is usually udev, but on embedded system, you can use for example mdev. You can find a more detailed explanation here and here
Regarding the second part of your question, the kernel is doing hardware discovery only if the hardware is discoverable. Example of discoverable hardware is USB and PCI. Example of non discoverable harwdare busses is SPI or I2C.
In the latter cases, the presence of a particular device on a given bus is either encoded directly in the kernel, or given to him by the booloader. Google for "device tree" for an example of the latter.
To sum things up : Hardware detection is done by the kernel, and module loading is done by userspace, with information provided by the kernel.

Related

What is SoC (system on chip)? Does Renesas V850 have a system on it?

I have experience writing a C program and burning the program into a chip using an IDE provided by the chip manufacturer.
I also heard that there is a concept called SoC, which means an operating system, like Linux, is running on a chip. In this case, I can run my program on the chip just like on a Linux PC.
I don't really know the differences between these two kinds of chips. Are they the same? Can I install Linux on every chip?
And I have to use a chip called Renesas V850 in my work. Which kind of chip is this V850?
SoC is just a marketing term for 'more than a processor on a chip'. It doesn't mean Linux or operating system.
Years ago, each part of a system was on its own chip: processor, serial port, memory, ADC, DAC, etc. You had a PCB and a schematic that tied them all together.
Over time, more and more got integrated into the processor, particularly for application-specific processors and microcontrollers. Today, pretty much only big iron processors like Intel and AMD flagship processors are stand-alone, and even then there's some x86 chip produced that are 'SoC's (like the AMD Geode line, if that's still around). Everything else has USB ports, serial ports, ADCs, DACs, even wireless radios integrated into the same die.
As for 'what is a Renasas v850?' You'd do better to google that and read the product documentation. It isn't an ARM or MIPs core, and it doesn't appear to support the mainline Linux kernel, only μClinux.
The Renesas V850 Wikipedia page states that the Linux kernel support for v850 has been absent since version 2.6.27 (which released in 2008).
Typically, you need to know what group your chip belongs to and to read more about it on Renesas website. They provide all the documentation you may need. There is also a section for application notes and sample code that may also help.

Possible to write to BIOS from linux kernel mode?

Is it possible to flash/write to a BIOS from kernel mode in Linux?
I've been doing some research on this and can't find a definitive answer to this. I'm not so great with kernel level stuff and hardware.
From what I've been able to find, I know certain kernel facilities can interrogate the BIOS (see dmidecode) given the BIOS supports certain interfaces.
I know the difference between real and protected mode. But switching to real mode from Linux seems impossible to do (?). I also know x86 has emulation for 8088 programs but unsure whether the emulation would allow flashing the BIOS.
Wouldn't it be possible to just write to certain addresses in kernel mode to "flash" the BIOS?
Update Working from the answer and comments below it seems the answer is yes depending on the hardware platform. The only, and necessary requirement is that the BIOS flash chip is addressable in the IO address space. You also need software support fir flashing chips, whether kernel or user space. For example I found the user space utility flashrom that can do it on what seems to be a narrow set of hardware platforms.
Yes, you can do that if BIOS flash chip is connected to the IO address bus and you have all necessary drivers.

How are device driver development and linux kernel programming related/different?

This might be a stupid question but I am confused and google couldn't help.
I know Linux is the Kernel which is the heart of many distros( Ubuntu, Mint). But when we say "Linux kernel programming", what do we exactly mean? Is it Bash scripting?
And how it is related to the device driver development? (Do we mean that the hardware is running linux kernel and we do kernel programming to support peripherals, this is ,in general, device driver development in relation to linux? )
Linux Kernel Programming is something which involves kernel components, meaning - kernel data structures and headers. A program in which one uses the existing kernel features or enhances the current features is a kernel program, typically a kernel module. In a way even the Bash scripting can be called as Linux Kernel programming. The device driver in a broad term is nothing but a set of interrupt handlers. Having said that, a device driver is a kernel program in itself as it uses the Linux kernel capabilities which is ported on a device/hardware. So in short the relation between the two is Device driver development is a form of Linux Kernel Programming.
Basically you have two kinds of programs running on your computer : the kernel, which has access to the computer hardware, and "userland" programs which ask the kernel to do low-level stuff (allocate memory, send data to the network, ...).
To do this, the kernel must know how to interact with some given piece of hardware. This is what we call "device drivers". In Linux, the device drivers are implemented as kernel module and device driver programming is akin to kernel programming because you deal with low-level operations straight to the metal instead of higher-level operations that go through the kernel.
Bash scripting is programming a shell (Bash) to run userland programs that themselves use the kernel to do the actual work. Bash-scripting is userland programming.
Device driver development is a subset of Linux kernel programming.
Device driver development is writing or modifying kernel modules that will handle a device. A device driver is a special case of kernel modules.
Kernel modules are codes that work from within the kernel and do privileged tasks.
Kernel modules are an integral part of Linux kernel programming. That is how device driver development and Linux kernel programming are related. The former is a part of the latter.
Also, device drivers will ultimately be inserted into the kernel, and will work in a kernel context. That is, device drivers ultimately become a part of the kernel.
Hence driver development is a subset within Linux kernel programming.

How to get USB device details in kernel programming?

I am new to kernel programming and I have dev_t value of a USB device.
I want to get the details of the device like vendor ID, product ID, or some other attribute which will vary from device to device. I want to do this in kernel space, and without loading my program as an external module.
I have came across a libusb library, however, as far as I know, it is used in user space. Is it possible to use libusb in kernel space also, like my requirement? If possible, how to import and set-up libusb so that I can compile kernel?
It is better to write a loadable kernel module for this task. Every time you find a bug you just have to compile your module against your kernel and load it. There is a defined framework in kernel for USB, use APIs that are provided by kernel to do things you are looking for.
Except That libusb is a user space library and there is no point of using it inside kernel.
In user space you can access USB related information using procfs/sysfs also.

How can the linux kernel be forced to enumerate the PCI-e bus?

Linux kernel 2.6
I've got an fpga that is loaded over GPIO connected to a development board running linux.
The fpga will transmit and receive data over the pci-express bus. However, this is enumerated
at boot and as such, no link is discovered (because the fpga is not loaded at boot).
How can I force re-enumeration of the pci-e bus in linux?
Is there a simple command or will I have to make kernel changes?
I need the capability to hotplug pcie devices.
As root, try the following command:
echo "1" > /sys/bus/pci/rescan
See this link for more information: http://www.kernel.org/doc/Documentation/ABI/testing/sysfs-bus-pci
I wonder what platform you are on: A work around (aka hack) for this that works on x86 systems is to have the BIOS basically statically configure a PCI device at whatever bus, device, function the FPGA normally lands on, then the OS will enumerate the device and reserve the PCI space for it (even though the device isn't really there). Then in your device driver you will have to do some extra things like setup the BARs and int lines manually after the fpga has been programmed. Of course this requires modifying the BIOS, which if you are working with a BIOS vendor you can contract them to make this change for you, if you are not working with a BIOS vendor then it will be much harder... Also keep in mind that I was working on VxWorks on x86, and we had a AMI make a custom BIOS for our boards...
If you don't have a BIOS, then consider programming it in the bootloader, there you already have the ability to read from disk, and adding GPIO capabilities probably isn't too difficult (assuming you are using jtag and GPIOs?), in fact depending on what bootloader you use it might already be able to do GPIO?
The issues with modifying the kernel to do this is that you have to find the sweet spot where you can read the bitfile, before the PCI enumeration... If for example the disk device drivers are initialized after PCI, then obviously you must do some radical changes to the kernel just to read the bitfile prior to PCI enumeration, which might cause other annoying problems...
One other option which you may have already discovered, and which is really only ok for development time: Power up the system, program the fpga board, then do a reset (without power cycle, for example: sudo reboot now), the FPGA should keep its configuration, and linux should enumerate it...
After turning on your computer, the BIOS enumerates the PCI bus and attempts to fulfill all IO space and memory mapped IO (MMIO) requests. It sets up these BAR's initially, and when the operating system loads these BAR's can be changed by the OS as it sees fit while the PCI bus driver enumerates the bus yet again. It is even possible for the superuser of the system to run the command setpci to change these BAR's after the BIOS has already attempted to configure them and the OS has loaded (may cause drivers to fail and several other bad things if done improperly).
I have had to do this in cases where the card in question was not assigned any resources by the BIOS since the region requested required a 64-bit address and the BIOS only operated with 32-bit address assignments. I was able to go in after-the-fact and change these addresses (originally assigned by the BIOS) to whatever addresses I saw fit, insert the kernel module, and my driver would map and use these newly-assigned addresses for the card without knowing the difference.
The problem that exists with hotplugging PCI-Express cards is that the power to the slot, itself, cannot be turned on/off without specific hotplug controllers that need to exist on the motherboard/backplane. Not having these hotplug controllers to turn the slot's power off may lead to shorts between the tiny pins when the card is physically inserted and/or removed if power is still present. Hotplug events, however, can be initiated by either end (the host or the endpoint device). This does not seem to be the case, however if your FPGA already has a link established with the root complex, a possible solution to your problem would be to generate hotplug interrupts to cause a bus rescan in the OS.
There is a major problem, though -- if your card does not actually obtain a link to the root complex, it won't be able to generate any hotplug events; which seems to be the case. After booting, the FPGA should toggle the PRESENT line on the PCIe bus to tell the OS there is a card ready to be enumerated. Once detected, the OS should attempt to establish a link to the card and assign memory regions to the device. After the OS enumerates the card you'll be able to load drivers against it and see it in lspci. You stated you're using kernel 2.6, which does have support for hotplugging and dynamic resource allocation so this method should work as long as your FPGA supports the ability to toggle the PRESENT PCIe line, too.

Resources