i'm trying to make my first steps with yocto.
While using psplash i can see the yocto-splashscreen only while shutting down the system. Not while the system is booting up.
For this i'm using a Ubuntu 18.10 in a Virtual Box (oracle).
I build the image with this commans:
~$ sudo apt-get install git python chrpath g++ gawk gcc make texinfo
~$ git clone -b sumo git://git.yoctoproject.org/poky
~$ cd poky/
~/poky$ source oe-init-build-env
~/poky/build$ nano /conf/local.conf
insert at the end of file:
BB_NUMBER_THREADS = “8”
PARALLEL_MAKE = “-j 4”
IMAGE_INSTALL_append = “ psplash”
INHERIT_remove = “uninative”
build with:
~/poky/build$ bitbake core-image-minimal
run the image with:
runqemu qemux86
While booting up i noticed the following two messages:
framebuffer /dev/fb0 not detected
Boot splashscreen disabled
I found this question: yocto splash screen not appearing
I already try to add IMAGE_INSTALL_append = " psplash" in the local.conf but no effect.
Do you have some ideas?
I just had the same problem. Apparently yocto would create a file /etc/rc.d/S00psplash.sh . S00 means this is executed right at the beginning of the boot process, before the required graphics drivers are loaded. I changed it to S40 and it worked. Not sure yet how to fix this inside yocto. You might also need to add to your local.conf:
DISTRO_FEATURES_append = " directfb" # (not sure whether this is really required)
and
IMAGE_FEATURES_append = " splash" # (this might already be enabled for your image)
If it does not work please report back
Best regards ~
Screenshot
Here you can see the described boot-sequence
framebuffer /dev/fb0 not detected
Boot splashscreen disabled
comes from the psplash-init file
#!/bin/sh
### BEGIN INIT INFO
# Provides: psplash
# Required-Start:
# Required-Stop:
# Default-Start: S
# Default-Stop:
### END INIT INFO
echo "########################################################"
if [ ! -e /dev/fb0 ]; then
echo "Framebuffer /dev/fb0 not detected"
echo "Boot splashscreen disabled 1"
exit 0;
fi
read CMDLINE < /proc/cmdline
for x in $CMDLINE; do
case $x in
psplash=false)
echo "Boot splashscreen disabled 2"
exit 0;
;;
esac
done
export TMPDIR=/mnt/.psplash
mount tmpfs -t tmpfs $TMPDIR -o,size=40k
rotation=0
if [ -e /etc/rotation ]; then
read rotation < /etc/rotation
fi
/usr/bin/psplash --angle $rotation &
So the try to show the splashscreen (lines 6-7 in screenshot) occures before the framebuffer is loaded (from line 13 ...)
Is this right?
I'm wondering about the message "Please wait: booting...."
Do we talk about different bootsteps? (like bootloader-boot and linux-boot)
I can reload kernel by using 'kexec -e', that means the configuration of my kernel should be correct. However the kernel can't automatically reboot after crashes. The output of command 'kdump-config show' shows the environment is correct.
RAMDISK$ kdump-config show
USE_KDUMP: 1
KDUMP_SYSCTL: kernel.panic_on_oops=1
KDUMP_COREDIR: /var/crash
crashkernel addr: 0xf000000
current state: ready to kdump
kernel link:
kexec command:
/sbin/kexec -p --command-line="BOOT_IMAGE=/boot/vmlinuz-3.2.1 root=UUID=4989514c-5622-4cd7-9b75-f0e07f7c6f84 ro initrd=/install/initrd.gz quiet kgdboc=ttyS0,115200 irqpoll maxcpus=1 nousb" --initrd=/boot/initrd.img-3.2.1 /boot/vmlinuz-3.2.1
RAMDISK$
RAMDISK$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-3.2.1 root=UUID=4989514c-5622-4cd7-9b75-f0e07f7c6f84 ro initrd=/install/initrd.gz crashkernel=256M quiet kgdboc=ttyS0,115200
RAMDISK$
The original kernel 3.2.0-4-amd64 build-in by debian 7.9 can work with kdump without any problem.
Can anyone figure out what's wrong to my kernel, or the error log when kdump is working?
I am working first time with a minnowboard hardware from Intel and have create a core-image-minimal using Yocto project. When I power on the Minnowboard, I enter the UEFI shell where I execute following commands:
connect -r
map -r
fs0:
bootx64
The keyboard works fine for all this process. Then I enter the GRUB menu and select "BOOT".
When the core-image-minimal boots, I am asked to login.
At this point, the keyboard doesn't work. I inspected the boot command and it goes something like this:
setparams 'boot'
linux /vmlinuz root=/dev/mmcblk0p2 ro rootwait quiet console=ttys0,115200 console=tty0
I am not sure why keyboard works in the UEFI shell but not when the linux image is booted. Do I need to add some option like -usb or -usbdevice to this boot commands for it to detect keyboard?
It sounds horrible but apparently the issue was with my keyboard which is a make from "Cherry". When I plugged in a Dell keyboard, it works seamlessly. Duh!
I am running Debian in an embedded system and seeing the booting through a serial console, but I don't know how to show boot messages.
I see the BIOS, the grub menu, and then:
Loading Linux 3.2.0-4-686-pae ...
Loading initial ramdisk ...
and nothing else until login pormpt
I already erased the 'quiet' parameter from /etc/default/grub and executed update-grub command after that. And after booting I see that the cmdline is right, without that param:
cat /proc/cmdline :
BOOT_IMAGE=/vmlinuz-3.2.0-4-686-pae root=UUID=0d645791-109e-4ce4-87be-1cc7074da5f8 ro
But it doesn't work... what else am I missing? do I need to recompile the kernel with a specific flag or what?
uname -a :
Linux hostname 3.2.0-4-686-pae #1 SMP Debian 3.2.68-1+deb7u2 i686 GNU/Linux
/boot/grub/grub.cfg
#
# DO NOT EDIT THIS FILE
#
# It is automatically generated by grub-mkconfig using templates
# from /etc/grub.d and settings from /etc/default/grub
#
### BEGIN /etc/grub.d/00_header ###
if [ -s $prefix/grubenv ]; then
load_env
fi
set default="0"
if [ "${prev_saved_entry}" ]; then
set saved_entry="${prev_saved_entry}"
save_env saved_entry
set prev_saved_entry=
save_env prev_saved_entry
set boot_once=true
fi
function savedefault {
if [ -z "${boot_once}" ]; then
saved_entry="${chosen}"
save_env saved_entry
fi
}
function load_video {
insmod vbe
insmod vga
insmod video_bochs
insmod video_cirrus
}
serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1
terminal_input serial
terminal_output serial
set timeout=2
### END /etc/grub.d/00_header ###
### BEGIN /etc/grub.d/05_debian_theme ###
set menu_color_normal=cyan/blue
set menu_color_highlight=white/blue
### END /etc/grub.d/05_debian_theme ###
### BEGIN /etc/grub.d/10_linux ###
menuentry 'Debian GNU/Linux, with Linux 3.2.0-4-686-pae' --class debian --class gnu-linux --class gnu --class os {
load_video
insmod gzio
insmod part_msdos
insmod ext2
set root='(hd1,msdos1)'
search --no-floppy --fs-uuid --set=root c1265ba3-c4bd-493f-9fec-7c015099c0bc
echo 'Loading Linux 3.2.0-4-686-pae ...'
linux /vmlinuz-3.2.0-4-686-pae root=UUID=0d645791-109e-4ce4-87be-1cc7074da5f8 ro
echo 'Loading initial ramdisk ...'
initrd /initrd.img-3.2.0-4-686-pae
}
menuentry 'Debian GNU/Linux, with Linux 3.2.0-4-686-pae (recovery mode)' --class debian --class gnu-linux --class gnu --class os {
load_video
insmod gzio
insmod part_msdos
insmod ext2
set root='(hd1,msdos1)'
search --no-floppy --fs-uuid --set=root c1265ba3-c4bd-493f-9fec-7c015099c0bc
echo 'Loading Linux 3.2.0-4-686-pae ...'
linux /vmlinuz-3.2.0-4-686-pae root=UUID=0d645791-109e-4ce4-87be-1cc7074da5f8 ro single
echo 'Loading initial ramdisk ...'
initrd /initrd.img-3.2.0-4-686-pae
}
### END /etc/grub.d/10_linux ###
### BEGIN /etc/grub.d/20_linux_xen ###
### END /etc/grub.d/20_linux_xen ###
### BEGIN /etc/grub.d/30_os-prober ###
### END /etc/grub.d/30_os-prober ###
### BEGIN /etc/grub.d/40_custom ###
# This file provides an easy way to add custom menu entries. Simply type the
# menu entries you want to add after this comment. Be careful not to change
# the 'exec tail' line above.
### END /etc/grub.d/40_custom ###
### BEGIN /etc/grub.d/41_custom ###
if [ -f $prefix/custom.cfg ]; then
source $prefix/custom.cfg;
fi
### END /etc/grub.d/41_custom ###
I am stuck! any help will be appreciated!
thanks
EDIT:
Sorry guys, I did a stupid mistake. I defined
GRUB_SERIAL_COMMAND="serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1"
in /etc/default/grub
and I thought that was enough for grub to pass the serial specifications to the kernel, but of course it is not, GRUB only pass the GRUB_CMDLINE_LINUX variable to the kernel as parameter.
Adding the console parameter in the GRUB_CMDLINE_LINUX makes the kernel to receive the console settings and use the serial for messages output:
GRUB_CMDLINE_LINUX="video=off elevator=deadline console=ttyS0,115200"
Now it is working.
Sorry for the stupid misunderstood and thanks for your time! :)
You can try adding to the kernel line where you removed quiet the options
console=tty0 console=ttyS0,115200n8
where 115200 is the speed you want. See eg ubuntu how-to.
Instead of the quiet flag you could try using the verbose flag in your kernel parameters then do update-grub.
As suggested by this wiki.
I'm new to kernel development and I would like to know how to run/debug the linux kernel using QEMU and gdb. I'm actually reading Robert Love's book but unfortunately it doesn't help the reader on how to install proper tools to run or debug the kernel... So what I did was to follow this tutorial http://opensourceforu.efytimes.com/2011/02/kernel-development-debugging-using-eclipse/. I'm using eclipse as an IDE to develop on the kernel but I wanted first to get it work under QEMU/gdb. So what I did so far was:
1) To compile the kernel with:
make defconfig (then setting the CONFIG_DEBUG_INFO=y in the .config)
make -j4
2) Once the compilation is over I run Qemu using:
qemu-system-x86_64 -s -S /dev/zero -kernel /arch/x86/boot/bzImage
which launch the kernel in "stopped" state
3) Thus I have to use gdb, I try the following command:
gdb ./vmlinux
which run it correctly but... Now I don't know what to do... I know that I have to use remote debugging on the port 1234 (default port used by Qemu), using the vmlinux as the symbol table file for debugging.
So my question is: What should I do to run the kernel on Qemu, attach my debugger to it and thus, get them work together to make my life easier with kernel development.
I'd try:
(gdb) target remote localhost:1234
(gdb) continue
Using the '-s' option makes qemu listen on port tcp::1234, which you can connect to as localhost:1234 if you are on the same machine. Qemu's '-S' option makes Qemu stop execution until you give the continue command.
Best thing would probably be to have a look at a decent GDB tutorial to get along with what you are doing. This one looks quite nice.
Step-by-step procedure tested on Ubuntu 16.10 host
To get started from scratch quickly I've made a minimal fully automated QEMU + Buildroot example at: https://github.com/cirosantilli/linux-kernel-module-cheat/blob/c7bbc6029af7f4fab0a23a380d1607df0b2a3701/gdb-step-debugging.md Major steps are covered below.
First get a root filesystem rootfs.cpio.gz. If you need one, consider:
a minimal init-only executable image: https://unix.stackexchange.com/questions/122717/custom-linux-distro-that-runs-just-one-program-nothing-else/238579#238579
a Busybox interactive system: https://unix.stackexchange.com/questions/2692/what-is-the-smallest-possible-linux-implementation/203902#203902
Then on the Linux kernel:
git checkout v4.15
make mrproper
make x86_64_defconfig
cat <<EOF >.config-fragment
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_KERNEL=y
CONFIG_GDB_SCRIPTS=y
EOF
./scripts/kconfig/merge_config.sh .config .config-fragment
make -j"$(nproc)"
qemu-system-x86_64 -kernel arch/x86/boot/bzImage \
-initrd rootfs.cpio.gz -S -s \
-append nokaslr
On another terminal, from inside the Linux kernel tree, supposing you want to start debugging from start_kernel:
gdb \
-ex "add-auto-load-safe-path $(pwd)" \
-ex "file vmlinux" \
-ex 'set arch i386:x86-64:intel' \
-ex 'target remote localhost:1234' \
-ex 'break start_kernel' \
-ex 'continue' \
-ex 'disconnect' \
-ex 'set arch i386:x86-64' \
-ex 'target remote localhost:1234'
and we are done!!
For kernel modules see: How to debug Linux kernel modules with QEMU?
For Ubuntu 14.04, GDB 7.7.1, hbreak was needed, break software breakpoints were ignored. Not the case anymore in 16.10. See also: https://bugs.launchpad.net/ubuntu/+source/qemu-kvm/+bug/901944
The messy disconnect and what come after it are to work around the error:
Remote 'g' packet reply is too long: 000000000000000017d11000008ef4810120008000000000fdfb8b07000000000d352828000000004040010000000000903fe081ffffffff883fe081ffffffff00000000000e0000ffffffffffe0ffffffffffff07ffffffffffffffff9fffff17d11000008ef4810000000000800000fffffffff8ffffffffff0000ffffffff2ddbf481ffffffff4600000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000801f0000
Related threads:
https://sourceware.org/bugzilla/show_bug.cgi?id=13984 might be a GDB bug
Remote 'g' packet reply is too long
http://wiki.osdev.org/QEMU_and_GDB_in_long_mode osdev.org is as usual an awesome source for these problems
https://lists.nongnu.org/archive/html/qemu-discuss/2014-10/msg00069.html
nokaslr: https://unix.stackexchange.com/questions/397939/turning-off-kaslr-to-debug-linux-kernel-using-qemu-and-gdb/421287#421287
Known limitations:
the Linux kernel does not support (and does not even compile without patches) with -O0: How to de-optimize the Linux kernel to and compile it with -O0?
GDB 7.11 will blow your memory on some types of tab completion, even after the max-completions fix: Tab completion interrupt for large binaries Likely some corner case which was not covered in that patch. So an ulimit -Sv 500000 is a wise action before debugging. Blew up specifically when I tab completed file<tab> for the filename argument of sys_execve as in: https://stackoverflow.com/a/42290593/895245
See also:
https://github.com/torvalds/linux/blob/v4.9/Documentation/dev-tools/gdb-kernel-debugging.rst official Linux kernel "documentation"
Linux kernel live debugging, how it's done and what tools are used?
When you try to start vmlinux exe using gdb, then first thing on gdb is to issue cmds:
(gdb) target remote localhost:1234
(gdb) break start_kernel
(continue)
This will break the kernel at start_kernel.
BjoernID's answer did not really work for me. After the first continuation, no breakpoint is reached and on interrupt, I would see lines such as:
0x0000000000000000 in ?? ()
(gdb) break rapl_pmu_init
Breakpoint 1 at 0xffffffff816631e7
(gdb) c
Continuing.
^CRemote 'g' packet reply is too long: 08793000000000002988d582000000002019[..]
I guess this has something to do with different CPU modes (real mode in BIOS vs. long mode when Linux has booted). Anyway, the solution is to run QEMU first without waiting (i.e. without -S):
qemu-system-x86_64 -enable-kvm -kernel arch/x86/boot/bzImage -cpu SandyBridge -s
In my case, I needed to break at something during boot, so after some deciseconds, I ran the gdb command. If you have more time (e.g. you need to debug a module that is loaded manually), then the timing doesn't really matter.
gdb allows you to specify commands that should be run when started. This makes automation a bit easier. To connect to QEMU (which should now already be started), break on a function and continue execution, use:
gdb -ex 'target remote localhost:1234' -ex 'break rapl_pmu_init' -ex c ./vmlinux
As for me the best solution for debugging the kernel - is to use gdb from Eclipse environment. You should just set appropriate port for gdb (must be the same with one you specified in qemu launch string) in remote debugging section. Here is the manual:
http://www.sw-at.com/blog/2011/02/11/linux-kernel-development-and-debugging-using-eclipse-cdt/
On Linux systems, vmlinux is a statically linked executable file that contains
the Linux kernel in one of the object file formats supported by Linux, which
includes ELF, COFF and a.out. The vmlinux file might be required for kernel
debugging, symbol table generation or other operations, but must be made
bootable before being used as an operating system kernel by adding a multiboot
header, bootsector and setup routines.
An image of this initial root file system must be stored somewhere accessible
by the Linux bootloader to the boot firmware of the computer. This can be the
root file system itself, a boot image on an optical disc, a small partition on
a local disk (a boot paratition, usually using ext4 or FAT file systems), or a
TFTP server (on systems that can boot from Ethernet).
Compile linux kernel
Build the kernel with this series applied, enabling CONFIG_DEBUG_INFO (but leave CONFIG_DEBUG_INFO_REDUCED off)
https://www.kernel.org/doc/html/latest/admin-guide/README.html
https://wiki.archlinux.org/index.php/Kernel/Traditional_compilation
https://lwn.net/Articles/533552/
Install GDB and Qemu
sudo pacman -S gdb qemu
Create initramfs
#!/bin/bash
# Os : Arch Linux
# Kernel : 5.0.3
INIT_DIR=$(pwd)
BBOX_URL="https://busybox.net/downloads/busybox-1.30.1.tar.bz2"
BBOX_FILENAME=$(basename ${BBOX_URL})
BBOX_DIRNAME=$(basename ${BBOX_FILENAME} ".tar.bz2")
RAM_FILENAME="${INIT_DIR}/initramfs.cpio.gz"
function download_busybox {
wget -c ${BBOX_URL} 2>/dev/null
}
function compile_busybox {
tar xvf ${BBOX_FILENAME} && cd "${INIT_DIR}/${BBOX_DIRNAME}/"
echo "[*] Settings > Build options > Build static binary (no shared libs)"
echo "[!] Please enter to continue"
read tmpvar
make menuconfig && make -j2 && make install
}
function config_busybox {
cd "${INIT_DIR}/${BBOX_DIRNAME}/"
rm -rf initramfs/ && cp -rf _install/ initramfs/
rm -f initramfs/linuxrc
mkdir -p initramfs/{dev,proc,sys}
sudo cp -a /dev/{null,console,tty,tty1,tty2,tty3,tty4} initramfs/dev/
cat > "${INIT_DIR}/${BBOX_DIRNAME}/initramfs/init" << EOF
#!/bin/busybox sh
mount -t proc none /proc
mount -t sysfs none /sys
exec /sbin/init
EOF
chmod a+x initramfs/init
cd "${INIT_DIR}/${BBOX_DIRNAME}/initramfs/"
find . -print0 | cpio --null -ov --format=newc | gzip -9 > "${RAM_FILENAME}"
echo "[*] output: ${RAM_FILENAME}"
}
download_busybox
compile_busybox
config_busybox
Boot Linux Kernel With Qemu
#!/bin/bash
KER_FILENAME="/home/debug/Projects/kernelbuild/linux-5.0.3/arch/x86/boot/bzImage"
RAM_FILENAME="/home/debug/Projects/kerneldebug/initramfs.cpio.gz"
qemu-system-x86_64 -s -kernel "${KER_FILENAME}" -initrd "${RAM_FILENAME}" -nographic -append "console=ttyS0"
$ ./qemuboot_vmlinux.sh
SeaBIOS (version 1.12.0-20181126_142135-anatol)
iPXE (http://ipxe.org) 00:03.0 C980 PCI2.10 PnP PMM+07F92120+07EF2120 C980
Booting from ROM...
Probing EDD (edd=off to disable)... o
[ 0.019814] Spectre V2 : Spectre mitigation: LFENCE not serializing, switching to generic retpoline
can't run '/etc/init.d/rcS': No such file or directory
Please press Enter to activate this console.
/ # uname -a
Linux archlinux 5.0.3 #2 SMP PREEMPT Mon Mar 25 10:27:13 CST 2019 x86_64 GNU/Linux
/ #
Debug Linux Kernel With GDB
~/Projects/kernelbuild/linux-5.0.3 ➭ gdb vmlinux
...
(gdb) target remote localhost:1234
Remote debugging using localhost:1234
0xffffffff89a4b852 in ?? ()
(gdb) break start_kernel
Breakpoint 1 at 0xffffffff826ccc08
(gdb)
Display all 190 possibilities? (y or n)
(gdb) info functions
All defined functions:
Non-debugging symbols:
0xffffffff81000000 _stext
0xffffffff81000000 _text
0xffffffff81000000 startup_64
0xffffffff81000030 secondary_startup_64
0xffffffff810000e0 verify_cpu
0xffffffff810001e0 start_cpu0
0xffffffff810001f0 __startup_64
0xffffffff81000410 pvh_start_xen
0xffffffff81001000 hypercall_page
0xffffffff81001000 xen_hypercall_set_trap_table
0xffffffff81001020 xen_hypercall_mmu_update
0xffffffff81001040 xen_hypercall_set_gdt
0xffffffff81001060 xen_hypercall_stack_switch
0xffffffff81001080 xen_hypercall_set_callbacks
0xffffffff810010a0 xen_hypercall_fpu_taskswitch
0xffffffff810010c0 xen_hypercall_sched_op_compat
0xffffffff810010e0 xen_hypercall_platform_op