VELT-0.1.5 development: Using kgdb to debug Linux kernel, velt-0.1.5kgdb
VELT is short for Visual EmbedLinuxTools. It is a visual studio plug-in similar to visual gdb to assist in Linux development. With this plug-in, you can develop Linux applications (including compilation and debugging) in visual studio IDE, or compile uboot and Linux kernel, the source code is correctly located based on the error information during compilation. The current version is 0.1.4 and only vs2013 is supported. This plug-in can be downloaded in the CSDN download channel (http://download.csdn.net/detail/lights_joy/8429771), the installation process see with vs2013 + velt-0.1.4 for Embedded Development: plug-in installation. The basic functions are as follows:
Supports x86 Linux, hith hi3516, hi3520, and MinGW platforms, and provides project templates for these platforms.
Complete UBOOT compilation and automatically locate the corresponding file location based on the Compilation error information.
Complete the Linux kernel compilation and automatically locate the corresponding file location based on the Compilation error information.
Complete Linux Kernel configuration in.
Do not use Makefile to compile Linux applications.
Use Makefile to develop Linux applications.
Use SSH to connect to the target machine and debug the application with gdb.
Use Telnet to connect to the target machine and debug the application with gdb.
Integrate the Linux terminal (Poderosa) in VS and support SSH, Telnet, and Com. When the terminal is opened, the VS variables are automatically exported as bash variables, such as ProjectDir.
Next, try to debug the Linux kernel through a serial port.
The test object is hi3520 kernel.
1.1 enable the kernel debugging Switch
First turn on the kernel debugging switch:
Add the kernel debugging information:
Open kgdb
1.2 boot parameter configuration
Configure the parameters passed to the kernel in UBOOT:
Kernel command line: mem = 127 m console = ttyAMA0, 115200ip = 192.168.110.10 ::: 255.255.255.0 :: eth0: root = mtd: work02 init =/sbin/initmtdparts = hi_sfc: 256 K (uboot01), 64 K (env01), 64 K (sysinfo01), 3712 k (configs01), 8 M (boot01), 20 M (work01 ), 256 K (uboot02), 64 K (env02), 64 K (sysinfo02), 3712 k (configs02), 8 M (boot02), 20 M (work02) kgdboc = ttyAMA0, 115200 kgdbwait
The most important parameters here are kgdboc and kgdbwait. The first parameter specifies the serial port parameter to be used, and the last parameter allows kgdb to wait during kernel startup.
Load the kernel:
Kgdb: Registered I/O driver kgdboc.
Kgdb: Waiting for connection from remote gdb...
Then the system starts to wait.
1.3 Use MinGW gdb to connect to the kernel
Use MinGW gdb to open the vmlinux file generated during kernel compilation,
Then use
Target remote COM1
Connection to the serial port. Sorry, it timed out!
1.3 modify the kernel code
After checking the kernel code, the kernel stops at the following position while waiting for the connection:
static int gdbstub_read_wait(void){int ret = dbg_io_ops->read_char();while (ret == NO_POLL_CHAR)ret = dbg_io_ops->read_char();return ret;}
It will constantly query the serial port for data. At the beginning, it is suspected that the serial port parameter configuration is incorrect, leading to the failure to read data, but after tracking it, we found that read_char can correctly call the query function in the serial drive (amba-pl011.c:
static int pl010_get_poll_char(struct uart_port *port){struct uart_amba_port *uap = (struct uart_amba_port *)port;unsigned int status, ena_status;status = readw(uap->port.membase + UART01x_FR);ena_status = readw(uap->port.membase + UART011_CR);if (status & UART01x_FR_RXFE)return NO_POLL_CHAR;return readw(uap->port.membase + UART01x_DR);}
However, when reading the UART01x_FR register, no data is always returned.
Further checks show that the serial port reception enabling function is disabled at this time, while the sending enabling function is enabled! Therefore, the serial port can only send data and cannot receive it!
I don't quite want to figure out why it is like this. Open the receive enable directly in the shutdown function:
static void pl011_shutdown(struct uart_port *port){struct uart_amba_port *uap = (struct uart_amba_port *)port;/* * disable all interrupts */spin_lock_irq(&uap->port.lock);uap->im = 0;writew(uap->im, uap->port.membase + UART011_IMSC);writew(0xffff, uap->port.membase + UART011_ICR);spin_unlock_irq(&uap->port.lock);pl011_dma_shutdown(uap);/* * Free the interrupt */free_irq(uap->port.irq, uap);/* * disable the port */uap->autorts = false;writew(UART01x_CR_UARTEN | UART011_CR_TXE | UART011_CR_RXE, uap->port.membase + UART011_CR);/* * disable break condition and fifos */pl011_shutdown_channel(uap, uap->lcrh_rx);if (uap->lcrh_rx != uap->lcrh_tx)pl011_shutdown_channel(uap, uap->lcrh_tx);/* * Shut down the clock producer */clk_disable(uap->clk);if (uap->port.dev->platform_data) {struct amba_pl011_data *plat;plat = uap->port.dev->platform_data;if (plat->exit)plat->exit();}}
Modified this line:
writew(UART01x_CR_UARTEN | UART011_CR_TXE | UART011_CR_RXE, uap->port.membase + UART011_CR);
The original code is as follows:
writew(UART01x_CR_UARTEN | UART011_CR_TXE, uap->port.membase + UART011_CR);
Add the Enable mark directly to it!
Execute the target remote COM1 command of gdb. The connection is normal !!
1.5 kdb
Kdb support has been included in the HI3520 kernel:
Kdb will be enabled when the bottom option is selected, so that we can execute some simple Debugging commands on the target machine without relying on gdb on the host.
However, because we want to debug through gdb combined with the source code, we do not select kdb, but only use kgdb.