What can I use to debug/trace step-by-step Freebsd kernel booting process on Pandaboard? - arm

To start with - I don't have JTAG hardware debugger.
What I have:
Pandaboard and serial-USB cable to connect to console and my computer with Freebsd and GNU/Linux distribution.
What I'm looking for
- convinient way to trace/debug bootprocess inside FreeBSD kernel ( I'm mostly interested in this fragment: https://github.com/freebsd/freebsd/blob/master/sys/arm/arm/locore-v6.S and https://github.com/freebsd/freebsd/blob/master/sys/arm/arm/mp_machdep.c as I'm, going to modyfy those files ).

Based on my experience, there are few ways:
KDB / DDB: add call kdb_enter("A", "XYZ") to stop processing and enter interactive debug mode of DDB via serial.
printf-s in machine dependent (mach_dep) code
bootverbose, BUSDEBUG, VERBOSE_SYSINIT in machine independent code
Also it's worth to mention that DDB code contains functions to print registers, stack trace and etc.

Related

I2C-Bus Implementation on Linux (Raspberry Pi)

I have recently written numerous functions in C for microfluidic pumps which are controlled via I2C on a Raspberry Pi. They work perfectly. I made use of the O_RDWR to write and read from "/dev/i2c-1".
However, I am still wondering how exactly these file changes are implemented on a low level. How is the code, which generates the correct bit sequences to communicate with these pumps, transferred to the PINs? What tells the kernel to change the states of the 2 I2C-PINs accordingly to code?
Thank you!
In most cases, software is not directly responsible for generating each individual logic level change. Instead, it is a combination of a hardware based I2C controller, that is managed from software by a driver.
In the case of your RPi, you are most likely using this driver:
https://elixir.bootlin.com/linux/v5.19/source/drivers/i2c/busses/i2c-bcm2835.c
The hardware block that this driver is controlling is described in section 3 of this reference manual:
https://www.raspberrypi.org/app/uploads/2012/02/BCM2835-ARM-Peripherals.pdf
(A side note: the kernel does know how to generate all logic changes in software as well, for cases where no dedicated hardware is available. If you want to know more about that, have a look at the i2c-gpio driver)

Tracing Kernel mode (privileged) instructions in Qemu

I am trying to write a Qemu TCG plugin to recognize if an instruction is executed in user mode or in kernel mode for a basic program.
I understand that a full system emulation is needed for the same. I wrote a TCG plugin, registering two Qemu callbacks qemu_plugin_register_vcpu_syscall_cb and qemu_plugin_register_vcpu_syscall_ret_cb. I am using the target arm-softmmu for full system emulation (and then the corresponding qemu-system-arm). I can see that there are svc calls in the user mode but I do not get any kernel-mode instructions. Any idea on what might be happening?

How to debug Bootloader Qemu ARM?

I'm trying to boot a kernel (extracted from a firmware) using QEMU.
Qemu emulation seems to start at 0x0.
The problem is that the memory from 0x0 to 0x04000000 is only filled with 0.
How can i debug the bootloader?
You don't say what your command line is. The address where QEMU starts execution depends on many things:
the guest CPU architecture
which board model you are emulating
whether you passed QEMU a BIOS image file
the file format of any file passed to -kernel (ELF, plain kernel image, uImage, etc)
In general, though, you should not expect to be able to pull a random kernel image out of a firmware dump for a piece of Arm hardware and run it under QEMU. This is because every Arm board or machine is different -- RAM may be in different places, the devices such as the serial port are at different addresses, and so on -- and the kernel will only boot on systems which it has been compiled to support. The chances are very high that (a) QEMU does not have a specific emulation of the bit of hardware that the firmware dump is for and (b) the kernel from the firmware has not been built to also run on any of the board types that QEMU does support. So it will almost certainly simply crash very early on in bootup without producing any output.
If you want to debug what's going on in early bootup, the best approach is probably to use QEMU's built in gdbstub, and attach a guest-architecture-aware gdb to it. You may also find QEMU's internal logging via the '-d' option useful, though it requires some familiarity with how QEMU works to make sense of the output.

Debug Linux kernel in a board without GDB

I am totally a fresh on an assignment of developing a driver on a board, which uses a "small" Linux. Every time I make everything and get a ".bin" file on PC and then ftp ".bin" to the board, the system will just work.
Now the problem come. I checked the system, it can not use gdb. So when the system crash, it will just provide a core dump file, which gives messy address info (seems not helping or at least I have no idea how to use this).
Any experienced embedded developer can kindly give some suggestions? How you debugging in your work?
By the way, if the console print crash info includes stack info and Call Trace, no epc and ra (I just learnt that). Can the epc(crashed address) be found still?
Many kernel developers, including myself, do not use a debugger when developing device drivers. For many years, Linux did not support kernel debugging. Even now, not all CPU architectures support kernel debugging.
One of the easiest things you can do is to use printk to log events to the console. Also, increase the console UART speed. I often use 115200 baud.
The Linux kernel does support kgdb now, for some CPU architectures.
https://www.kernel.org/doc/htmldocs/kgdb/index.html
I also highly recommend Linux kernel developers read these two books:
Linux Device Drivers, by Jonathan Corbet, Alessandro Rubini, Greg Kroah-Hartman
Understanding the Linux Kernel, by Daniel P. Bovet, Marco Cesati

Running MMU-less Linux on ARM Cortex-R4

I'm using ARM Cortex-R4 for my system. It has a Memory Protection Unit instead of a Memory Management Unit. Effectively, this means that there's dedicated hardware for memory protection but that there's a one-to-one mapping between physical and virtual addresses. I'm a little confused about which Linux I should go for - standard Linux kernel with MMU disabled or uCLinux.
On ARM's evaluation board, I have run the standard kernel compiled with MMU disabled. I used the cramfs filesystem which is available on the official ARM website. After the kernel boots up, I'm in the shell, but I couldn't do much experimentation as I found that, most of the time, the shell stops responding (particularly when I press "tab" for auto-completion).
So I'm still not sure whether the MMU-less kernel should run smoothly if I use the correct filesystem. Also, which distro (buildroot?) should I use for the no-VM Linux?
Any idea or suggestion is welcome.
It's been more than 2 years since I asked this question. Now is the time I should write what I found for myself.
ucLinux was a project forked from the Linux kernel long back with the aim to develop Kernel for MMU less systems. However, after a certain while, it was merged to the parent Linux branch. So, today there doesn't exist any active ucLinux distribution.
So, if you disable MMU from the mainline kernel configuration, you'll get an MMU-less version. In fact, now there are configuration options provided in the kernel itself whereby a user can specify the memory layout and the access permissions.
Cheers!
uClinux is a Linux distribution which uses the Linux kernel with the MMU "turned off" and adds some applications and libraries on top of it. You wont choose one or the either as they are best one on top of the other.
If you got to a point where you have a shell running, you've managed to boot Linux sans MMU on your board but ran into a bug.
I believe ucLinux was built for something just like this [mmu less systems]
http://www.uclinux.org/description/

Resources