Debugging the Linux Kernel on Boot - linux

I have compiled the Linux kernel with configuration options for ROOT_NFS. My problem now is the screen prints to fast for me the see the error and I cannot find any documentation on the best approach to solve this problem. I am performing this in VirtualBox.

There is Documentation/serial-console.txt you could look into. Serial console has traditionally been used for debugging linux boot problems, where you then can save all of the screen capture on a different pc. This should be possible for a virtualbox use case as well, although I do not know how difficult it will be to configure serial access.

The dmesg command prints the kernel's circular log buffer. Your messages may be in there.

Related

How do I turn off the console on an embedded system built with Yocto?

I am running Linux kernel 4.14.149 built by Yocto Zeus, and I am running 2019.07 U-boot. At the recommendation of our security team, I am trying to get rid of the Linux console. I am not worried about debugging (once I get this to work anyways); we have other ways of getting the system logs out of the machine, and this will not be done on software development boards. That mechanism is already in place and is tested working. We have an i.MX6 as our core (this is an embedded system), and we have dedicated UART5 to our console on dev boards.
I have tried a few different methods to do this. The first was to disable the framebuffer console kernel config (CONFIG_FRAMEBUFFER_CONSOLE). The primary issue with this approach is that it disabled the splash screen. We have a splash screen that is put up in U-boot (and it is displayed again by Linux), but Linux appears to reset the framebuffer or something when it is booting, resulting in the display flickering and being blank for a bit before our applications start, which was unacceptable (and is the reason we put the splash screen up in both U-boot and Linux).
I also tried just setting "console=" on our command line. This is close to what we want to achieve in that the console doesn't come out the UART anymore, but we see it start to appear on the display on top of the splash screen. I haven't found any way to fix that (I can upload a screenshot if desired).
Just eliminating the console parameter entirely didn't appear to work, it still came out the UART. This is to be expected based on the serial console documentation which says it just uses the first available device.
I have tried commenting out the console initialization in main.c in the Linux source, which exploded rather quickly.
I tried setting to be a netconsole (see Where do you send the kernel console on an embedded system?) but the splash screen still got overwritten, same as the setting it nothing case.
The last thing I have tried was just setting it to a bogus device ("console=ttymxc9" on the Linux command line). While this appears to work (there is no data on the display or the UART) it appears to stall (crash?) partway through bootup and without being able to get the logs (it stalls before our application service runs). I say stall because we have Linux configured for a heartbeat and we do still get proper LED heartbeat behavior. None of the systemd services I added to our build however appear to run (I added one to save the journalctl log file after boot to a file on an external SD card for debugging purposes until I get this working)
At this point, I have run out of ideas on how to get rid of the console while keeping the splash screen intact. What is the proper way to disable the Linux console?
For kernel versions 5.11 and newer:
In the submenu "Character devices" under "Device Drivers" from make menuconfig, there is an option called "Null TTY driver" (CONFIG_NULL_TTY) that you can enable and add console=ttynull to the kernel boot cmdline so that all console output will be simply discarded.
You can also disable CONFIG_VT and CONFIG_UNIX98_PTYS, since you don't need to interact with your program via console at all.
For older kernels (like my 4.14):
You can add this support with the diffs at: https://lore.kernel.org/lkml/20190403131213.GA4246#kroah.com/T/ and then follow the instructions above.
More recent versions of yocto use systemd and a service called getty.target to load the serial port console. Disable by running the following command (once):
systemctl mask getty.target
This answer may not fully fit your question, however, it could serve as a research source for other users, just like me. I use the commands below to temporarily turn the console (ttyS0) on and off.
systemctl stop serial-getty#ttyS0.service
and
systemctl start serial-getty#ttyS0.service

debugging Device driver using GDB

I'm new to device drivers in Linux. And my first day task is to debug driver using GDB in Linux.
I need to debug some XYZ (PCIe device driver supports ethernet) device driver to know about the flow and what is going on device's registers and all.
I have installed the driver with patch file and insmod command.
The device is working properly. But am not getting any solution to debug the device driver.
All I know is that how to debug C program using GDB in Linux(fedora20). I got one link similar to my Problem but from that also I have not got any knowledge.
Can anybody please share your thoughts that how can I start from scratch.
I am very specific to learn about Debugging device drivers in Linux. Especially that init or probe function inside my driver I need to know the flow.
The gdb debugger is useful to debug user-space application level programs (since it uses ptrace(2)).
For kernel code, things are different. Consider using kgdb (I don't know the details). You might also add debug prints ....
I recommend at least reading more about operating systems, e.g. Operating Systems: Three Easy Pieces (freely downloadable), and reading something about Linux programming (perhaps the old ALP, and also intro(2), syscalls(2) and related stuff). Don't dare coding Linux loadable kernel modules without good familiarity with Linux programming (in user-land). See also kernelnewbies.
BTW, you should prefer writing user-land code than kernel modules. A very simple rule of thumb is to avoid writing kernel code when possible.
To begin with, you may need to understand basics of device driver and kernel in linux. Subsequently focus as per the type of driver in-hand. You also need to understand the functionality (specification / manual / datasheet) of the device you are working on.
The very basic approach for debugging can be using printk. Normally there will be debug logs that can be enabled through compilation flags. If it is present, enable it so that it can give important pointers else you might need to add it on your own.
Start with verification of driver registration and verification of loading of your driver (static or loadable module as per your requirement). Check whether it is getting listed as part of sysfs or proc as applicable. Check whether probe is successful and subsequently the appropriate read/write/open/close/other calls as per your driver / device functionality.
The dmesg shall be very helpfull for viewing the kernel messages. There are also tools like kdb, LTT, strace that can be useful as per the scenario.

How they do debugging Linux Kernel Core

Now a days debugging become so advanced that even 'core kernel source code' can be debugged using Virtual environment.
But after reading couple of blog related to Kernel Core development it was not clear whether they are debugging using Virtual environment.
They have mentioned that they rely on 'Printing message' rather than using debugging tool, at-least for core component.
So, I Request from 'Linux Kernel Experts' to let me know what is good practice followed while debugging Kernel?
I've tried multiple approaches when trying to debug the kernel.
Sometimes, the easiest way is to just add a few printk statements based on my own conditional values, monitor the serial log and see what's going on. Its especially useful when the function in question is invoked quite often, but you are interested only in a subset of those.
QEMU GDB debugging. I have a buildroot filesystem setup. This means the kernel is lean and it boots up real fast. I start qemu with the -s -S flags, and attach gdb as target remote :1234. Additionally, there aren't very many userspace processes in this setup so its easier to debug the kernel.
VMWare stub. Assuming you are running an Ubuntu VM, it is possible that you can attach gdb to a VMware stub and debug the kernel. Personally, I never have had to pursue this route, but I look forward to trying it out someday.
If you have a kernel for a device that gets stuck in a bootloop and it does not print out any debug information out onto serial, it still might be helpful to try and boot it up using QEMU. Sure, the booting up will probably fail as the kernel tries to load up drivers, but you should be able to attach gdb, get a stack trace and see what the root cause is(perhaps a recursive call).

Switching into (Linux) Kernel Mode

Linux n00b here. How does one switch from User Mode to Kernel Mode? I'm running Linux Ubuntu 12.10. Is there an interrupt that I can call using inline assembly code that will do this? If not, how can it be done?
I'm asking this question because I am wishing to write a SCTP (network)protocol stack which has access to the kernel and runs in the background constantly though the UI cannot directly access the kernel. Never done anything like this before so tips from pros would definitely be appreciated.
All switches to kernel mode are made via system calls. In the case of network protocols these system calls are socket, listen, accept, ioctl, read, write, recvmsg, etc.
You write a Linux kernel module. There is already a SCTP protocol stack for Linux though. You would likely be better off modifying it to do what you want.
Once you have written and compiled your module you can load it into the kernel using insmod and rmmod. In my experience you rarely get a chance to use rmmod because if you made a mistake the system crashes or freezes. So use a virtual machine for your testing. It is faster to reboot, you lose less data, and it is easier to hook up a virtual serial console for debugging.
I am sure this question is a duplicate by the way. You can find a lot of questions on this topic.

Current Linux Kernel debugging techniques

A linux machine freezes few hours after booting and running software (including custom drivers). I'm looking a method to debug such problem. Recently, there has been significant progress in Linux Kernel debugging techniques, hasn't it?
I kindly ask to share some experience on the topic.
If you can reproduce the problem inside a VM, there is indeed a fairly new (AFAIK) technique which might be useful: debugging the virtual machine from the host machine it runs on.
See for example this:
Debugging Linux Kernel in VMWare with Windows host
VMware Workstation 7 also enables a powerful technique that lets you record system execution deterministically and then replay it as desired, even backwards. So as soon as the system crashes you can go backwards and see what was happening then (and even try changing something and see if it still crashes). IIRC I read somewhere you can't do this and debug the kernel using VMware/gdb at the same time.
Obviously, you need a VMM for this. I don't know what VMM's other than VMware's VMM family support this, and I don't know if any free VMware versions support this. Likely not; one can't really expect a commercial company to give away everything for free. The trial version is 30 days.
If your custom drivers are for hardware inside the machine, then I suppose this probably won't work.
SystemTap seems to be to Linux what Dtrace is to Solaris .. however I find it rather hostile to use. Still, you may want to give it a try. NB: compile the kernel with debug info and spend some time with the kernel instrumentation hooks.
This is why so many are still using printk() after empirically narrowing a bug down to a specific module.
I'm not recommending it, just pointing out that it exists. I may not be smart enough to appreciate some underlying beauty .. I just write drivers for odd devices.
There are many and varied techniques depending on the sort of problems you want to debug. In your case the first question is "is the system really frozen?". You can enable the magic sysrq key and examine the system state at freeze and go from there.
Probably the most directly powerful method is to enable the kernel debugger and connect to it via a serial cable.
One option is to use Kprobes. A quick search on google will show you all the information you need. It isn't particularly hard to use. Kprobes was created by IBM I believe as a solution for kernel debugging. It is essentially a elaborate form of printk() however it allows you to handle any "breakpoints" you insert using handlers. It may be what you are looking for. All you need to do is write and 'insmod' a module into the kernel which will handle any "breakpoints" hit that you specify in the module.
Hope that can be a useful option...
How I debug this kind of bug, was to run my OS inside the VirtualBox, and compile the kernel with kgdb builtin. Then I setup a serial console on the VirtualBox so that I can gdb to the kernel inside the VirtualBox's OS via the serial console. Anytime the OS hang, just like magic sysrq key, I can enter ctrl-c on the gdb to stop and understand the kernel at that point in time.
Normally kernel stack tracing is just too difficult to pinpoint the culprit process, so the best way I think is still generic "top" command, just looking at the application logs to see what are the cause of hanging - this will need a reboot to see the log of course.

Resources