Changes between Initial Version and Version 1 of linux/kernel


Ignore:
Timestamp:
10/22/2017 05:28:45 AM (7 years ago)
Author:
trac
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • linux/kernel

    v1 v1  
     1[[PageOutline]]
     2
     3= Linux Kernel Development =
     4This page is for new or inexperienced developers wanting to work directly on the linux kernel.
     5
     6
     7[=#linuxsource]
     8== Kernel sources ==
     9When choosing a kernel source you need to determine what support you are interested in. Gateworks recommends using our Gateworks downstream vendor kernel if you are needing full hardware support as the mainline Linux kernel is still lacking certain IMX6 support.
     10
     11=== Gateworks downstream vendor kernel ===
     12Gateworks maintains a downstream Linux kernel that contains patches from Freescale and Gateworks to add support for Ventana including some items that have not made it into mainline Linux yet.
     13 * [https://github.com/Gateworks/linux-imx6 source]
     14 * [http://svn.gateworks.com/ventana/images/gateworks-linux-imx6-3.14.48.tar.gz gateworks-linux-imx6-3.14.48.tar.gz] - prebuilt tarball
     15 * see [#backports below] if needing the latest wireless drivers from linux-wireless on top of the older Gateworks downstream vendor kernel
     16
     17Our pre-built Gateworks downstream vendor kernel is a build artifact of our Yocto BSP and contains the following:
     18 * drivers we feel are important for our user base
     19 * wireless drivers from the Linux backports project
     20 * firmware for various devices that require run-time firmware loading
     21 * kernel headers
     22
     23Our kernel source has a default config file (arch/arm/configs/gwventana_defconfig) which which we use but keep in mind that in general wireless drivers and subsystems are not defined there because those modules come from linux-backports instead.
     24
     25=== Mainline upstream linux kernel ===
     26The mainline Linux kernel is missing the following support (which is present in the Gateworks vendor kernel):
     27 * IMX6 video capture (this is slowly being worked on but not yet present as of 4.2)
     28 * adv7393 analog video output (GW54xx)
     29 * HW crypto support
     30 * IMX6 GPU driver (there is work ongoing on an open-source reverse engineered Vivante driver called [https://github.com/laanwj/etna_viv etna_viv])
     31 * VPU support (technically, the upstream coda driver does support the chips-and-media VPU but not in a way that gstreamer can utilize it)
     32
     33See also:
     34 * [wiki:ventana/#mainline-linux Gateworks mainline linux details and patches]
     35 * http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git - source
     36 * https://www.kernel.org/ - source archives
     37 * http://kernelnewbies.org/LinuxVersions - Linux version info
     38
     39
     40[=#toolchain]
     41== Toolchains ==
     42A toolchain is a set of compiler tools (typically gcc) and libraries necessary for compiling and linking source (and possibly debugging, diss-assembling, etc).
     43
     44Typically this includes the following (for the GNU C Compiler):
     45 * ar - linker
     46 * as - assembler
     47 * c++/g++ - C++ compiler
     48 * gcc - C compiler
     49 * ld - linker
     50 * nm - list symbols from object files
     51 * strip - strips debug info from object files
     52 * objcopy - copy and translate object files
     53 * objdump - display info from object files
     54 * ranlib - generate index to archive
     55 * lib/lib* - stdc libraries
     56 * include/ - stdc library headers
     57
     58The kernel (which is written entirely in ANSI-C) is compiled with gcc and does not link against the stdc library.
     59
     60You likely have one of the following toolchains to work with:
     61 * toolchain from an OpenWrt build directory
     62 * toolchain from a prebuilt OpenWrt BSP SDK
     63 * toolchain from a Yocto build directory
     64 * toolchain from a prebuilt Yocto BSP SDK
     65 * pre-built toolchain from somewhere else, like Android
     66
     67
     68[=#rootfs]
     69== Userspace and root filesystem ==
     70Userspace refers to anything in a Linux based OS which is 'not' the kernel. After initialization, the Linux kernel mounts the rootfs and executes PID1 (/sbin/init) which is the start of userspace. The init process and any processes it launches are part of userspace. When applications act on device files such as /dev/sda they use an ioctl API to interact with kernel functions from userspace. A useful way to determine the uses per directory is to execute a {{{man hier}}} on your Ubuntu system.
     71
     72A root filesystem (sometimes referred to as 'a userspace') contains everything you need for a Linux based OS other than the kernel itself. The root filesystem could contain the kernel, but only if the bootloader mounts it and launches it from the rootfs (ie the Gateworks Ventana product family). Note that kernel modules are contained on the root filesystem but they are not considered userspace (yet the insmod/rmmod/modprobe apps that load/remove them are).
     73
     74You likely have one of the following userspaces you want to work with:
     75 * OpenWrt root filesystem
     76 * Yocto root filesystem
     77 * Android root filesystem
     78 * Ubuntu root filesystem
     79
     80In general, you should be able to mix and match kernels and userspace within reason, but note that certain Linux based OS's may require specific kernel functionality (ie Android requires several Android specific kernel features to exist).
     81
     82When working on mainline Linux patches, Gateworks developers often use either an OpenWrt userspace root filesystem or a Yocto userspace root filesystem depending on their needs.
     83
     84
     85[=#building]
     86== Building the Linux kernel (out-of-tree) ==
     87Building the Linux kernel 'out-of-tree' refers to building it outside of the Board Support Package development environment. Each BSP that Gateworks provides builds the kernel for you, but doing constant kernel development within those BSP's may not be very time efficient.
     88
     89Gateworks developers typically do kernel development out-of-tree and boot the kernel over the network to speed up development.
     90
     91If working with kernel modules, one could remove the module (rmmod), download it, install it (insmod) again and test and avoid constantly rebooting the board. Often its just as quick to build a driver static in the kernel, configure your board for network booting, and just rebuild/reboot continually.
     92
     93'''Prerequisites:'''
     94- Linux development host: Gateworks uses and supports Ubuntu which is used here as an example, but other Linux variants can work as well
     95- Toolchain for the CPU architecture of the boards you are working with:
     96 * Ventana uses the Freescale IMX6 SoC which has ARM Cortex-A9 cores with NEON SIMD support. You can download our pre-built OpenWrt toolchain [http://dev.gateworks.com/openwrt/14.08/imx6/OpenWrt-Toolchain-imx6-for-arm_cortex-a9+neon-gcc-4.8-linaro_uClibc-0.9.33.2_eabi.tar.bz2 here]
     97 * Laguna uses the Cavium cns3xxx SoC which has ARM11 MP-Core cores
     98
     99Steps to build the Gateworks kernel for the Ventana family using the Gateworks OpenWrt toolchain:
     1001. Install pre-requisites:
     101{{{#!bash
     102apt-get install build-essential ncurses-dev bc u-boot-tools liblzo2-dev lzop git
     103}}}
     104  * typically 'build-essential' provides enough for compiling, however we need a few other things for kernel development:
     105   - ncurses-dev is needed for menuconfig
     106   - u-boot-tools, bc, and lzop are needed for uImage
     107   - git is needed for checking out the source
     108
     1092. Obtain and install compiler toolchain:
     110 * For Ventana, you can use the pre-built Gateworks OpenWrt 14.08 BSP tailored to the ARM Cortex-A9 CPU used in the IMX6 SoC:
     111{{{#!bash
     112wget http://dev.gateworks.com/openwrt/14.08/imx6/OpenWrt-Toolchain-imx6-for-arm_cortex-a9+neon-gcc-4.8-linaro_uClibc-0.9.33.2_eabi.tar.bz2
     113tar -xvf OpenWrt-Toolchain-imx6-for-arm_cortex-a9+neon-gcc-4.8-linaro_uClibc-0.9.33.2_eabi.tar.bz2
     114}}}
     115
     1163. Obtain Linux kernel source (see [#linuxsource above] to help you decide which kernel version you should use):
     117 * for the '''Gateworks Linux 3.14.x''' based downstream vendor kernel (with full Ventana support including video capture which hasn't made it fully into mainline yet):
     118{{{#!bash
     119git clone https://github.com/Gateworks/linux-imx6.git
     120cd linux-imx6
     121git checkout gateworks_fslc_3.14_1.0.x_ga
     122}}}
     123 * for mainline '''Linux v4.1''' for example (which is missing video capture support for IMX6/Ventana):
     124{{{#!bash
     125git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
     126cd linux
     127git checkout v4.1
     128}}}
     129
     1304. Setup shell env for building:
     131 * Note that the paths here are dependent on the toolchain you installed. The following is for the pre-built Gateworks OpenWrt 14.08 BSP toolchain:
     132{{{#!bash
     133export STAGING_DIR=../OpenWrt-Toolchain-imx6-for-arm_cortex-a9+neon-gcc-4.8-linaro_uClibc-0.9.33.2_eabi
     134TOOLCHAIN=toolchain-arm_cortex-a9+neon_gcc-4.8-linaro_uClibc-0.9.33.2_eabi
     135PATH=$PATH:$STAGING_DIR/$TOOLCHAIN/bin
     136export INSTALL_MOD_PATH=install
     137export INSTALL_HDR_PATH=install
     138export ARCH=arm
     139export CROSS_COMPILE=arm-openwrt-linux-
     140}}}
     141 * Note that STAGING_DIR is something required by the OpenWrt toolchain... your toolchain may differ
     142 * The INSTALL_MOD_PATH env var is used by the modules_install and firmware_install make targets to specify the directory to install modules/firmware into
     143 * The ARCH and CROSS_COMPILE env args are required for proper cross-compilation using your toolchain
     144
     1455. Configure the kernel:
     146 * for the '''Gateworks Linux 3.14.x''' based downstream vendor kernel start with {{{gwventana_defconfig}}}
     147 *
     148{{{#!bash
     149make gwventana_defconfig
     150}}}
     151 * for mainline '''Linux v4.1''' start with the {{{imx_v6_v7_defconfig}}}:
     152{{{
     153#!bash
     154make imx_v6_v7_defconfig
     155}}}
     156 * Optional, modify kernel:
     157{{{#!bash
     158make menuconfig
     159}}}
     160  * The menuconfig make target launches the ncurses based (serial console) Linux kernel menu configuration tool so that you can add or adjust the support to your needs. A common change to the default kernel configurations above would be to add  support for a USB based device, or wireless (802.11) support for example.
     161
     1626. Build kernel:
     163{{{#!bash
     164LOADADDR=0x10008000 make uImage modules dtbs modules_install
     165}}}
     166 * the default make target will build zImage, modules, and dtbs - we want uImage, modules and dtbs
     167 * when building a multi-arch kernel, the build system needs to know the load address to put in the u-boot image header which you provide via the LOADADDR env var. For IMX6 its 0x10008000
     168 * the firmware_install make target can also be specified if you need specific firmware to be placed in $INSTALL_MOD_PATH/lib/firmware
     169 * The uImage make target builds a U-Boot image of the kernel
     170 * The dtbs make target builds the device-tree binaries needed to boot the Ventana kernel (not used for non device-tree kernels)
     171 * The modules_install make target installs the kernel modules to the INSTALL_MOD_PATH directory
     172 * After building and copying the uImage and dtbs to install/boot, you can copy or extract the contents of the install directory to your Linux root filesystem taking care to make the user and group root
     173 * headers will be in the install dir
     174
     1756. Copy additional artifacts:
     176{{{#!bash
     177mkdir $INSTALL_MOD_PATH/boot
     178cp arch/arm/boot/uImage arch/arm/boot/dts/imx6*gw*.dtb $INSTALL_MOD_PATH/boot
     179}}}
     180
     181If you wish to make a tarball of this kernel relative to the root fs:
     182{{{#!bash
     183tar -C $INSTALL_MOD_PATH --owner=0 --group=0 -cvzf linux-4.1.tar.gz .
     184}}}
     185
     186If you need kernel headers for development you can build them via:
     187{{{#!bash
     188make headers_install
     189}}}
     190 * headers will be in INSTALL_HDR_PATH which we set to the install subdir above
     191
     192If you wish to add additional drivers from a newer kernel (for example, you are using the 3.14.x Gateworks downstream vendor kernel but wish to have updated wireless drivers) see [#backports below].
     193
     194
     195[=#backports]
     196== Building the Latest Kernel Modules - Wireless Backports ==
     197Because we don't use mainline linux, but require the latest drivers in wireless, we use the {{{backports}}} project. For more detail on this project, please visit their [https://backports.wiki.kernel.org/index.php/Main_Page documentation] site.
     198
     199In order to build this, you will need a kernel tree already built. In this example, I will assume the {{{gateworks_fslc_3.14_1.0.x_ga}}} kernel is being used.
     200
     2011. Change into the kernel tree directory, making sure it is built using the example shown in the [wiki:linux/kernel#building building section above].
     202{{{#!bash
     203cd gateworks_fslc_3.14_1.0.x_ga
     204make gwventana_defconfig
     205etc...
     206}}}
     207
     2082. Grab the backports version you want to use and {{{cd}}} into it. This example will use the one currently used for our Yocto BSPs.
     209{{{#!bash
     210wget https://www.kernel.org/pub/linux/kernel/projects/backports/2016/01/22/backports-20160122.tar.gz
     211tar xzf backports-20160122.tar.gz
     212cd backports-20160122
     213}}}
     214
     2153. [OPTIONAL] You may have to patch the backports project, depending on the version being used
     216{{{#!bash
     217wget https://raw.githubusercontent.com/Gateworks/meta-gateworks/fido/recipes-kernel/compat-wireless/compat-wireless-all/0001-disable_kconf.patch
     218wget https://raw.githubusercontent.com/Gateworks/meta-gateworks/fido/recipes-kernel/compat-wireless/compat-wireless-all/0002-add-KLIB_CONFIG.patch
     219wget https://raw.githubusercontent.com/Gateworks/meta-gateworks/fido/recipes-kernel/compat-wireless/compat-wireless-all/add_db_txt.patch
     220
     221patch -p1 < 0001-disable_kconf.patch   # Used if no kconfig available (generally never needed)
     222patch -p1 < 0002-add-KLIB_CONFIG.patch # Used if config is not located in kernel directory
     223patch -p1 < add_db_txt.patch           # Used if needing static wireless regulatory database
     224}}}
     225
     2264. Configure shell for cross compiler (please see [wiki:linux/kernel#building the building section] for more details)
     227{{{#!bash
     228export STAGING_DIR=../OpenWrt-Toolchain-imx6-for-arm_cortex-a9+neon-gcc-4.8-linaro_uClibc-0.9.33.2_eabi
     229TOOLCHAIN=toolchain-arm_cortex-a9+neon_gcc-4.8-linaro_uClibc-0.9.33.2_eabi
     230PATH=$PATH:$STAGING_DIR/$TOOLCHAIN/bin
     231export INSTALL_MOD_PATH=install
     232export ARCH=arm
     233export CROSS_COMPILE=arm-openwrt-linux-
     234export KLIB=..
     235export KLIB_BUILD=..
     236export KLIB_CONFIG=..
     237}}}
     238
     239Notice that the {{{KLIB}}} variables are new; They refer to the location of the raw kernel, location where it is built, and location to the config file.
     240
     2415. Make menuconfig to select drivers you want the latest of, then build.
     242{{{#!bash
     243make menuconfig
     244make modules
     245}}}
     246
     2476. [OPTIONAL] Locate the .ko's and copy them to the built kernel
     248{{{#!bash
     249cp --parent $(find -name "*.ko") ../
     250}}}
     251
     252And that's it! If you tar the kernel up, make sure to remove the backports directory as each {{{.ko}}} will be double counted if you already copied the {{{.ko's}}} to the kernel tree. Please see the [wiki:linux/kernel#updating updating section] for details on how to update a target's kernel.
     253
     254== Kernel Module Commands ==
     255 * depmod - builds module dependency database
     256 * modprobe loads module and all dependecies
     257 * insmod loads module but NO depedencies
     258
     259See Linux documentation for more information.
     260
     261[=#updating]
     262== Updating the kernel dtbs and modules on a running target ==
     263If you want to update the kernel, dtbs, and modules on a running target using the tarball created after building the kernel (see above), you can do this by booting and using:
     264{{{#!bash
     265# download kernel specific tarball suitable for booted kernel
     266KERNEL=$(uname -r)
     267URL=http://192.168.1.165/tftpboot/ventana/
     268rm -f /tmp/linux-$KERNEL.tar.gz
     269wget -P /tmp $URL/linux-$KERNEL.tar.gz
     270
     271# untar appropriately
     272if [ -d /etc/config ]; then
     273  # OpenWrt stores modules in a flat tree
     274  echo "OpenWrt Filesystem"
     275  ( cd /; tar -xvzf /tmp/linux-$KERNEL.tar.gz )
     276  find /lib/modules/$KERNEL -name *.ko -exec mv {} /lib/modules/$KERNEL \;
     277else
     278  ( cd /; tar -xvf /tmp/linux-$KERNEL.tar.gz )
     279fi
     280depmod -a
     281sync
     282}}}
     283
     284
     285[=#netboot]
     286== Booting the kernel from the network ==
     287The bootloader's job is to load the linux kernel and execute it. Often during kernel development its advantageous to boot the kernel from the network to create very quick edit/build/boot cycles.
     288
     289This can be accomplished in a variety of ways depending on what you want to come from the network, the kernel, the device-tree blobs, the root filesystem etc. During kernel development usually its just the kernel and device-tree blobs that are needed to boot over the network and using a flash based userspace filesystem is fine.
     290
     291To do this using Ventana as an example:
     292{{{#!bash
     293# boot kernel+dtbs over network via tftp, using NAND filesystem
     294tftp ${loadaddr} ${prefix}uImage && \
     295  tftp ${fdt_addr} ${prefix}${fdt_file2} && \
     296  fdt addr ${fdt_addr} && \
     297  fdt boardsetup && \
     298  setenv bootargs console=${console},${baudrate} root=ubi0:rootfs ubi.mtd=2 rootfstype=ubifs ${video} ${extra} && \
     299  bootm ${loadaddr} - ${fdt_addr}
     300# boot kernel+dtbs over netowrk via tftp, using MMC filesystem
     301tftp ${loadaddr} ${prefix}uImage && \
     302  tftp ${fdt_addr} ${prefix}${fdt_file2} && \
     303  fdt addr ${fdt_addr} && \
     304  fdt boardsetup && \
     305  setenv bootargs console=${console},${baudrate} root=/dev/mmcblk0p1 rootfstype=ext4 rootwait rw ${video} ${extra} && \
     306  bootm ${loadaddr} - ${fdt_addr}
     307# boot kernel_dtbs over network via tftp, using USB filesystem
     308tftp ${loadaddr} ${prefix}uImage && \
     309  tftp ${fdt_addr} ${prefix}${fdt_file2} && \
     310  fdt addr ${fdt_addr} && \
     311  fdt boardsetup && \
     312  setenv bootargs console=${console},${baudrate} root=/dev/sda1 rootfstype=ext4 rootwait rw ${video} ${extra} && \
     313  bootm ${loadaddr} - ${fdt_addr}
     314}}}