Linux kernel

From indicium
Jump to navigation Jump to search

Kernel drivers


Building the kernel

Configure

To configure using a specified defconfig for a specified architecture

make ARCH=x86 i386_defconfig

To menuconfig starting from a specified defconfig for a specified architecture

make menuconfig ARCH=x86 i386_defconfig

Be sure to explicitly save the configuration.

Build

make -j4 ARCH=x86 CROSS_COMPILE=/bin/i686-linux- all

Various kernel information

New Linux network names

https://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames/

Tips for booting the kernel on a new ARM board

Step 1 - Uncompressing

Do you get the "Uncompressing Linux... done, booting the kernel." print? If not and you are on an ARM architecture, you can enable:

CONFIG_EARLY_PRINTK=y
CONFIG_DEBUG_LL=y
CONFIG_DEBUG_LL_UART_PL01X=y
CONFIG_DEBUG_UART_PHYS=0xF7800000
CONFIG_DEBUG_UART_VIRT=0xF7800000

You have to adjust the UART config according to your platform! Now you should get the Uncompressing Linux... print, otherwise your bootloader has either:

  • Not uploaded the kernel to RAM.
  • Not jumped to the correct place in RAM to execute it.

Good places to check out:

arch/arm/boot/compressed/head.S
arch/arm/boot/compressed/misc.c

Step 2 - First assembly files

The kernel will boot in two different ways:

  • Without device tree support (old style). Your bootloader should have set up register r1 to contain the machine ID and register r2 to contain a pointer to the ATAGS area.
  • With device tree support (new style). Your bootloader should have set up register r2 to contain a pointer to the DTB (device tree blob).

Do you get "Error: unrecognized/unsupported processor variant (0x414fc091)."? Then you have set your defconfig flags in your kernel to the wrong CPU type. Make sure to check if your CPU is an ARMv5, ARMv7 or whatever and set the correct defconfig flags (such as CONFIG_ARCH_ and CONFIG_CPU_).

Good places to check out:

arch/arm/kernel/head-common.S

Step 3 - early c code

You should now be able to reach the function start_kernel() in file init/main.c. This is great place to start off. prints are working differently here, the CONFIG_DEBUG_LL and EARLY_PRINTK is not working here, but once you reach the setup_arch() function in arch/arm/kernel/setup.c, you can use the early_print() function to print stuff using the CONFIG_DEBUG_LL stuff again!

If you have trouble getting the regular pr_xxxx-prints going, then you can replace them all in this file with early_print() instead.

Good places to start with are:

init/main.c
arch/arm/kernel/setup.c
arch/arm/kernel/devtree.c

Step 4 - interrupts and timers

If the board hangs at calibrate_delay() (you may see "Calibrating delay loop..." in the console), then either your interrupts or your timers are not working. Check that both IRQ and timer blocks have been successfully initialized!

Step 5 - getting the serial running the proper way

Make sure you have enabled the correct drivers for your serial HW block and added configuration for them in the devicetree if applicable.

Then make sure you have set up the kernel command line to contain a console keyword with a suitable UART configuration, either in your device tree file (*.dts) or in your defconfig (CONFIG_CMDLINE="console=ttyAMA0,115200 earlyprintk init=/linuxrc") or that it is given from your bootloader. Make sure it is set up to the correct UART and speed.

Hack to get something out

If you still can not get it to work, a good hack is to copy the function early_print() from file arch/arm/kernel/setup.c, and replace the function printk() in file kernel/prink/printk.c with the implementation from early_print(). Now all printk:s will be redirected to be output by the early assembler routines.