Jump to content

Mainlining FAQ

From postmarketOS Wiki
Revision as of 20:25, 31 March 2018 by Ollieparanoid (talk | contribs) (Add instructions from @opendata26 on how to split partitions from rootfs and flash them to real partitions on the device)

"Mainlining isn't fun, but it's hella rewarding"

Various information collected from #postmarketOS. See The Mainline Kernel for a more howto-style page.

How to start?

  • Serial cable highly recommended
  • First step will be to find out how much your device is already supported by mainline
  • Check if your soc is supported.. that will be basic building block
  • There's really no point doing display till you have uart or USB working

Writing dmesg to RAM and reading it out after reboot

During the mainlining process you need to be able to get the dmesg output from the device. Typically this is done with a serial cable (see below). Sometimes making such a cable is relatively easy by using the audio jack, but in other cases it requires opening the device or is not possible at all. Here is a less comfortable alternative.

In Android kernels it is possible to write the output of dmesg to memory, and read it out after reboot from /proc/last_kmsg. So while you are mainlining, you can use Android's ram_console driver from your downstream kernel to dump dmesg to memory as well, then reboot to the downstream kernel and read out /proc/last_kmesg. Quote from decatf:

The Andriod ram_console does this. It should exist in many if not most Android kernels. The driver is registered the board/machine init. I am still using it even on kernel 4.16

  • Make sure to allocate the same memory block as your downstream or recovery kernel,

https://github.com/Decatf/linux/blob/next-p4wifi_pmos/arch/arm/mach-tegra/board-p4wifi.c#L480-L481

  • Make sure the driver is using the same ram console signature as your downstream kernel.

https://github.com/Decatf/linux/blob/next-p4wifi_pmos/drivers/staging/android/ram_console.c#L41 On my device I can force reboot to a downstream recovery kernel and read last_kmsg from a kernel that booted nothing but the bare device tree and the ram_console driver.

Serial cable

Can I do it without a serial cable?

  • in theory, yes by dumping dmesg to RAM (see above)
  • once it reliably boots though, and USB comes up properly, you can use the USB serial gadget in the kernel (see below)

How to get serial output? (serial cable)

  • enable the serial device for your kernel (e.g. for OMAP: CONFIG_SERIAL_OMAP and CONFIG_SERIAL_OMAP_CONSOLE)
  • add console=ttySAC0,115200 to the kernel cmdline
  • it might also be ttyO0 (uppercase O for OMAP chipset)

How to get serial output over USB? (USB serial gadget)

The Linux kernel can act like a serial device, and it's possible to output what you would get on the serial port over that fake serial device directly via USB to your PC.

  • set CONFIG_USB_G_SERIAL=y and enable USB as console, and add console=ttyGS0,115200 to the cmdline

Is it possible to boot kernels with a serial cable?

  • No. Just flash with a normal cable and switch to the serial cable to read the log output.
  • Once it reliably boots though, and USB comes up properly, you can use the USB serial gadget in the kernel

There's no device tree source (dts) in the kernel fork for my device, how do I make one?

Previous kernels used board-*.c files instead of the dts files. These are in folders such as arch/arm/mach-omap2 (example). The idea is that you'll need to convert these to dts files. Doing so manually for each of them is a huge and error-prone task, better use one of the following techniques:

  • Strip down dts from similar hardware (n900 in case of omap3?) and try to get it to boot
  • Add support to an existing mainline driver (e.g. mms144 and mms114 are probably pretty similar) rather than forward-porting the old driver
  • Forward-port the board files to recent kernels (new kernels still understand board files for some hardware, but not for all!), then strip them down to a bare minimum you can still test (where serial or usb is still working, so you know that the device boots), and then convert that do dts.

Finding the best approach is very hardware specific. If you know C and think you have tried some of the methods above without success, consider asking the maintainers of the chipset in the kernel. Regarding OMAP, Pavel offered that you could CC him.

See also: #1021


Consider updating your device's kernel to the latest Android stable version first (these instruction might make it easier to convert the board files to dtbs) and then going to real mainline from there.

What options are needed to get USB network?

  • USB_ETH IIRC
  • also check the defconfig in aports/main/linux-postmarketos-mainline

How to make OpenRC print its output to the serial port?

  • just set RC_LOGGING to true in /etc/rc.conf
  • (it's the init system log like Starting etc.....[ok])

How can I compile kernel sources from a local git repo?

  • Clone the kernel with git (~5GB!)
  • Use the following command to build the mainline kernel package with the checked out sources
$ pmbootstrap build linux-postmarketos-mainline --src=~/code/linux

How can I repackage the initramfs with custom modules?

Run a normal installation to generate the initramfs:

$ pmbootstrap install

And then writing a short shell script, that repackages the postmarketOS initramfs with the modules you compiled. After reading through it, adjust it as needed and execute it as root:

#!/bin/sh
# Config
device="oneplus-bacon"
tmpdir="/tmp/pmOS-initfs-with-mainline-modules"
work="$(pmbootstrap -q config work)"

# Create temp folder
[ -d "$tmpdir" ] && rm -rf "$tmpdir"
mkdir -p "$tmpdir"

# Extract the pmOS initramfs
cp -v "$work/chroot_rootfs_$device/boot/initramfs-"* initramfs.gz
gzip -d initramfs.gz
cpio -i < initramfs

# Remove existing modules
rm -rf initramfs lib/modules

#
# CHANGEME: you need to write the commands that copy the kernel modules from your
# kernel source folder into the initramfs here!
#

# Package the initramfs again
cd "$tmpdir"
find . -print0 | busybox cpio --quiet -o -H newc | gzip -1 > initramfs-repackaged

How to merge kernel configs?

The idea is, that we have a shared linux-postmarketos-stable package, which all mainlined devices use. Check Kernel_configuration#Automatically_merging_kernel_configuration for instructions on how to merge kernel configs somewhat efficiently with a script.

How to flash each postmarketOS partition from the rootfs to a different partition on the phone

Usually pmOS writes the whole rootfs (which has its own /boot and / partitions) to one partition on the device (more). If your mainline kernel isn't able to find the postmarketOS partition by label (even if you have enabled device mapper in the kernel config), then you could use the following workaround to flash each partition from the rootfs image to a real partition on the device.

$ pmbootstrap install
$ pmbootstrap export
$ losetup <pathtoimage> /dev/loop0
$ dd if=/dev/loop0p1 of=boot_partition.img
$ dd if=/dev/loop0p2 of=root_partition.img
$ fastboot flash system root_partition.img
$ fastboot flash cache boot_partition.img