kgdb is starting far away from init.c start_kernel() - linux

Why kgdb always start from kernel/kgdb.c:1749 lines "kgdb:waiting dor connection from remote gdb" just step on the way of kernel of Linux.
I want to start from the beginning.
My environment is:
PC ubuntu10.10
gdb-kernel 2.6.34.1
filesys made by busybox
VirtualMach is qemu
Following the tips from web searches, I have made my linux. I can use it smoothly but when I try to remote-gdb it the kernel always start from:
kernel/kgdb.c:1749 "kgdb:waiting for connection from remote gdb"
which is much too far away from the function start_kernel which I want to meet.
I am using the following:
qemu -kernel /usr/src/work/bzImage -append "root=/dev/sda kgdboc=ttyS0,115200 kgdbwait"
-boot c -hda /usr/src/work/busybox.img -k en-us -serial tcp::4321,server
gdb /usr/src/work/vmlinux (gdb) target remote localhost:4321
Then I add -S so it can start from the beginning. But when I gdb it there is still something wrong.
When I input the command next it doesn't go to the next line and go to other place. For example I set a breakpoint at init.c startkernel() after the next. It is in other file.

If "kgdb:waiting dor connection from remote gdb" isn't early enough for you, you're going to have to try something other than kgdb. Think about this: kgdb is a service provided by the kernel. You can't debug the kernel "from the beginning" because the kernel has to perform enough initialization for it to provide the kgdb service.
Fortunately, there's another option for you. According to this source, if you start qemu with the flags -s -S, qemu will start the system and wait for you to attach a debugger to localhost:1234 before it even loads the kernel. Is that early enough?

Related

QEMU Booting for kernel developement not working when using tcp 2222:22 to copy things

I am learning how to implement my own system call in linux kernel by following:
Syscall Guide
Custom Kernel Guide
for getting QEMU set up.
In the end, it tells us to run the following command to Redirect port 2222 on the host OS to the QEMU VM's port 22 which will let me copy files between QEMU and my linux:
qemu-system-x86_64 -m 64M -hda ../debian_squeeze_amd64_standard.qcow2 - append "root=/dev/sda1 console=tty0 console=ttyS0,115200n8" -kernel arch/ x86_64/boot/bzImage -nographic -net nic,vlan=1 -net user,vlan=1 -redir tcp: 2222::22
But I get the follwing error on my terminal when I run the code:
qemu-system-x86_64: -: invalid option
Help me out, I am a beginner. Thanks
In this part of your command line: "- append" -- you have an extra space between the "-" and the "append". QEMU command line options are generally of the form "-something". If you put a space in the middle then QEMU won't recognize what you've given it.
If you're following a tutorial and a command it gives you doesn't work then it's often a good idea to check it carefully for minor typos, or to copy-and-paste the command from the tutorial and try that.

Serial port unavaliable arduino

Trying to upload a code to arduino, but whether in the Arduino IDE or Arduino Create, both return this erro while uploading. Running on Linux Tara(mint 19 cinnamon).
./opt/arduino-builder/arduino-builder -compile -core-api-version 10611 -hardware opt/arduino-builder/hardware -hardware ./opt/cores -tools opt/arduino-builder/tools -tools ./opt/tools -built-in-libraries opt/libraries/latest -logger humantags -fqbn arduino:avr:mega:cpu=atmega2560 -build-cache /tmp -build-path /tmp/716441957/build -verbose -libraries /tmp/716441957/custom -libraries /tmp/716441957/pinned /tmp/716441957/sketch_oct8a
Sketch uses 8280 bytes (3%) of program storage space. Maximum is 253952 bytes.
Global variables use 443 bytes (5%) of dynamic memory, leaving 7749 bytes for local variables. Maximum is 8192 bytes.
Programming with: Serial
Flashing with command:/home/jesus/.arduino-create/arduino/avrdude/6.3.0-arduino9/bin/avrdude -C/home/jesus/.arduino-create/arduino/avrdude/6.3.0-arduino9/etc/avrdude.conf -q -q -patmega2560 -cwiring -P/dev/ttyACM0 -b115200 -D -Uflash:w:/tmp/arduino-create-agent734074237/sketch_oct8a.hex:i
avrdude: ser_open(): can't open device "/dev/ttyACM0": Permission denied
ioctl("TIOCMGET"): Inappropriate ioctl for device
ioctl("TIOCMGET"): Inappropriate ioctl for device
1#
First, check the port in your IDE. In Arduino tools->port
If the port is hidden or you can not move the cursor over this then run this commands in your terminal.If everything ok then skips this and follow the second part.
sudo apt-get install librxtx-java -y
sudo usermod -aG dialout $USER
sudo apt-get install gnome-system-tools
2#
After this again check the first method. If it is not working then run this commands
ls -l /dev/ttyACM*
sudo usermod -a -G dialout <username>
You probably have another program running which is already using this port.
You should close most other programs like putty or another serial monitor app.
Otherwise, try to reconnect the Arduino to the PC.
I know that these ideas below come from using a Teensy, but they may help you.
Sometimes there are the ACM* ports listed in the Arduino IDE. Try looking at the ser ports. I know when I am running my Teensy, sometimes I have them switched and need to select the correct one.
Also, from my experience with the Teensy, you might need to add a udev rule to allow permissions to access the port from non-root user. Here is the link that shows the udev file.
There is no direct way to solve this issue. In addition to it, you are not using an IDE. I will list the things you need to check, I am sure this will solve your problem.
I am not good at Linux environment so I will refer to applications names as window, you go the corresponding application in Linux.
Go to linux device manager and see for your arduino board. It should have proper naming like "arduino uno at port 3", then use the correct port in your command. If this name does not come properly then it means Driver is not available in your machine. So, go to step2.
Find the driver online and install it in your system, I am not sure about the support of linux with arduino, once it is done please repeat step1.
So, I conclude in short that you do not have the proper driver (which is strongly believe) or pointing the wrong port. I am not an expert with the udev rules, but it is definitely an issue you can experience with these kinds of micro-controllers.

enable linux kernel driver dev_dbg debug messages

is there a simplest possible way to enable linux kernel driver dev_dbg debug messages (actually it's a trace style messages) hopefully without messing up with the kernel patching/recompiling or the driver implementing something extra like debugfs? perhaps there is a way to enable something SIMPLE in the kernel (like one flag?) triggering particular driver or all drivers dev_dbg (it can be filtered with the `dmesg|grep "driverName") output?
the kernel version is 4.14.
there is NO syslog/daemonlog/system log running at all. there is NO network interface and only single serial port is available. the target system is very slow and is very compact so there is NO WAY to add syslog/etc, there is nothing but dmesg where exactly would be good to see the output of the lines like:
dev_dbg(&client->dev, "bla bla bla\n");
some posts already suggested to add debug keyword for the bootargs kernel parameters unfortunately wasn't enough.
the outputs like dev_info are getting into the dmesg with no issue so it's definitely something close. thanks
the simplest way to receive dev_dbg messages without installing/configuring syslog/etc, appeared necessary to do following steps:
provide debug key into bootargs kernel parameters
append #define DEBUG at the first line of the driver file - if the driver is a single file and is using a common Makefile, or append -DDEBUG inside the CC build options if the driver contains of multiple source files and as usually has it's own Makefile
upon the kernel booted and the prompt appear to enable debug level messages by executing either dmesg -n 8 or echo 8 > /proc/sys/kernel/printk
load the driver if the module with the command either insmod <driver name> or modprobe <driver name> or if the driver is integrated into the kernel the insertion commands may vary.
example on how to assign the kernel integrated driver for the i2c bus subsystem:
echo <driver name> <i2c bus address> > /sys/bus/i2c/devices/i2c-0/new_device
side notes:
if the DTS will have a driver record assignment, manually repeated driver assignment will cause the error - in case of i2c subsystem - error EBUSY (-16), the driver will be assigned way before the command prompt and the dmesg messages will be limited to the default level (usually dev_info only)
in case if the driver has been already assigned by DTS and there is no way to exclude it temporary from the tree source - it's useful to detach and reattach it once again after the debug (trace) level messages activated
for the i2c subsystem it would require to execute a command:
echo <driver name> > /sys/bus/i2c/drivers/<drivername>/unbind
then
echo <driver name> > /sys/bus/i2c/drivers/<drivername>/bind
warning:
the kernel drivers trace mechanism will not help on debugging internal driver improper configured or missing service structures. i.e. if the driver is loaded but remain silent with no trace messages means the probe has never been executed because of some kernel expected service structures information were missing or faulty
You need to follow below three steps.
1. Make sure that your kernel is complied with CONFIG_DYNAMIC_DEBUG=y
cat /proc/config.gz | gunzip | grep CONFIG_DYNAMIC_DEBUG
If not then recompile your kernel with CONFIG_DYNAMIC_DEBUG=y
2) After boot up check that debugfs is mounted somewhere or not.
mount | grep debugfs
mostly it get mounted in /sys/kernel/debug if not then you can manually mount it anywhere like below
mount -t debugfs none /sys/kernel/debug
3) Now enable the file name for which you need dev_dbg() logs.
echo 'file <driverfilename.c> +p'>/sys/kernel/debug/dynamic_debug/control
some more commands to play with dynamic_debug/control are at https://www.kernel.org/doc/html/v4.11/admin-guide/dynamic-debug-howto.html
now you should get your debug.
If you still do not see your message then enable prink level
echo "8 4 1 7" > /proc/sys/kernel/printk
If the CONFIG_DYNAMIC_DEBUG option is not set, then dev_dbg/pr_debug can be turned into normal printk() statements with KERN_DEBUG level.
But for that you need to add #define DEBUG at beginning of file.
or add -DDEBUG while compiling
or Enable CONFIG_[SUBSYSTEM]_DEBUG=y
I used below command to turn on the Kernel log for Android. I think for Linux to it should work:
echo 'file <driverfilename.c> +p'>/sys/kernel/debug/dynamic_debug/control
You can see the driver logs in "dmesg"
Thanks
MJ
Adding "debug" to the kernel parameters will lift the kernel events log level to the KERN_DEBUG (level 7) that will pollute the kmsg buffer with debug messages for the entire kernel code and it's not usually what we want while debugging our kernel module. The same is right when we change the current kernel log level via /proc/sys/kernel/printk.
To gain fine-grained control of all log levels above the KERN_ERR for your kernel module only without messing with global kernel log level configuration just add the following lines at the beginning of your module code:
#undef dev_dbg
#undef dev_info
#undef dev_warn
#undef dev_notice
#define dev_dbg dev_err
#define dev_info dev_err
#define dev_warn dev_err
#define dev_notice dev_err
You can mount the debug filesystem manually by executing the following command:
mount -t debugfs none /sys/kernel/debug
Once done, do:
ls /sys/kernel/debug
All debug information and message would be stored there without having to re-compile.
Also, you can add the this under your /etc/fstab to make the mount go automatic when you reboot.
... If you are re-compiling your kernel anyway, then you could enable " [*] Debug File System" under "Kernel Hacking"
Good luck, I hope all goes well.
It's likely that the driver you're interested in has exported the Kconfig option to enable the debug messages. In such case, you can enable debug output from just one driver by setting the DEBUG_YOUR_DRIVER=y or YOUR_DRIVER_DEBUG=y in menuconfig and rebuilding the kernel. Search for the driver name and you will see if this is available.
For example, for NXP/Freescale i.MX pinctrl driver, I just changed DEBUG_PINCTRL to y and looked into dmesg to get the debug logs from that driver.
This was the fastest approach for me.

virtual parallel port connector in QEMU

I have been reading Linux Device Drivers 3rd edition and have been running linux 2.6 in QEMU. However, I am at the point where it requires real hardware. I attempted to emulate a paralleport connector in QEMU with no luck. The host has no parallel port connector.
qemu-system-x86_64 -parallel file:outputfile --enable-kvm -smp 2 -initrd initramfs.igz -kernel arch/x86/boot/bzImage -m 1024 -append "console=ttyS0 loglevel=8" -nographic
I then wrote a module to access the parallel port connector via request_region(0x378,1,"parallelport");. However, whenever I attempt to write to the ioport region, none of the output is seen in the file "outputfile" in the working directory where QEMU was booted. I have also added the CONFIG_PARPORT option in the kernel and added some of its associated CONFIG's (i.e CONFIG_PARPORT_PC...) which seemed to only add the linux built-in driver or register an IRQ handler. With this, I was still unable to write to the parallelport "outputfile" on the host machine.
However, I can read and write to the ioport region (meaning whatever I do write with outb can be then read with inb. However, it is not written to the parallel port outfile, which leads me to believe something is still wrong.
I was wondering if I could get some suggestions as to what I might be doing wrong or how to start going about this? The only research I found was the different paralleport options for qemu (use host devices, over udp, etc...), which I tried with no luck. In addition, with using the outputfile option or any option that does not require a host machine parallel port, is it possible to simulate interrupts?
Update: After playing around a little more, it seems the operations of writing and reading from the ioport are working (still don't appear in the outputfile thought). This is because when I do -parallel none, I can obtain the ioport and write to it, but reading from it results in unprintable characters (not the ones I inputed). This doesn't happen by default (specifying no -parallel option or when -parallel file:outputfile.
Update2: From QEMU -device documentation I found that -parallel is legacy. So I changed my command to the following:
qemu-system-x86_64 -chardev file,path=./outputfile,id=parallel0 -device isa-parallel,chardev=parallel0,iobase=0x378,irq=7,index=0 --enable-kvm --smp 2 -initrd initramfs.igz -kernel arch/x86/boot/bzImage -m 1024 -append "console=ttyS0 loglevel=8" -nographic
and then loaded the driver and made a chardev /dev/parallel0. However, this still didn't work.

Creating boot.scr for u-boot

I generate image for a Freescale i.mx6 sabresd using Yocto.
When booting, to activate the hdmi I have to modify u-boot by editing the bootargs. I use the following command :
setenv mmcargs 'setenv bootargs console=ttymxc0,115200 root=/dev/mmcblk2p2 rootwait rw video=mxcfb0:dev=hdmi, 1920x1080M#60, if=RGB24'
I can use saveenv to not enter it at every boot, but I'd like to automatize it to make the deployment easier. So I have made a boot.scr. Here is the boot.txt :
setenv mmcargs 'setenv bootargs console=ttymxc0,115200 root=/dev/mmcblk2p2 rootwait rw video=mxcfb0:dev=hdmi, 1920x1080M#60, if=RGB24'
boot
And I create the boot.scr using mkimage -A arm -T script -O linux -d boot.txt boot.scr. But, when booting, it makes a loop (boot make uboot reload the configuration, where it reads boot so it begin again). Without boot... no boot. I've tried a lot of possibilities : boot 0x120000000, bootm, bootz, with a lot of options, nothing works.
Most likely, your boot fails because you never load a kernel from which you could boot from.
In most cases, if bootcmd loads a boot.scr, then it is up to your boot.scr script to load the kernel (and also a device tree assuming you are using a recent iMX6 kernel). Then your script may boot with this kernel or allow bootcmd to carry on with its boot sequence using the loaded kernel. The load commands would look something like:
loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}
loaduimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${uimage}
And the boot command should look something like:
run loaduimage; run loadfdt; bootm ${loadaddr} - ${fdt_addr}
You may already have an mmcboot command defined which already takes care of these.
I would remove the "boot" line from your script and instead load the kernel and device tree and then run bootm (or mmcboot) - basically try adding the above three lines to your script after setting mmcarg - you'll need to ensure all referenced variables are properly set (ie. mmcdev, mmpart, etc).
Using the answer from shibley, I've found a simpler way :
run loadimage
run mmcboot
He was right, mmcboot takes care of the booting of the kernel. But I have to run loadimage (not loaduimage) before.

Resources