HowTo use Eclipse with CDT to develop and cross-compile(for ARM) Linux kernel module.

A small HowTo (and reminder for myself) on how to use Eclipse (Xilinx SDK) to develop, cross-compile and upload Linux kernel modules for Zynq (ARM-based) embedded board using Xilinx SDK and Xilinx Embedded Linux aka Petalinux. But most steps are universal, you just have to setup cross-compiler and possibly some missing packages, like sshpass and scp.

This HowTo based on:
HowTo use the CDT to navigate Linux kernel source
Configuring Eclipse for Linux Kernel module development

  1. Linux kernel sources is a huge collection of files and Eclipse indexer needs lots of memory. So, start Xilinx SDK with extra memory for indexer:

    xsdk -vmargs -Xms1024m -Xmx2048m -XX:+UseParallelGC

  2. Add new C Project and configure it:
    1. Give it a name AXIDMATest.
    2. Check Use default location.
    3. Set Project Type to Makefile Project > Empty Project.
    4. Select Xilinx ARM GNU/Linux Toolchain for Toolchain.
    5. Click Finish.
  3. In C/C++ General properties for AXIDMAProject:
    1. Check Enable project specific settings.
    2. Select Indexer on left menu:
      1. Check Enable project specific settings.
      2. Uncheck Index source files not included in the build and check Index all header variants.
    3. Select Preprocessor Include Paths, Macros etc. on left menu:
      1. Select GNU C in Languages
      2. Select CDT User Settings Entries for Settings Entries.
      3. Click Add... button on right.
      4. Select Preprocessor Macros File in top-left drop-down menu.
      5. Select File System Path in top-right left drop-down menu.
      6. Set File to /home/d9/Projects/ZedBoardPetalinux/build/linux/kernel/xlnx-4.0/include/generated/autoconf.h.
      7. Now click on Providers tab and check CDT GCC Built-in Compiler Settings.
      8. Uncheck Use global provider shared between projects and add -nostdinc to Command to get compiler specs:.
    4. Now select Paths and Symbols on left menu:
      1. Select Includes tab.
      2. Select GNU C on left languages list.
      3. Click Add... button on right.
      4. Check Add to all configurations and click File system... button.
      5. Select /opt/Petalinux/petalinux-v2015.4-final/components/linux-kernel/xlnx-4.0/arch/arm/include and click OK.
      6. Repeat prev. steps and add /opt/Petalinux/petalinux-v2015.4-final/components/linux-kernel/xlnx-4.0/include.
      7. Now we have to set some symbols, so select #Symbols tab.
      8. Select GNU C on left languages list.
      9. Click Add... button on right.
      10. Type name __KERNEL__ and value 1, check Add to all configurations and click OK.
      11. You may need other symbols too, like DEBUG and CONFIG_OF.
      12. Now we must exclude staff we don't need, so select Source Location tab.
      13. Click on your project and click Link Folder... button on right.
      14. Check Link to folder in the file system and click Browse... button.
      15. Browse to /opt/Petalinux/petalinux-v2015.4-final/components/linux-kernel/xlnx-4.0 and click OK.
      16. Next expand project, select Filter and click on Edit Filter...button.
        Here we can add folders which we want to exclude from the indexing. All paths are relative to project folder. What to exclude is up to you, but the minimum will be all architectures except ARM.
      17. Apply changes and click OK to close all dialogs.
  4. We can exclude kernel source folders from indexer other way too:
    1. Expand AXIDMATest in Project Explorer tab.
    2. Expand xlnx-4.0, select source folders you think you don't need to be indexed and right click on them.
    3. Select Resource Configuration and click on Exclude from Build....
    4. Select project build configurations in which you want to exclude selected sources. In this case you must have the only Default, so select it and click Ok.
    5. Verify that previously selected folders and sources now greyed out and icons "crossed".
    6. If you want to enable them back - do same steps and uncheck related "build configuration" in Resource configuration.
  5. Add sources to project:
    1. Add new Sources Folder and name it sources.
    2. Copy into it axidmatest.c from "/opt/Petalinux/petalinux-v2015.4-final/components/linux-kernel/xlnx-4.0/drivers/dma/xilinx"
    3. Open axidmatest.c and make sure Indexer did it job (you don't have indexer markers complaining about syntax errors).
  6. Now we need a Makefile:
    1. Add new File to the project folder and name it Makefile.
    2. Code below represents Makefile in my case. You have to modify at least path to your configured kernel folder:
      ARCH:=arm
      CROSS_COMPILE:=arm-xilinx-linux-gnueabi-
      KDIR_DI := ~/Projects/ZedBoardPetalinux/build/linux/kernel/xlnx-4.0/
      PWD  := $(shell pwd)
      
      obj-m += sources/axidmatest.o
      
      all:
      	make -C $(KDIR_DI) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) SUBDIRS=$(PWD/sources) modules
      
      clean:
      	make -C $(KDIR_DI) M=$(PWD) clean
      
  7. Finally we are ready to compile our project. Run Build Project, expand sources folder and and verify that it now includes axidmatest.ko.
  8. To upload module and insmod it to remote system I write a small script, which can be used from Eclipse:
    1. In a AXIDMAProject create folder utils.
    2. In utils folder create file upload_rmmod_insmod.sh.
    3. Put something like code below. You obviously must install sshpass and maybe some other missing utils and modify names, passwords, addresses and etc.
      #!/bin/bash
      
      REMOTE_IP="172.21.0.10"
      FILENAME="axidmatest"
      
      sshpass -p 'xxxx' scp $FILENAME.ko root@$REMOTE_IP:~
      sshpass -p 'xxxx' ssh root@$REMOTE_IP "/sbin/rmmod $FILENAME"
      sshpass -p 'xxxx' ssh root@$REMOTE_IP "/sbin/insmod $FILENAME.ko"
      
    4. Set Execute permissions for this script in console or by right clicking on it and selecting Properties and checking permission boxes.
    5. In Run -> External Tools -> External Tools Configurations... add New launch configuration for Program.
      For some reason it is filtered by default in XSDK 2015.4. So, uncheck Filter Configuration Types in menu on top.
    6. In Main tab:
      1. Type name: AXIDMATest
      2. For Location: select ${workspace_loc:/AXIDMATest/utils/upload_insmod.sh}
      3. For Working Directory: select ${workspace_loc:/AXIDMATest/sources}
    7. In Build tab:
      1. Check Build before launch box.
      2. Select Specific projects radio-button.
      3. Click Projects... button to select projects to build.
      4. Check AXIDMATest box and click OK.
    8. In Common tab:
      1. Check Allocate console (necessary for input) box.
      2. Check Launch in background box.
    9. Click Apply and Close button.
    10. Now we can just run this "External Tool" after making changes to source and it will compile project, upload module to remote system, overwrite existin file, rmmod previous and insmod new version of the module. Output related to script execution will be captured in Eclipse console and module output will be posted on remote system stdout.
    11. axidmatest requires an entrance in DTS in order to work and without it insmod and rmmod are silent. So, to make it print something to stdout add pr_info() to the module __init() and __exit():
      static int __init axidma_init(void)
      {
      	pr_info("axidmatest.ko axidma_init() called.\n");
      	return platform_driver_register(&xilinx_axidmatest_driver);
      
      }
      late_initcall(axidma_init);
      
      static void __exit axidma_exit(void)
      {
      	pr_info("axidmatest.ko axidma_exit() called.\n");
      	platform_driver_unregister(&xilinx_axidmatest_driver);
      }
      module_exit(axidma_exit)
      
      MODULE_AUTHOR("Xilinx, Inc.");
      MODULE_DESCRIPTION("Xilinx AXI DMA Test Client");
      MODULE_LICENSE("GPL v2");
      

Leave a Reply