enabling low level debuging in kernel on serial port - linux

I am compiling a linux distribution(openwrt) for beaglebone-black and getting the following o/p on my serial port
uncompressing Linux....done,booting the kernel(kernel hangs) in order to trace the error i have enabled CONFIG_DEBUG_LL=y(enables the low level debuging) and CONFIG_DEBUG_INFO=y(enables kernel debug information) but i found CONFIG_DEBUG_LL_UART_NONE=y so if i am correct this means the platform does not support UART debugging(even though kernel is giving the information i might not be seeing that) so is there any other way to debug the kernel or enable the serial port on beagle bone black? if any 1 can guide me through that it would be a great help.....
thanks,

If you have a debugger, then you can certainly debug why your kernel is not booting up.
Assuming, you have one, do the following:
In Kernel configuration, enable CONFIG_DEBUG_INFO (Kernel Hacking ->
Compile-time checks and compiler options)
Compile the kernel
From the debugger software, load the symbols from the elf. The
command varies from one debugger to another
Find symbol "log_buf", and chose option to "Display memory as dump"
There you can see the kernel logs that are not yet printed but stored in the buffer. Hope it helps!

Related

How can I debug kernel module running on a virtual machine?

I think I have once read about this but can't find it now.
I'm running linux-5.4.188 on a qemu arm64 virtual machine. Because I built the kernel from the source, I can debug(analyze) the kernel by attaching to the linux kernel program running on a remote machine(qemu virtual machine). To test an application which uses our device(the device model is in qemu too), I compiled a device driver against kernel 5.4.188 and the linux application and can do insmod the driver and run the application.
Now something is wrong and I have panic while running the application. I can debug linux kernel itself, but I don't know where the kernel module was loaded, so the debugger cannot debug the driver module. How can I debug the device driver? (or even the application? in case I need to someday). I remember by first getting the loaded address of the kernel module, and doing add-symbol-file for the driver image relative to that loaded address, it is possible to do kernel module debug. I think this is what driver developers will be doing always. Please tell me how I can do it. If this is possible, it will save many days for me.
As Ian Abbott said I use printk for kernel debugging. Usually for this I put his this line in /etc/sysctl.conf. (for ubuntu-20.04 case. I'm not sure it's applicable to vanila linux too)
kernel.printk = 5 4 1 7
The first value is the console log level and the second value is default log level. By making default 4 (WARNING) and console log level 5 (NOTICE), every default printk appears in the console (because 5 is higher thatn 4, less value is more important and more important messages than the console log level gets printed in the console. see How can I show printk() message in console?).
This way you don't have to check with dmesg everytime. You can see the kernel __log_buf before the serial port is initialized in setup_arch function in start_kernel. The kernel message are written in memory called __log_buf before serial port is initialized.
I refered to https://www.kernel.org/doc/html/latest/dev-tools/gdb-kernel-debugging.html that stark pointed me to and I also found https://wiki.st.com/stm32mpu/wiki/Debugging_the_Linux_kernel_using_the_GDB very useful.
Important things during the kernel config :
set CONFIG_GDB_SCRIPTS=y, CONFIG_DEBUG_INFO_REDUCED=n, CONFIG_FRAME_POINTER=y.
I use nokaslr in the kernel command line, but added CONFIG_RANDOMIZE_BASE=n to make sure.
Now the part I originally wanted to know from my question :
In the shell (in virtual machine linux shell) do,
$ls -la /sys/module/<module_name>/sections
Then you'll see files like .text, .data, .bss, etc. You cd to that directory and do
$cat .text .data .bss
To see the address of each section. In my case,
/sys/module/axpu_ldd_kc/sections # cat .bss .data .text
0xffff800008ca5480
0xffff800008ca5000
0xffff800008ca0000
and in the gdb, (after stopping the program by ctrl-c) I did
add-symbol-file ~/testlin540/axpu_ldd_kc.ko 0xffff800008ca0000 -s .data 0xffff800008ca5000 -s .bss 0xffff800008ca5480
and I tried setting breakpoint at my ioctl function.
(gdb) b axpu_ioctl
and when I pressed c (continue) and when I started my application, I could see the program stop at the axpu_ioctl and I could single step through the code and see the values.
When I did kernel debug for booting using u-boot recently, I frequently wrapped a function with
#pragma GCC push_options
#pragma GCC optimize ("O0")
and
#pragma GCC pop_options
To prevent some parts of the codes from being optimized away. (sometime you should do it for the related #include <xxx.h> statement too to prevent compile error).

How to add printk functions while the kernel boot up

I need to find a problem of a third party hypervisor which leads the kernel boot failure in the AHCI disk driver boot process.
So, is there any way to add print boot up message while kernel boot up? The kernel boot process is failure, so it is impossible to see printk information after system boot.
How to debug kernel, while the system boot up, thanks
Following are some suggestions you can try out:
Enable CONFIG_EARLY_PRINTK found in Kenrel hacking -> Kernel low-level debugging functions menuconfig option
If you have UART debug access, select appropriate UART port for early printk
Boot your kernel with additional debug arguments likes debug earlyprintk
You can also try adding some prints in do_initcall_level() found in init/main.c. To print the name of the function pointer, you can use printk with %pS format specifier. More details on format specifiers for printk can be found here: https://www.kernel.org/doc/Documentation/printk-formats.txt
Hope this helps!

Where could I find the oops info from kernel logs

I am a newer of driver development. I have configured my linux kernel according to the Linux Device Driver chaper 4, enabled a lot of debug configuration. When I try to test a driver written by me, the kernel issues an oops. This oops, however, immediately flushed by chunks of other debug information. So, where could I find out the oops info which occurred in a flash.
By the way, can anyone explain the meaning of debug information below?
[ 1698.129712] evbug: Event. Dev: input0, Type: 0, Code: 0, Value: 0
This type of message flushed by screen and I even can't stop them.
To avoid a lot of useless information (in your case) you have to enable only and only what you really need to debug your module. I highly recommend to disable everything you enabled back. Then case-by-case you may enable debug features.
Next, there is a nice framework in kernel called Dynamic Debug. It allows at runtime enable or disable certain debug messages (be sure you have CONFIG_DYNAMIC_DEBUG=y in the Linux kernel configuration). More detailed description is available in Documentation/dynamic-debug-howto.txt.
evbug is a module to monitor input events in the kernel. There is one of the message it can issue. It's very simple one you may check at drivers/input/evbug.c. Unfortunately, it uses printk() calls directly and you can't manipulate its output through dynamic debug.
At the end the answer to your topic question is check output of dmesg command. But be aware that the kernel buffer for output is small enough and if you have a lot of logs you may miss some of them.

Getting Linux Serial Console working on imx31

I have just ported uboot and the linux kernel to my imx31 based board. The kernel boots up because I can see the kernel messages in the ring buffer in ram, but I am not seeing and text on the serial port after ... decompressing kernel, done, booting kernel"
I am passing "console=ttySMX0,115200" on the kernel arguement line, but I am not seeing the serial device being probed by the kernel (the serial driver is being registered, but no probe is happening).
I don't understand the relationship between the serial console name "ttySMX" and what the kernel expects.
I have built the kernel under openembedded with support for the LogicPD liteboard and Freescale ADS31 board, as these are closest to my board.
Any help much appreciated ... I have been trying to get this going for two weeks.
Amongst other things need to have both CONFIG_SERIAL_IMX and CONFIG_SERIAL_IMX_CONSOLE selected in your kernel configuration.
It's possible these tags could have other names in your build. In the one I looked at, they were referenced in driver/tty/serial/imx.c - if there is a different file that embodies the driver in your build, look for similar options in its source and in the Makefile in that directory.

ARM linux and cross toolchain issue

I have a problem probably with my arm toolchain but maybe there's something other that I do wrong. I have Chinese made dev board qq2440 using Samsung s3c2440 ARM9 uC. I'm using Ubuntu x86 with native gcc(4.3.3) and cross-compile version arm-unknown-linux-uclibc-gcc (crosstool-NG-1.3.2) 4.3.2
I followed tutorials from http://blog.leshak.ru/english/pages/how-to-install-u-boot-linux-2629-rootfsjffs2-busybox-1132-into-nand-qq2440/
and used Leshak's kernel patches for that board. Problem is that his binaries work perfectly and mine don't...
I communicate with my board over RS232 (serial port) and I have serial terminal configured on target Linux. I use Leshak's uboot image. To configure my kernel I use following command line:
qq2440> setenv bootargs 'noinitrd root=/dev/mtdblock2 rootfstype=jffs2 rw console=ttySAC0,115200'
For target I use vanilla Linux sources version 2.6.29, with patches created by Leshak. I don't honestly believe that this will ever be supported officially by Linux as it's not mainstream product.
My kernel image starts booting up, but it probably changes bandwidth (or CPU frequency) to some non standard value (tried all standard ones already). Instead of dots indicating loading kernel into memory I've got only trash instead. Unfortunately it doesn't probably finish the boot process as the network interface nor file system don't come up. So I figured out that it panics somewhere in the middle.
Any ideas what should I do next?
Thanks & regards,
Chris
There are a lot of different things that could be going on here.
It sounds like you are talking about a serial port, and that it appears to be giving garbage once control is passed to the kernel from uboot. Am I understanding that correctly?
Look into specifying the baud rate, parity, etc. for the serial console on the kernel commandline.
Oh, and IIRC, there was some 'early_printk' thing in the ARM Linux tree that might help you debug serial console problems. (But I'll warn you -- it's been a couple years since I dealt with that so my memory is fuzzy.)
Double-check that the memory address layout (the locations of all the various devices) matches what your board has. (I think this is probably not the issue, but wanted to mention it for completeness.)
You say that you have a binary kernel that works correctly; compare the kernel config of that kernel to the config you are using for building your kernel. Investigate every difference, particularly any specific to ARM.
You may want to double-check the endianness of your toolchain vs what your board is expecting. Some of the ARM / XScale processors can be configured to big-endian or little-endian in software, so it might be worth double-checking.
Just enable the debug build of the kernel[while building the uImage] so that you get a more clearer picture of the scenario [Just would make your boot up somewhat slow since all the printk's would be enabled].
Can you check whether you are passing the correct parameters to the UART ie. Serial Port Name, it's baud rate etc This would be provided by the board manufacturer-Samsung
WRT the network instead of DHCP can you just assign a static ip address to your system as it might be possible that the DHCP process is still not ON.
Also a better option would be to use NFS but yeah, it depends on your choice and the purpose of your application. To use NFS, your network should be UP & running and your filesystem should be shared.
As retracile has already pointed out "Endianness" could be a point to look into !!!
You can refer this link which might help you out since it is specific to S3C2440
Hope this helps.
-hjsblogger
I had a similar problem at one point when I omitted --send-cmd from picocom. this is the command I issue to picocom for serial uBoot comms with the mini2440.
picocom -b 115200 /dev/ttyS0 --send-cmd "sx -vv"

Resources