Devicetree in embedded linux - linux

How can I convert platform specific file to device tree?.
I know theoretically about device tree.
Please explain how its works in raspberry pi board or any other boards.

A device-tree is simply a data structure for describing the hardware present on a system. In the absence of device-tree, systems rely on "board-files". These are C files with plenty of structures, each describing every individual hardware present on the system and also how they are connected.
Porting of code from legacy "board-files" to device-tree dts files is currently an ongoing process across several platforms/devices based on the ARM architecture.
To do this one requires proper understanding of the
platform/device hardware.
structure of the board-file.
structure of the dts file.
This answer should help you get started in preparing a device-tree dts.
Also there is an ongoing effort to migrate the raspberry-pi Linux-kernel to use device-tree. Take a look at the source and booting instructions.

Related

Zynq, Yocto Linux and Custom FPGA IP Block Workflow

I'm new to the Zynq devices and also to linux and the Yocto project.
I now have a project where I need to implement a custom FPGA IP block and use it from a yocto generated linux distribution.
Obviously I will have to write the linux drivers for that custom IP. But I'm not able to find a clear explanation how the workflow for such a project may look like.
I found some old tutorials but I'm not sure if they are still the way to go, so an up-to-date best practice workflow would be great.
What I did so far:
I created a test project in Vivado and created a small led example by passing through the FPGA block in a Microzed + carrier board.
Then I exported the HW from Vivado to get a BSP package I tested in a bare metal project with Vitis.
I installed Yocto and I build a reference distro for my microzed board with just a serial interface by following a tutorial online.All this comes more or less pre-backed from Xilinx.
But now I need to use a Yocto generated linux distro and enable it to use my custom (LED) IP.
My questions:
How does a detailed workflow in this case look like (at the end I
need a bootable SD card)?
More in detail:
How can I bring the mydevice_bsp generated from Vivado into the Yocto distro?
In which environment(how to write them i'll find out my self) do I write the
drivers for the yocto Linux and bring them into the distro?
How do I load the bitstream into the FPGA fabric when the Linux image has booted up?
Unfortunately I do not have to much time to get all this working, so it would be really cool to find a step by step tutorial from the start to the end.
Thanks in advance for your help.
Regards
Martin
I´m not sure if someone has written down a workflow for this, but I can tell you how I would handle it.
Create your IP code as hardware and use the IP packager to pack the code. You can also add some driver code too, so the SDK can use this to automatic generate the drivers. So you can use the regular workflow in Vitis to write your software.
Or you skip this part and use the hardware direct in your Linux. So you will create an IP core and add him to your system in Vivado. Export the hardware to get your BSP file. Then you need the Xilinx Device Tree Generator to generate your device tree. This tool uses some basic definitions (like the base adress) of your IP core to generate the device tree part for your hardware.
Then you create a normal bitstream and a bunch of tools to create your bootloader, kernel, device tree, bitstream file, etc. (all without Yocto). Copy all files to a SD card and boot up your device. You can take a look at my Linux project and the Wiki when you need some help. Now you can begin to write the driver for your device and test him on your real hardware. At last you can create a Yocto recipe to automatic include your driver to the kernel with KConfig.
After booting Linux you find a device /dev/devcfg which can be used to reprogram the FPGA. Please note that changing the FPGA with impact on the processing system (i. e. you add some interfaces to your PS) will cause in some errors (maybe that bug is gone over the last years, but I have to issue this problem a few years ago).
So according to your LED example you have to do the following steps:
Create the IP core
Create a basic processing system and add the IP core
Generate the bitstream
Export the hardware to Vitis
Open Vitis and create a new FSBL project
Add the Device Tree Generator to the Vitis repositories
Create a new device tree project
Build BOOT.bin, uImage, devicetree.dtb and copy them to your SD card
Boot your device
Check /proc/device-tree/ for your device
Begin with the driver development
Export your driver to Kconfig and Yocto (or use him as a loadable module)
You can find all the steps in my Wiki. Feel free to ask me.
But please note: The tutorial isn´t that new and unfortunately I don´t add a custom IP integration to that tutorial (maybe I will add it soon) but it should show you the way how you can do it.

Linux - Nic's flags configuration

Context
Debian 64 bit. kernel 3.18.x
Litterally struggling to understand how a network driver is initialized.
I mean how to choose which flag to set. I dig in the kernel for days now to train myself. The card setup is the only point I miss.
I take the intel 82574 as an example. I downloaded the card's datasheet, saw many information but not a clue on how to setup the hardware.
Question
Where to start to know what flags to set ? The datasheet didn't helped me (i am not very experienced but willing to learn).
Please give me a starting point, a tip or anything to help me understand what is going on in the already written open sourced driver.
How can a developer knows how to initialize his nic ? (yes reinventing the wheel the time to understand)
You'll need to read the source code of the kernel module that handles your specific NIC.
EDIT: Of course, to develop such a module, you'd usually just use a register map as specified in a data sheet or application node; often, manufacturers develop their linux drivers themselves, so the driver developers might even be the same people that developed the chipset (because it's really handy to have a platform to test against -- it's impossible to test hardware without having something like a driver, so you might as well write a proper driver).
Furthermore, devices often come with code examples -- no one is going to build a device based on an IC that he has not seen in action.
If you've got access to neither proper documentation nor source, you can only reverse engineer - and that's an incredibly large field.
Using your example with the Intel 82574 Network Adapter, Intel provides a zip file of the source code used to build the Linux driver. The driver is like all drivers in that it hooks into the OS API for Networking.
The Linux networking API is document on both the linux.org site and discussed on popular Linux sites like lwn.org. Below is the link to lwn's chapter on Network drivers using the networking API called NAPI.
https://static.lwn.net/images/pdf/LDD3/ch17.pdf
You'll notice in the Intel igb driver source code that the NAPI net_device data structure is one of the first things that is setup. It registers the driver with the OS. This way the OS knows which igb functions to call when loading/unloading the driver, or when needing to send/receive data.
The igb functions read/modify/write the necessary bits in the 82574's memory-mapped registers that control and monitor the device. The device registers are all documented in the 82574 datasheet available on Intel's site. And this is usually the case for almost any networking company like Broadcom/Chelsio/Mellanox/Marvell.
Hope that helps a little more.

Custom Linux Kernel

I'm complety new to this but I finally got around to building a Linux kernel so far so good. I am following a guide here:
A10-OLinuXino-LIME
My problem/concern is now I am in a .config menu and I've been searching online to no avail to determine what does it mean by a modularizes features verse includes, like should I switch to if I want those features to be there?
Any help or advice would be greatly appreciated it! I'm primarily doing this to include WiFi usb drivers I will be needing.
It depends on what system you run this kernel. If it's an embedded system, then you will probably be more concerned about memory benefits. In RAM you can win about several Kbytes per module. For the devices are not represented in the system/hardware, it then has a sense to put some drivers on Modules. Some modules can be taking more time when the kernel starts, and it is probably better to load them later, when the system is running.
You will probably be concerned about disk space, if you put some stuff Compiled-in so you can have a benefit because you don't need to have a module loading utility.
Have a look at this thread as well
I'm primarily doing this to include WiFi usb drivers I will be needing.
Its not necessary to build the complete kernel unless to build a USB WiFi driver. All you need is the kernel headers installed. From make menuconfig select the module you want to build, choose M, save the .config. This will build a module which can be loaded, instead of getting compiled as a part of the vmlinux image.

Linux kernel internals using ARM architecture as reference

Most of the linux kernel architecture books were written taking x86 architecture as reference (LKD by robert love or ULKI by bovett). Does there exist any book which explain linux kernel internals taking ARM architecture as reference.
Some basic questions are missing to really recommend you something and point you to useful resources:
what low level routines do you mean?
what are you going to do with that information?
The linux kernel is running on ARM already and most of the low level stuff is solved there and you shouldn't touch that unless you really know what you're doing. The linux kernel provides some generic low-level interfaces that its drivers stay portable without plattform specific snippets. Unless your intention is to add another ARM processor that is not supported yet you shouldn't need to dig around there.
If you want to add drivers or use components look into this device tree howto.
One major difference to X86 is the device tree/ open firmware stuff because System on Chip devices have often the same hardware mapped to different memory.
If you are looking for embedded kernel development you might also look into elinux.
Further reading is also provided in the linux-kernel tag wiki of stackoverflow.

Porting Linux to ARM

BACKGROUND
Off late, I am finding myself increasingly fascinated for better understanding of Linux. Additionally, I want to play around as well, to understand the nuances of it.
I am not a great Linux hacker. I know C,C++ etc,I have programmed in assembly for ARM and other processors, I know a bit theoretically of the workings of an OS, to a small extent of how Linux is structured (monolithic kernel etc).
Under this light, I am increasingly interested in how can a particular kernel be ported into an ARM based machine.
So my questions are:
What are the steps a developer need to take to port a kernel to an ARM based machine.
How should the development be, i.e should hardware be made first or development of both hw/sw should run parallely or any other method.
If anybody has link of "chronicling" of such an endeavour of designing an ARM based machine (or any other chip based machine) and then porting a kernel onto it, please do share it.
If you're truly interested in finding out what differentiates Linux on one arch from another then you should look at the contents of the arch/ directory in the kernel source tree.

Resources