world leader in high performance signal processing
Trace: » early_printk

Linux Kernel Early Printk Debugging

Sometimes the kernel crashes during boot before the serial driver and console get a chance to initialize and display the log buffer and possibly relevant crash messages. In that case, you can enable the “early printk” option so that the serial driver is specially initialized very early and you get normal kernel boot messages. Normally you'd instead have to use the post mortem method of viewing the log buffer from u-boot.

There are two parts to the early printk. First you have to enable the option in your kernel configuration menu. Then you have to add the proper options to your kernel commandline (typically the u-boot bootargs environment variable).

Note that this feature is only available in Linux 2.6.22 and later.

Kernel Configuration

The option is enabled by default for ADI development boards. To enable (or make sure it is enabled) for your setup, just open up the kernel configuration menu and browse:

Linux Kernel Configuration
   Kernel hacking  --->
      [*] Early printk

Using the serial port as the early console

Kernel Command Line

Now that your kernel supports early printk, you need to tell the kernel what UART to write out messages during the initial process. This is normally the same UART as your console, but it does not need to be the same. Once the normal console is available, the kernel will disable the early printk and continue on.

The UART you select must match the actual hardware. While the “ttyBF#” will count from 0 based on what UARTs are actually enabled, the “uart#” will count from 0 based on the hardware that is enabled. So on the BF548-EZKit, “ttyBF0” often refers to UART1, which means you would have console=ttyBF0,… but earlyprintk=serial,uart0,…

Enough talking, here's an example that sets the early boot output to go to the first UART (uart0) at a baud rate of 57600.

bfin> print bootargs
bootargs=root=/dev/mtdblock0 rw
bfin> set bootargs $(bootargs) earlyprintk=serial,uart0,57600
bfin> print bootargs
bootargs=root=/dev/mtdblock0 rw earlyprintk=serial,uart0,57600

Kernel Output

There's two lines to look for to make sure things are working properly. The first is early printk enabled on early_BFuart0 while the second is console handover: boot [early_BFuart0] → real [ttyBF0].

bfin> tftp 0x1000000 uImage
Using Blackfin EMAC device
TFTP from server 192.168.0.2; our IP address is 192.168.0.16
Filename 'uImage'.
Load address: 0x1000000
Loading: #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #######################################
done
Bytes transferred = 3525696 (35cc40 hex)
bfin> bootm
## Booting image at 01000000 ...
   Image Name:   Linux-2.6.22.10-ADI-2007R2-pre-s
   Created:      2007-10-24  19:44:19 UTC
   Image Type:   Blackfin Linux Kernel Image (gzip compressed)
   Data Size:    3525632 Bytes =  3.4 MB
   Load Address: 00001000
   Entry Point:  00144000
   Verifying Checksum ... OK
   Uncompressing Kernel Image ... OK
Starting Kernel at = 144000
Linux version 2.6.22.10-ADI-2007R2-pre-svn3763 (vapier@G5) (gcc version 4.1.2 (ADI svn)) #33 Wed Oct 24 15:44:15 EDT 2007
early printk enabled on early_BFuart0                          <--- FIRST LINE TO LOOK FOR ###
Hardware Trace Active and Enabled
Warning: limiting memory to 56MB due to hardware anomaly 05000263
Blackfin support (C) 2004-2007 Analog Devices, Inc.
Compiled for ADSP-BF537 Rev 0.2
Blackfin Linux support by http://blackfin.uclinux.org/
Processor Speed: 500 MHz core clock and 100 MHz System Clock
Board Memory: 64MB
Kernel Managed Memory: 64MB
Memory map:
  text      = 0x00001000-0x000eea60
  rodata    = 0x000ef000-0x0013368c
  data      = 0x00134000-0x00144000
    stack   = 0x00134000-0x00136000
  init      = 0x00144000-0x00634e04
  bss       = 0x00634e04-0x00643610
  available = 0x00643610-0x037ff000
  DMA Zone  = 0x03f00000-0x04000000
Instruction Cache Enabled
Data Cache Enabled (write-through)
Built 1 zonelists.  Total pages: 14224
Kernel command line: root=/dev/mtdblock0 rw earlyprintk=serial,uart0,57600
Configuring Blackfin Priority Driven Interrupts
PID hash table entries: 256 (order: 8, 1024 bytes)
console handover: boot [early_BFuart0] -> real [ttyBF0]        <--- SECOND LINE TO LOOK FOR ###
Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
...

Using shadow Console

The shadow console is always enabled when early printk is enabled.

The shadow console uses a small buffer in memory to keep all the information that printk would normally output to the serial port (or other console). This can be printed out from the bootloader to see what is going on. For example:

## Booting kernel from Legacy Image at 01000000 ...
   Image Name:   bf533-2.6.30.1-ADI-2010R1-pre-sv
   Created:      2009-07-13  18:41:44 UTC
   Image Type:   Blackfin Linux Kernel Image (gzip compressed)
   Data Size:    871534 Bytes = 851.1 kB
   Load Address: 00001000
   Entry Point:  0017e4f4
   Verifying Checksum ... OK
   Uncompressing Kernel Image ... OK
Starting Kernel at = 0017e4f4
We just got the dreaded no messages out of the kernel. Hitting the reset button, and then interrupting the bootloader:
Log buffer from operating system:
Linux version 2.6.30.1-ADI-2010R1-pre-svn6984 (rgetz@imhotep) (gcc version 4.3.3 (ADI-trunk/svn-3407) ) #397 Mon Jul 13 14:41:33 EDT 2009
arch/blackfin/kernel/early_printk.c : 191 [init_early_exception_vectors]
Running on wrong machine type, expected 0x27a5, but running on 0x27c8
arch/blackfin/kernel/setup.c : 190 [bfin_relocate_l1_mem]
arch/blackfin/kernel/bfin_dma_5xx.c : 240 [blackfin_dma_early_init]
arch/blackfin/kernel/bfin_dma_5xx.c : 251 [early_dma_memcpy]
arch/blackfin/kernel/bfin_dma_5xx.c : 307 [early_dma_memcpy_done]

This clearly shows that the system hung in early_dma_memcpy_done since it is booting a kernel built for 0x27a5 (BF533) on a 0x27c8 (BF537).

Further Reading

For more information, see the following file in the kernel source code:

  • linux-2.6.x/Documentation/kernel-parameters.txt