We need to enable the RX function of the jz4740 pin for GPIO Port D for serial RX, instead of a keyboard line. But we need to do that at boot time, before kgdbwait.
I used this command line, enabling also kgdb in the kernel (also kdb):
CONFIG_CMDLINE="mem=32M console=tty0 ubi.mtd=2 rootfstype=ubifs root=ubi0:rootfs rw rootwait kgdboc=ttyS0,57600 kgdbwait kgdbcon"
I had to build the kernel with a special patch, to enable the ttyS0 RX signal instead of the keyboard gpio line. It was this patch. I tried to guess what code would map to the PDFUNCS register described in the manual.
diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c index f2d94c1..48289f5 100644 --- a/arch/mips/jz4740/board-qi_lb60.c +++ b/arch/mips/jz4740/board-qi_lb60.c @@ -442,6 +442,7 @@ static void __init board_gpio_setup(void) * drivers. Everything else is done by the drivers themselves. */ jz_gpio_disable_pullup(QI_LB60_GPIO_SD_VCC_EN_N); jz_gpio_disable_pullup(QI_LB60_GPIO_SD_CD); + jz_gpio_set_function(JZ_GPIO_UART0_RXD, JZ_GPIO_FUNC_UART0_RXD); }
As explained in kgdb doc, kgdbcon allows me to see the printk in gdb. And kgdbwait blocks the boot at an early stage. Specifically, at this point:
NAND Secondary Program Loader [U] pressed, goto USBBOOT mode Ben NanoNote GPIO, clocks, SDRAM, UART setup now jump back to BOOT ROM... ziess 80010000 Nkernel... the kernel... [ 0.000000] Linux version 3.2.0prova-86406-g986a58a-dirty (viric@bergamota) (collect2: ld returned 1 exit status) #12 PREEMPT Wed Jan 11 23:32:39 CET 2012 [ 0.000000] bootconsole [early0] enabled [ 0.000000] CPU revision is: 0ad0024f (Ingenic JZRISC) [ 0.000000] Determined physical RAM map: [ 0.000000] memory: 02000000 @ 00000000 (usable) [ 0.000000] User-defined physical RAM map: [ 0.000000] memory: 02000000 @ 00000000 (usable) [ 0.000000] Zone PFN ranges: [ 0.000000] Normal 0x00000000 -> 0x00002000 [ 0.000000] Movable zone start PFN for each node [ 0.000000] early_node_map[1] active PFN ranges [ 0.000000] 0: 0x00000000 -> 0x00002000 [ 0.000000] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 8128 [ 0.000000] Kernel command line: mem=32M console=tty0 ubi.mtd=2 rootfstype=ubifs root=ubi0:rootfs rw rootwait kgdboc=ttyS0,57600 kgdbwait kgdbcon [ 0.000000] PID hash table entries: 128 (order: -3, 512 bytes) [ 0.000000] Dentry cache hash table entries: 4096 (order: 2, 16384 bytes) [ 0.000000] Inode-cache hash table entries: 2048 (order: 1, 8192 bytes) [ 0.000000] Primary instruction cache 16kB, VIPT, 4-way, linesize 32 bytes. [ 0.000000] Primary data cache 16kB, 4-way, VIPT, no aliases, linesize 32 bytes [ 0.000000] Memory: 27616k/32768k available (3140k kernel code, 5152k reserved, 1060k data, 176k init, 0k highmem) [ 0.000000] NR_IRQS:190 [ 0.000000] Console: colour dummy device 80x25 [ 0.000000] console [tty0] enabled, bootconsole disabled Entering kdb (current=0x81c188c8, pid 1) due to Keyboard Entry kdb>
Then we can start gdb:
$ mipsel-unknown-linux-gdb vmlinux GNU gdb (GDB) 7.3.1 Copyright (C) 2011 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "--host=x86_64-unknown-linux-gnu --target=mipsel-unknown-linux". ---Type <return> to continue, or q <return> to quit--- For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /home/viric/3rd/qi-kernel/vmlinux... done. (gdb) set remotebaud 57600 (gdb) target remote /dev/ttyUSB0 Remote debugging using /dev/ttyUSB0 0x8001cc68 in arch_kgdb_breakpoint () at arch/mips/kernel/kgdb.c:200 200 __asm__ __volatile__( (gdb) break jz_nand_probe Breakpoint 1 at 0x803192b0: file drivers/mtd/nand/jz4740_nand.c, line 404. (gdb) c Continuing. [ 0.600000] brd: module loaded Breakpoint 1, jz_nand_probe (pdev=0x8040d850) at drivers/mtd/nand/jz4740_nand.c:404 404 { (gdb) .... listing ... (gdb) 459 /* We are going to autodetect NAND chips in the banks specified in the 460 * platform data. Although nand_scan_ident() can detect multiple chips, 461 * it requires those chips to be numbered consecuitively, which is not 462 * always the case for external memory banks. And a fixed chip-to-bank 463 * mapping is not practical either, since for example Dingoo units 464 * produced at different times have NAND chips in different banks. 465 */ 466 chipnr = 0; 467 for (bank_idx = 0; bank_idx < JZ_NAND_NUM_BANKS; bank_idx++) { 468 unsigned char bank; (gdb) until 467 platform_set_drvdata (data=0x81cf2800, pdev=0x8040d850) at drivers/mtd/nand/jz4740_nand.c:467 467 for (bank_idx = 0; bank_idx < JZ_NAND_NUM_BANKS; bank_idx++) { (gdb)
Usually there is no way to print local variables, because the kernel is built with -O2. This means that you have to rely on some static variables for debugging, or have a good virtual machine in your brain for the assembler gdb is going to show to you on 'disasm'.
A good explanation about the kernel built on -O2 (set on the root Makefile, KBUILD_CFLAGS += -1), you can find throughout this lkml thread - Building Kernel with -O0.
I don't know how to print local variables though. It looks like not working for me:
(gdb) print chip No symbol "chip" in current context. (gdb) print nand No symbol "nand" in current context. (gdb) print pdata No symbol "pdata" in current context.
SYSRQ - sysreq - system request
Typing KEY_LEFTALT and KEY_SYSRQ at once brings you the sysrq possibilities. If you want to break at any point with an attached gdb, or you want to trigger kgdb, you can use the combination sysrq-g (Remember that sysrq-h shows the help).
I used this patch, that changes the KEY_F8 key for KEY_SYSRQ in the nanonote keyboard:
--- a/arch/mips/jz4740/board-qi_lb60.c +++ b/arch/mips/jz4740/board-qi_lb60.c @@ -200,7 +200,7 @@ static const uint32_t qi_lb60_keymap[] = { KEY(5, 5, KEY_QI_QI), /* S47 */ KEY(5, 6, KEY_RIGHTCTRL), /* S48 */ KEY(5, 7, KEY_LEFT), /* S49 */ - KEY(6, 0, KEY_F8), /* S50 */ + KEY(6, 0, KEY_SYSRQ), /* S50 */ KEY(6, 1, KEY_P), /* S51 */ KEY(6, 2, KEY_BACKSPACE),/* S52 */ KEY(6, 3, KEY_ENTER), /* S53 */
Then I could use ALT-F8 in the keyboard as a SYSRQ key. ALT-F8, and then H without releasing the ALT, showed the help in the console. In my case, tty0. ALT-F8, G started kgdb.
kgdb and kdb
If you compiled both in, typing "kgdb" in "kdb>" will make the kernel wait for a gdb to attach. If you know that the kernel is in kgdb mode, then you can type $3#33 (or check the proper manual for more information).