Skip to content
flto edited this page Mar 18, 2018 · 1 revision

Misc commands:

# extract `ramdisk.cpio.gz` to folder `ramdisk/`

mkdir ramdisk && (cd ramdisk && (gzip -dc ../ramdisk.cpio.gz  | cpio -idm))

# creating a gzip ramdisk from folder `ramdisk/`

(cd ramdisk && (find . | cpio -o -H newc | gzip > ../ramdisk.cpio.gz))

# create arm64 fastboot image from kernel build in "linuxb" for device "msm8917-basic"

cat linuxb/arch/arm64/boot/Image.gz linuxb/arch/arm64/boot/dts/qcom/msm8917-basic.dtb > Image.gz.dtb
mkbootimg --kernel Image.gz.dtb --ramdisk ramdisk.cpio.gz --base 0x80000000 -o test.img

Files:

Kernel config: config_msm8917

Ramdisk: ramdisk.cpio.gz

Is the bootloader running the kernel?

Writing zero to the pshold address reboots the device. This provides a simple (but low information) debugging method which can be used to verify if code is executed or used for simple cases:

if (condition)
	reboot();
else
	hang_or_continue();

On msm8917, the pshold address is 0x004ab000. Insert the following sequence at the kernel entry point (in head.S, before MMU is enabled) and the device should reboot instantly if the kernel is booted:

mov x0, #0xb000
movk x0, 0x004a, lsl 16
mov x1, #0
str x1, [x0]
hang: b hang

Once MMU is enabled it gets more tricky until everything needed for ioremap() has been initialized.

Does it hang before reaching userspace?

With a minimal dtb, there's a good chance the kernel doesn't hang on any drivers and is able to reach userspace. Add the following command to rc.boot (first script run by the init system in the example initrd):

devmem 0x004ab000 32 0

If the kernel reaches userspace and runs the init, it should reboot instantly.

Dumping dmesg to RAM from userspace

First step is to choose a physical address to copy the log to. Choose a reserved-memory region that won't be touched by the bootloader/TWRP. On msm8917, 0x86800000 is a good choice (it is a modem memory region). Don't flag it as no-map in the mainline dtb, otherwise it can't be accessed through /dev/mem. In the rc.boot script:

# might want to sleep for a few seconds before this
dmesg | dd of=/dev/mem seek=$((0x86800000)) bs=1
# try to wait for CPU cache to flush
sleep 10
# reboot
devmem 0x004ab000 32 0

Then boot TWRP and use the following command to read back the log (change 8k value as needed):

dd if=/dev/mem skip=$((0x86800000)) bs=1 count=8k