{"id":128,"date":"2018-02-05T15:43:09","date_gmt":"2018-02-05T23:43:09","guid":{"rendered":"https:\/\/sysprogs.com\/tutorials\/?p=128"},"modified":"2018-02-05T15:43:09","modified_gmt":"2018-02-05T23:43:09","slug":"building-and-deploying-linux-kernel-for-i-mx6","status":"publish","type":"post","link":"https:\/\/sysprogs.com\/VisualKernel\/tutorials\/imx6\/buildkernel\/","title":{"rendered":"Building and Deploying Linux Kernel for i.MX6"},"content":{"rendered":"<p>This tutorial shows how to build a Linux kernel with debug symbols for your i.MX6 device and boot into it. We will show it based on the dual-core\u00a0<a href=\"http:\/\/www.wandboard.org\/\">Wandboard<\/a>\u00a0board.<\/p>\n<ol>\n<li>First of all identify the kernel version that is currently running on your device by running the following command:\n<pre class=\"code\">uname -r<\/pre>\n<p><img decoding=\"async\" src=\"http:\/\/sysprogs.com\/VisualKernel\/legacy_tutorials\/imx6\/buildkernel\/img\/01-uname.png\" width=\"697\" \/>To minimize compatibility problems it is always recommended to first try building exactly the same kernel version and ensuring that it works. In this example we will use the\u00a0<a href=\"http:\/\/www.wandboard.org\/images\/downloads\/ubuntu-14.04-lxde-20150511.zip\">Ubuntu 14 image<\/a>\u00a0that comes with the 3.10.53 kernel.<\/li>\n<li>Determine whether the device us running a hard float or soft float version of the operating system. The easiest way is to run &#8220;gcc -v&#8221; on the i.MX6 device and check the reported target:<img decoding=\"async\" src=\"http:\/\/sysprogs.com\/VisualKernel\/legacy_tutorials\/imx6\/buildkernel\/img\/02-gnueabihf.png\" width=\"697\" \/>If the target ends with &#8220;gnueabihf&#8221;, it is a hard-float target. If it ends with &#8220;gnueabi&#8221;, it is a soft-float one.<\/li>\n<li>Locate the sources for the kernel version that is running on your device. Normally the board vendor&#8217;s website should provide a link. For Wandboard the sources can be found\u00a0<a href=\"https:\/\/github.com\/wandboard-org\/linux\/tree\/wandboard_imx_3.10.53_1.1.0_ga\">here<\/a>.<\/li>\n<li>On a fast Linux machine install git (apt-get install git) and checkout the sources for the\u00a0<strong>same<\/strong>\u00a0version of the kernel that is running on the device. E.g. for the 3.10.53 version this can be done with the following command\n<pre class=\"code\">git clone https:\/\/github.com\/wandboard-org\/linux.git -b wandboard_imx_3.10.53_1.1.0_ga<\/pre>\n<p><img decoding=\"async\" src=\"http:\/\/sysprogs.com\/VisualKernel\/legacy_tutorials\/imx6\/buildkernel\/img\/02a-gitclone.png\" width=\"700\" \/><\/li>\n<li>Download and extract a cross-toolchain that matches the target of your device. Do not confuse\u00a0<strong>arm-linux-gnueabi<\/strong>\u00a0and\u00a0<strong>arm-linux-gnueabihf<\/strong>\u00a0toolchains. Note that the kernel version 3.10.53 does not support gcc 5.x, so we will download the latest release from the 4.x branch. You can find the arm-linux-gnueabihf releases of the Linaro toolchain\u00a0<a href=\"https:\/\/releases.linaro.org\/components\/toolchain\/binaries\/4.9-2016.02\/arm-linux-gnueabihf\/\">here<\/a>. Then add set the CROSS_COMPILE environment variable to the prefix of the toolchain so that\u00a0<strong>${CROSS_COMPILE}gcc<\/strong>expression will refer to the gcc from the toolchain.<img decoding=\"async\" src=\"http:\/\/sysprogs.com\/VisualKernel\/legacy_tutorials\/imx6\/buildkernel\/img\/03-toolchain.png\" width=\"700\" \/><\/li>\n<li>Now you are ready to build the kernel. First of all extract the kernel configuration from the i.MX6 device (available as \/proc\/config.gz) and unpack it:\n<pre class=\"code\">scp ubuntu@wandboard:\/proc\/config.gz .\r\ngunzip config.gz --stdout &gt; .config<\/pre>\n<p><img decoding=\"async\" src=\"http:\/\/sysprogs.com\/VisualKernel\/legacy_tutorials\/imx6\/buildkernel\/img\/04-config.png\" width=\"700\" \/><\/li>\n<li>Before we can build the kernel we need to make the following modifications to the configuration:\n<ul>\n<li>Enable debug symbols<\/li>\n<li>Disable the DEV_FSL_CAAM cryptographic device as its driver will freeze the kernel once you connect a JTAG debugger<\/li>\n<\/ul>\n<p>The easiest way to do that is to filter out lines containing DEBUG_INFO and DEV_FSL_CAAM from the .config file and run &#8220;make oldconfig&#8221;:<\/p>\n<pre class=\"code\">grep -v \"DEBUG_INFO\\|DEV_FSL_CAAM\" &lt; .config &gt; newconfig\r\nmv newconfig .config\r\nARCH=arm make oldconfig<\/pre>\n<p><img decoding=\"async\" src=\"http:\/\/sysprogs.com\/VisualKernel\/legacy_tutorials\/imx6\/buildkernel\/img\/05-filterconfig.png\" width=\"700\" \/>Ensure you answer &#8220;Yes&#8221; to the question about debug info and &#8220;No&#8221; to the question about the FSL CAAM driver.<\/li>\n<li>Finally build the kernel by running &#8220;ARCH=arm make -j&lt;number of parallel build threads&gt;&#8221;:<img decoding=\"async\" src=\"http:\/\/sysprogs.com\/VisualKernel\/legacy_tutorials\/imx6\/buildkernel\/img\/06-build.png\" width=\"686\" \/><\/li>\n<li>Now we will install the kernel on the board. On most i.MX6 boards the kernel is loaded by the\u00a0<a href=\"http:\/\/www.denx.de\/wiki\/U-Boot\">U-Boot bootloader<\/a>\u00a0that can be configured to load it from many different places. In order to figure out how to install the kernel, connect the COM port to your board, reset it and press ENTER when the bootloader asks to press any key to abort automatic boot. Then run the &#8220;printenv&#8221; command:<img decoding=\"async\" src=\"http:\/\/sysprogs.com\/VisualKernel\/legacy_tutorials\/imx6\/buildkernel\/img\/07-printenv.png\" width=\"640\" \/><\/li>\n<li>\u00a0U-Boot may be configured to load the kernel from various places: specific address on the SD card, specific file in one of the SD card partitions or even a network location. You can find it out by looking at the\u00a0<strong>bootcmd<\/strong>\u00a0environment variable. E.g. here is the snippet from the environment of the Ubuntu 14 image:\n<pre class=\"code\">bootcmd=mmc dev ${mmcdev}; if mmc rescan; then if run loadbootscript; then run bootscript; else if run loadimage; then run mmcboot; else run netboot; fi; fi; else run netboot; fi\r\nfdt_file=boot\/imx6dl-wandboard.dtb\r\nimage=boot\/zImage\u00a0\r\nloadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\r\nloadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}\u00a0\r\nmmcdev=0\r\nmmcpart=1\r\nscript=boot.scr<\/pre>\n<p>The boot sequence here is as follows:<\/p>\n<ul>\n<li>Select SD card #0<\/li>\n<li>Try loading the\u00a0<strong>boot.scr<\/strong>\u00a0script from partiaion 1 of SD card 0<\/li>\n<li>If the script is not found, load the kernel from\u00a0<strong>image\/zImage<\/strong>\u00a0and device tree from\u00a0<strong>boot\/imx6dl-wandboard.dtb<\/strong><\/li>\n<\/ul>\n<\/li>\n<li>Boot into the current system on the i.MX6 board and mount the partition 1 to \/media\/boot:\n<pre class=\"code\">sudo su\r\nmkdir \/mnt\/boot\r\nmount \/dev\/mmcblk2p1 \/mnt\/boot<\/pre>\n<p><img decoding=\"async\" src=\"http:\/\/sysprogs.com\/VisualKernel\/legacy_tutorials\/imx6\/buildkernel\/img\/08-boot.png\" width=\"664\" \/><\/li>\n<li>The boot partition on the Ubuntu 14 image does not contain the boot.scr script, so all we need to do is replace the \/mnt\/boot\/boot\/zImage with the new kernel:<img decoding=\"async\" src=\"http:\/\/sysprogs.com\/VisualKernel\/legacy_tutorials\/imx6\/buildkernel\/img\/09-deploy.png\" width=\"686\" \/>\n<p class=\"warning\">Do not confuse the boot directory on the partition 1 (<strong>\/mnt\/boot\/boot<\/strong>) and the boot directory on the system partition (<strong>\/boot<\/strong>). The second one on the Ubuntu 14 image is simply ignored.<\/p>\n<\/li>\n<li>If the bootloader configuration loads kernel from a fixed address on the SD card, you can build an U-Boot image of the kernel by running the following command:\n<div class=\"code\">ARCH=arm make -j8 uImage LOADADDR=0x10008000<\/div>\n<p>LOADADDR can be found by checking the U-Boot output when loading the current image. Then you can copy the image to the SD card using the &#8216;dd&#8217; command on the Wandboard.<\/li>\n<li>Before you can boot into the new kernel, build and install the kernel modules. First of all, run the following command on the build machine to export all modules into a separate folder:\n<pre class=\"code\">ARCH=arm make INSTALL_MOD_PATH=..\/modules modules_install<\/pre>\n<p><img decoding=\"async\" src=\"http:\/\/sysprogs.com\/VisualKernel\/legacy_tutorials\/imx6\/buildkernel\/img\/instmod.png\" width=\"691\" \/><\/li>\n<li>Then go to the ..\/modules directory, create a .tgz file containing all modules and upload it to the i.MX6 board:\n<pre class=\"code\">cd ..\/modules\r\ntar czf modules.tgz *\r\nscp modules.tgz ubuntu@wandboard:\/tmp\/modules.tgz<\/pre>\n<p><img decoding=\"async\" src=\"http:\/\/sysprogs.com\/VisualKernel\/legacy_tutorials\/imx6\/buildkernel\/img\/upload.png\" width=\"691\" \/><\/li>\n<li>On the board unpack the modules.tgz archive directly to the root directory (it will have the &#8216;lib\/modules\/&lt;name&gt;&#8217; subdirectories inside it):\n<pre class=\"code \">cd \/\r\nsudo tar xf \/tmp\/modules.tgz<\/pre>\n<p><img decoding=\"async\" src=\"http:\/\/sysprogs.com\/VisualKernel\/legacy_tutorials\/imx6\/buildkernel\/img\/extract.png\" width=\"674\" \/><\/li>\n<li>Reboot your board and run the &#8216;dmesg | head&#8217; command to check the first lines of the startup log. Use the build date reported by the kernel to verify that the new image was loaded successfully:<img decoding=\"async\" src=\"http:\/\/sysprogs.com\/VisualKernel\/legacy_tutorials\/imx6\/buildkernel\/img\/10-head.png\" width=\"700\" \/><\/li>\n<li>Check that the kernel modules have been loaded by running &#8216;insmod&#8217;. If no modules are listed, you may start getting strange debugging errors, so double-check the module directory and the log shown by the dmesg command for clues:<img decoding=\"async\" src=\"http:\/\/sysprogs.com\/VisualKernel\/legacy_tutorials\/imx6\/buildkernel\/img\/lsmod.png\" width=\"674\" \/><\/li>\n<\/ol>\n<p>Now that the kernel with debug symbols is built and loaded, you can setup a VisualKernel project to conveniently debug your kernel-mode code.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to build a Linux kernel with debug symbols for your i.MX6 device and boot into it.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[39],"tags":[34,40],"_links":{"self":[{"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/posts\/128"}],"collection":[{"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/comments?post=128"}],"version-history":[{"count":1,"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/posts\/128\/revisions"}],"predecessor-version":[{"id":129,"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/posts\/128\/revisions\/129"}],"wp:attachment":[{"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/media?parent=128"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/categories?post=128"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/tags?post=128"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}