DEBUG_KERNEL - notro/rpi-firmware GitHub Wiki

lib/Kconfig.debug

config DEBUG_KERNEL
        bool "Kernel debugging"

arch/arm/Kconfig.debug

config DEBUG_LL
        bool "Kernel low-level debugging functions (read help!)"
        depends on DEBUG_KERNEL

config DEBUG_BCM2835
        bool "Kernel low-level debugging on BCM2835 PL011 UART"
        depends on ARCH_BCM2835
        select DEBUG_UART_PL01X

config DEBUG_LL_INCLUDE
        string
        default "debug/pl01x.S" if DEBUG_LL_UART_PL01X || DEBUG_UART_PL01X
        default "mach/debug-macro.S"

config DEBUG_UART_PHYS
        hex "Physical base address of debug UART"
        default 0x20201000 if DEBUG_BCM2835

config DEBUG_UART_VIRT
        hex "Virtual base address of debug UART"
        default 0xf0201000 if DEBUG_BCM2835

config DEBUG_UNCOMPRESS
        bool
        depends on ARCH_MULTIPLATFORM || PLAT_SAMSUNG || ARM_SINGLE_ARMV7M
        default y if DEBUG_LL && !DEBUG_OMAP2PLUS_UART && \
                     (!DEBUG_TEGRA_UART || !ZBOOT_ROM)

config UNCOMPRESS_INCLUDE
        string
        default "debug/uncompress.h" if ARCH_MULTIPLATFORM || ARCH_MSM || \
                                        PLAT_SAMSUNG || ARM_SINGLE_ARMV7M || \
                                        ARCH_SHMOBILE_LEGACY
        default "mach/uncompress.h"

Kernel decompression message

Uncompressing Linux... done, booting the kernel.

ARCH_BCM2835

kconfig

CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_LL=y
CONFIG_DEBUG_BCM2835=y
CONFIG_DEBUG_LL_INCLUDE="debug/pl01x.S"
CONFIG_DEBUG_UART_PL01X=y
CONFIG_DEBUG_UART_PHYS=0x20201000
CONFIG_DEBUG_UART_VIRT=0xf0201000
CONFIG_DEBUG_UNCOMPRESS=y
CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"

arch/arm/configs/bcm2835_defconfig

CONFIG_DEBUG_LL=y
CONFIG_EARLY_PRINTK=y

arch/arm/include/debug/uncompress.h

#ifdef CONFIG_DEBUG_UNCOMPRESS
extern void putc(int c);
#else
static inline void putc(int c) {}
#endif
static inline void flush(void) {}
static inline void arch_decomp_setup(void) {}

arch/arm/boot/compressed/Makefile

ifeq ($(CONFIG_DEBUG_UNCOMPRESS),y)
OBJS    += debug.o
endif

arch/arm/boot/compressed/debug.S

#include CONFIG_DEBUG_LL_INCLUDE

ENTRY(putc)
        addruart r1, r2, r3
        waituart r3, r1
        senduart r0, r1
        busyuart r3, r1
        mov      pc, lr
ENDPROC(putc)

arch/arm/include/debug/pl01x.S

#ifdef CONFIG_DEBUG_UART_PHYS
                .macro  addruart, rp, rv, tmp
                ldr     \rp, =CONFIG_DEBUG_UART_PHYS
                ldr     \rv, =CONFIG_DEBUG_UART_VIRT
                .endm
#endif

                .macro  senduart,rd,rx
                strb    \rd, [\rx, #UART01x_DR]
                .endm

                .macro  waituart,rd,rx
1001:           ldr     \rd, [\rx, #UART01x_FR]
 ARM_BE8(       rev     \rd, \rd )
                tst     \rd, #UART01x_FR_TXFF
                bne     1001b
                .endm

                .macro  busyuart,rd,rx
1001:           ldr     \rd, [\rx, #UART01x_FR]
 ARM_BE8(       rev     \rd, \rd )
                tst     \rd, #UART01x_FR_BUSY
                bne     1001b
                .endm

ARCH_BCM2708

kconfig

# CONFIG_DEBUG_LL is not set
CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
CONFIG_UNCOMPRESS_INCLUDE="mach/uncompress.h"

arch/arm/mach-bcm2708/include/mach/uncompress.h

#include <linux/io.h>
#include <linux/amba/serial.h>
#include <mach/hardware.h>

#define UART_BAUD 115200

#define BCM2708_UART_DR   __io(UART0_BASE + UART01x_DR)
#define BCM2708_UART_FR   __io(UART0_BASE + UART01x_FR)
#define BCM2708_UART_IBRD __io(UART0_BASE + UART011_IBRD)
#define BCM2708_UART_FBRD __io(UART0_BASE + UART011_FBRD)
#define BCM2708_UART_LCRH __io(UART0_BASE + UART011_LCRH)
#define BCM2708_UART_CR   __io(UART0_BASE + UART011_CR)

/*
 * This does not append a newline
 */
static inline void putc(int c)
{
        while (__raw_readl(BCM2708_UART_FR) & UART01x_FR_TXFF)
          barrier();

        __raw_writel(c, BCM2708_UART_DR);
}

static inline void flush(void)
{
        int fr;

        do {
          fr = __raw_readl(BCM2708_UART_FR);
          barrier();
        } while ((fr & (UART011_FR_TXFE | UART01x_FR_BUSY)) != UART011_FR_TXFE);
}

static inline void arch_decomp_setup(void)
{
        int temp, div, rem, frac;

        temp = 16 * UART_BAUD;
        div = UART0_CLOCK / temp;
        rem = UART0_CLOCK % temp;
        temp = (8 * rem) / UART_BAUD;
        frac = (temp >> 1) + (temp & 1);

        /* Make sure the UART is disabled before we start */
        __raw_writel(0, BCM2708_UART_CR);

        /* Set the baud rate */
        __raw_writel(div, BCM2708_UART_IBRD);
        __raw_writel(frac, BCM2708_UART_FBRD);

        /* Set the UART to 8n1, FIFO enabled */
        __raw_writel(UART01x_LCRH_WLEN_8 | UART01x_LCRH_FEN, BCM2708_UART_LCRH);

        /* Enable the UART */
        __raw_writel(UART01x_CR_UARTEN | UART011_CR_TXE | UART011_CR_RXE,
            BCM2708_UART_CR);
}

/*
 * nothing to do
 */
#define arch_decomp_wdog()

arch/arm/mach-bcm2708/include/mach/debug-macro.S

#include <mach/platform.h>

		.macro	addruart, rp, rv, tmp
		ldr	\rp, =UART0_BASE
		ldr	\rv, =IO_ADDRESS(UART0_BASE)
		.endm

#include <debug/pl01x.S>

early_print()

arch/arm/kernel/setup.c#

void __init early_print(const char *str, ...)
{
        extern void printascii(const char *);
        char buf[256];
        va_list ap;

        va_start(ap, str);
        vsnprintf(buf, sizeof(buf), str, ap);
        va_end(ap);

#ifdef CONFIG_DEBUG_LL
        printascii(buf);
#endif
        printk("%s", buf);
}

arch/arm/kernel/Makefile

obj-$(CONFIG_DEBUG_LL)  += debug.o

arch/arm/kernel/debug.S

#include CONFIG_DEBUG_LL_INCLUDE

                .macro  addruart_current, rx, tmp1, tmp2
                addruart        \tmp1, \tmp2, \rx
                mrc             p15, 0, \rx, c1, c0
                tst             \rx, #1
                moveq           \rx, \tmp1
                movne           \rx, \tmp2
                .endm

ENTRY(printascii)
                addruart_current r3, r1, r2
                b       2f
1:              waituart r2, r3
                senduart r1, r3
                busyuart r2, r3
                teq     r1, #'\n'
                moveq   r1, #'\r'
                beq     1b
2:              teq     r0, #0
                ldrneb  r1, [r0], #1
                teqne   r1, #0
                bne     1b
                ret     lr
ENDPROC(printascii)
⚠️ **GitHub.com Fallback** ⚠️