07-31-2019 11:24 PM
Hello all,
Yet another similar post about UIO. I have created a custom IP which simply writes the 4 LEDs. This is in a custom AXI-IP rather than using the AXI-GPIO. So, the slv_reg0 updates the values of LEDs on every rising edge of the axi_clk. Everything works fine I have tested with /dev/mem. And I am using Vivado v2019.1 and Enclustra BSP (Linux buildroot 4.14.0-xilinx-g7b5b9941b-dirty)
I have created Linux kernel with Userspace I/O drivers enbaled
--- Userspace I/O drivers <*> Userspace I/O platform driver with generic IRQ handling <*> Userspace platform driver with generic irq and dynamic memory
I added "generic-uio" compatible string as well as bootargs. The devicetree blob converted back to text
chosen { linux,stdout-path = "/amba/serial@e0000000"; bootargs = "uio_pdrv_genirq.of_id=generic-uio"; }; amba_pl { #address-cells = <0x1>; #size-cells = <0x1>; compatible = "simple-bus"; ranges; Blink@43c00000 { clock-names = "s00_axi_aclk"; clocks = <&clkc 15>; compatible = "generic-uio"; reg = <0x43c00000 0x10000>; xlnx,s00-axi-addr-width = <0x4>; xlnx,s00-axi-data-width = <0x20>; }; };
Then copied everything to SD card and booted Linux, but in /dev there in no uioX present.
The /sys/class/uio dir is also empty (eg. /sys/class/uio/uio0 not there)
the UIO driver is compiled and present from the kernel symbol table (/proc/kallsyms)
# grep uio /proc/kallsyms c047a860 t uio_poll c047a8c0 t uio_find_mem_index c047a8f4 T uio_event_notify c047a940 t uio_interrupt c047aaf8 t uio_dev_del_attributes c047ab78 t uio_free_minor c047abac T __uio_register_device c047afbc T uio_unregister_device c047b020 t uio_fasync c047b030 t uio_release c047b078 t uio_open c047b148 t uio_mmap c047b270 t uio_vma_fault c047b318 t uio_write c047b3e8 t uio_read c047b578 t uio_major_cleanup c047b5a0 t uio_pdrv_genirq_runtime_nop c047b5a8 t uio_pdrv_genirq_remove c047b5e0 t uio_pdrv_genirq_release c047b600 t uio_pdrv_genirq_open c047b620 t uio_pdrv_genirq_irqcontrol c047b694 t uio_pdrv_genirq_handler c047b6d8 t uio_pdrv_genirq_probe c047b930 t uio_dmem_genirq_runtime_nop c047b938 t uio_dmem_genirq_remove c047b990 t uio_dmem_genirq_release c047bad0 t uio_dmem_genirq_open c047bc04 t uio_dmem_genirq_irqcontrol c047bc78 t uio_dmem_genirq_handler c047bca8 t uio_dmem_genirq_probe c091b2c4 t uio_init c091b398 t uio_pdrv_genirq_init c091b3a8 t uio_dmem_genirq_init
The question is what should I modify, add or remove to have /dev/uio 'created' so I can access it in a C code via the UIO? Where did I go wrong?
Thank you for the help :)
09-03-2019 07:57 PM - edited 09-03-2019 07:58 PM
There are two aspects to the problem.
1. Kernel UIO driver enabling/linking
There are 4 ways to do this.
a. On the command line in u-boot, set bootargs to include "uio_pdrv_genirq.of_id=generic-uio". While booting, stop in u-boot and do this with setenv command. After booting to userspace, output of cat /proc/cmdline should show the bootargs with what was set.
b. Use a custom modified u-boot and have it as part of your env. I am assuming one would know where to do this in u-boot.
c. Device tree approach should work but I have not tried it so not sure what exactly has to go in device tree's chosen node. It seems correct in your case, but, may be your deployment (see below) is not correct or not happening.
d. Change the compatible property in the uio_pdrv_genirq.c itself.
2. Deployment
Here there are two ways depending on your preferred workflow.
I use Yocto, however, during development I prefer to have an out of tree build of either kernel or u-boot, which I then deploy to the device by copying it via ssh and then replacing it on the boot partition. I am not sure about the Enclustra BSP, but, I work on our custom board with an Ultrascale MPSOC and I generate an image.ub file which I replace for this. During testing and development, trying to do builds everytime for an update is cumbersome. When I said, recompile the kernel again, I was referring to 1.c & 1.d above and then deploying it like this.
In the end, you would want to integrate this in build system. Now, depending on what you opt for in the first step, accordingly you would point your build system to a git repo with your custom changes or tell it to apply the patches required on top of vanilla Xilinx kernel/u-boot and then deploy this complete image.
Hope this clarifies things.
08-30-2019 04:03 AM
Are you sure the bootargs in chosen are actually being passed? Does the output of /proc/cmdline show it? Also the device tree node entry does not seem to have a status okay entry.
08-30-2019 04:26 AM
Are you sure the bootargs in chosen are actually being passed?
⇒ I have also tried directly compatible = "uio_pdrv_genirq" but didn't work either
Does the output of /proc/cmdline show it?
⇒ console=ttyPS0,115200 rw earlyprintk rootwait root=/dev/mmcblk0p2
Also the device tree node entry does not seem to have a status okay entry.
⇒ I tried that as well, didn't work
08-30-2019 07:53 AM
compatible = "uio_pdrv_genirq" would be incorrect. If the compatible device tree node is "generic-uio" then your bootargs should have "uio_pdrv_genirq.of_id=generic-uio".
This should also show up when you do cat /proc/cmdline. I am not that well versed with buildroot but you can try compiling a kernel outside of buildroot and then place it in the image or board.
Another way would be to put the compatible in uio_of_genirq_match struct itself in the driver.
I use uio for Display Port RX and I have these.
&SUBBLOCK_DP_BASE_v_dp_rxss1_0 { compatible = "xlnx,v-dp-rxss1-1.0", "dprxss-uio"; reg = <0x0 0x80004000 0x0 0x2000>; status = "okay"; };
And in the driver uio_pdrv_genirq.c
static struct of_device_id uio_of_genirq_match[] = { { .compatible = "dprxss-uio", }, { /* Sentinel */ }, };
These two give me the /dev/uio0 node.
09-02-2019 02:13 AM
@sanchayan_maity thank you for your reply, It helped a lot.
But I didn't understand why did you suggest to recompile the whole Kernel once gain!?
And Second, I don't think my bootargs in DeviceTree is parsing at all, because no matter what I set when I do cat /proc/cmdline, I always get the same output
# cat /proc/cmdline console=ttyPS0,115200 rw earlyprintk rootwait root=/dev/mmcblk0p2
09-03-2019 07:57 PM - edited 09-03-2019 07:58 PM
There are two aspects to the problem.
1. Kernel UIO driver enabling/linking
There are 4 ways to do this.
a. On the command line in u-boot, set bootargs to include "uio_pdrv_genirq.of_id=generic-uio". While booting, stop in u-boot and do this with setenv command. After booting to userspace, output of cat /proc/cmdline should show the bootargs with what was set.
b. Use a custom modified u-boot and have it as part of your env. I am assuming one would know where to do this in u-boot.
c. Device tree approach should work but I have not tried it so not sure what exactly has to go in device tree's chosen node. It seems correct in your case, but, may be your deployment (see below) is not correct or not happening.
d. Change the compatible property in the uio_pdrv_genirq.c itself.
2. Deployment
Here there are two ways depending on your preferred workflow.
I use Yocto, however, during development I prefer to have an out of tree build of either kernel or u-boot, which I then deploy to the device by copying it via ssh and then replacing it on the boot partition. I am not sure about the Enclustra BSP, but, I work on our custom board with an Ultrascale MPSOC and I generate an image.ub file which I replace for this. During testing and development, trying to do builds everytime for an update is cumbersome. When I said, recompile the kernel again, I was referring to 1.c & 1.d above and then deploying it like this.
In the end, you would want to integrate this in build system. Now, depending on what you opt for in the first step, accordingly you would point your build system to a git repo with your custom changes or tell it to apply the patches required on top of vanilla Xilinx kernel/u-boot and then deploy this complete image.
Hope this clarifies things.
09-04-2019 12:11 AM
I tried 1.a & 1.b methods and it worked. Thank you :) However, I have following questions;
1. In the section 2. Deployment, you said "out of tree build", What do you mean by that?
2. Every time I make changes to the DeviceTree, do I have to recompile the Kernel with it?!
3. Can you please provide more information about your last point "you would want to integrate... ...complete image", may be a link or something. It is not clear to me.
P.S. I knew method 1.d will work, since It works with my custom platform device driver. But I didn't want to change the Linux source code.
09-11-2019 09:39 PM