Mainlining Guide: Difference between revisions
LogicalErzor (talk | contribs) No edit summary |
|||
Line 269: | Line 269: | ||
= See also = | = See also = | ||
* https://wiki.postmarketos.org/wiki/User:Alexeymin/Kernel_development_in_chroot_using_abuild | |||
* https://wiki.postmarketos.org/wiki/Troubleshooting:kernel | |||
* {{issue|175|pmaports}} Google Galaxy Nexus (samsung-maguro): Mainlining progress (initial tricks with RAM and some sleep calls before the reboots in the code to figure out where it was failing will also be useful for other devices) | * {{issue|175|pmaports}} Google Galaxy Nexus (samsung-maguro): Mainlining progress (initial tricks with RAM and some sleep calls before the reboots in the code to figure out where it was failing will also be useful for other devices) | ||
* {{issue|153|pmaports}} Google Pixel 3 XL (google-crosshatch): mainlining attempt: progress and questions (useful for newer SoCs, useful info about force-reboot code, stub dtbo partition) | * {{issue|153|pmaports}} Google Pixel 3 XL (google-crosshatch): mainlining attempt: progress and questions (useful for newer SoCs, useful info about force-reboot code, stub dtbo partition) | ||
[[Category:Guide]] | [[Category:Guide]] |
Revision as of 08:35, 13 January 2022
General information about Mainlining is on the Mainlining page. |
Introduction
Please have realistic expectations: Booting mainline even if nothing else is working is already a great achievement! |
This guide will walk you through mainlining your device. For the devices where this will work, you should be fine with basic shell knowledge, and you will be rewarded with learning a lot of new stuff and possibly booting the mainline kernel on your device!
Requirements
postmarketOS port
This guide assumes that postmarketOS was already ported with a downstream kernel to your device, and that you can enter a shell after it booted via USB (SSH or telnet). Downstream kernels are the ones from the vendor, that ship with the device, and all derivatives from that (e.g. your typical Android / LineageOS ROM). You can check if it was ported already on the devices page, and start a new port if necessary.
An existing port with downstream kernel is not a hard dependency, it may take less effort overall to skip that depending on the state of the codebase. |
Getting Help
The mainlining process varies greatly for each device, which means we can't just write down straight forward instructions here. But luckily there are skilled people who have a bigger picture of a specific SoC and they know how to help you out efficiently. Head over to your device's wiki page (as linked in the device overview) and look at the chipset the device has (infobox on the top right). You can also check out Mainlining#Getting_help
Make sure that your SoC is listed in Mainlining#Supported_SoCs. If it isn't, ask someone on #postmarketOS-mainline if it's supported in mainline Linux.
Cooperative firmware
Some firmware, especially the bootloader, trustzone etc., don't play nice with the mainline Linux kernel. That is because it may require ugly hacks in the kernel, courtesy of being disgustingly broken. Those ugly hacks will not be accepted into mainline, because the proper solution would be to fix the firmware, regardless of the fact that the freedom to do that was taken away from you thanks to signature verification.
For example, a device shipping with 32bit kernel or even 64bit kernel with aforementioned ugly hacks, is likely to not support PSCI, the only mainline-approved way of CPU power management (including SMP) on aarch64. Considering this relies on trustzone cooperation, which is as far from being under your control as it possibly can, you're probably out of luck unless you a) implement said ugly hacks or b) manage to exploit your device and supply a proper trustzone.
Only if we campaign for the freedom to run our own software on the devices we own will we be able to replace the firmware with an open one, shall one emerge.
Preparation
Serial cable
It is recommended to have a working serial cable for your device. In case you can not make one, it might be possible to use a workaround for retrieving log messages but that isn't straight forward. You can also use a framebuffer console to see logs appearing on your screen, which you will have to enable in your dts.
pmbootstrap setup
If you have not done this already, please download and initialize pmbootstrap
. You can stay with the defaults. Just make sure to select the right device, and (to save you some time), select none
as the user interface. Replace ~/code
with the path where you would like to store the source code.
$ cd ~/code
$ git clone https://gitlab.com/postmarketOS/pmbootstrap.git
$ cd pmbootstrap
$ alias pmbootstrap=$PWD/pmbootstrap.py
$ pmbootstrap init
Generate an initramfs with the debug-shell hook:
$ pmbootstrap initfs hook_add debug-shell
Kernel
Download a copy of linux-next
. If your device's SoC has a git repository with active development, use that instead of https://github.com/torvalds/linux.git
:
$ cd ~/code
$ git clone https://github.com/torvalds/linux.git --depth 1
$ cd linux
If you have already checked out the regular linux repository, you can add the linux-next
branch as follows:
$ cd ~/code/linux
$ git remote add linux-next https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
$ git fetch --tags linux-next
$ git checkout -b development linux-next/master
After running the commands of one of the two blocks above, add a new branch for your device:
$ cd ~/code/linux
$ git checkout -b "device-<vendor>-<codename>"
envkernel.sh
Usually when compiling a kernel, you would install all dependencies and a cross compiler in your host system. To make it easier, we have the envkernel.sh
script (for fish shell: envkernel.fish
). It sets up an Alpine Linux chroot with all the dependencies by using pmbootstrap
internally, exports the environment variables to use the right cross compiler and creates an alias to make
. This means, whenever you type make
after sourcing that script, it will actually run make
in the chroot. Please try the script out once to make sure everything is working as expected:
(enter the directory where you have cloned the linux kernel source)
$ cd ~/code/linux
$ source ~/code/pmbootstrap/helpers/envkernel.sh
Initializing Alpine chroot (details: 'pmbootstrap log')
pmbootstrap envkernel.sh activated successfully.
* kernel source: /home/user/code/linux
* output folder: /home/user/code/linux/.output
* architecture: arm (samsung-i9100 is armhf)
* aliases: make, kernelroot, pmbootstrap, pmbroot (see 'type make' etc.)
$ make defconfig # or qcom_defconfig for a Qualcomm device
*** pmbootstrap envkernel.sh active for /home/user/code/linux! ***
make: Entering directory '/mnt/linux'
make[1]: Entering directory '/mnt/linux/.output'
getconf: LFS_CFLAGS: unknown variable
getconf: LFS_LDFLAGS: unknown variable
getconf: LFS_LIBS: unknown variable
HOSTCC scripts/basic/fixdep
GEN ./Makefile
HOSTCC scripts/kconfig/conf.o
YACC scripts/kconfig/zconf.tab.c
LEX scripts/kconfig/zconf.lex.c
HOSTCC scripts/kconfig/zconf.tab.o
HOSTLD scripts/kconfig/conf
*** Default configuration is based on 'multi_v7_defconfig'
#
# configuration written to .config
#
make[1]: Leaving directory '/mnt/linux/.output'
make: Leaving directory '/mnt/linux'
envkernel.sh has grown to be quite powerful, read more about it at the compiling kernels with envkernel.sh wiki page.
Got everything?
Please double check with the following checklist that you meet all the requirements before proceeding further. If you need any help with the above, just ask in the channel or on GitLab.
- Serial cable (or suitable workaround)
- Device ported to postmarketOS
- Initramfs with debug-shell generated
- envkernel.sh test run
Device Tree Source
The DTS file describes how the peripherals of the device are connected to the SoC. Here is a short description of the process you are guided through here.
Start with an existing file
When trying to make a DTS file for your device, it's best to start with one that already works. Look under arch/{arm,arm64}/boot/dts
or use Gitlab's find file feature to search for your dts for your specific SoC. If you are having trouble, ask in the channel.
Example for copying an existing file:
$ cd ~/code/linux/arch/arm/boot/dts
$ cp qcom-apq8064-asus-nexus7-flo.dts qcom-apq8064-lge-nexus4-mako.dts
Let's commit that directly, so it will be easy to see what you have changed later on by running git diff
(adjust the description of the commit accordingly):
$ git add -A
$ git commit -m "Starting with: qcom-apq8064-asus-nexus7-flo.dts"
Adjust model and compatible
Open the DTS file in an editor and replace the model
and compatible
strings at the top of the file:
// SPDX-License-Identifier: GPL-2.0-only
#include "qcom-apq8064-v2.0.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
/ {
model = "Asus Nexus7(flo)";
compatible = "asus,nexus7-flo", "qcom,apq8064";
// ...
In the example, we replace model
with "LGE Nexus4 (mako)"
and the first string after compatible with "lge,nexus4-mako
(we leave the second string in place, as this is the name of the SoC, which is the same).
And again, let's commit this change. It's recommended to commit after every change you make to the DTS files so you can revert easily to the last known working state if necessary:
$ git add -A
$ git commit -m "Adjusted model and compatible"
! caveat: The right compatible values can be found in downstream dts. You may however find something unexpected.
In the following example (sm-a300fu), msm8916-mtp is used, which will result in the wrong dts being selected unless you copy qcom,board-id = <0xCE08FF01 1>;
as well. Unfortunately, this board-id is shared between several Samsung phones, but considering they only bundle the one dtb a particular model uses, we can be grateful there even is a board-id. A solution has not been decided upon yet. (18. 3. 2019)
// SPDX-License-Identifier: GPL-2.0-only
/dts-v1/;
#include "msm8916-samsung-a300fu.dtsi"
/ {
model = "Samsung Galaxy A3 sm-a300fu";
compatible = "qcom,msm8916-mtp", "qcom,msm8916", "qcom,mtp";
qcom,board-id = <0xCE08FF01 1>;
};
Finally, if you see regulators defined in your dts, remove them. They most likely won't work on your device, and can potentially damage your device/peripherals if set to the wrong values. An example would be: https://github.com/torvalds/linux/blob/master/arch/arm/boot/dts/qcom-msm8960-cdp.dts#L39-L273
Minimal booting version
The next steps are done to try an run a minimal mainline Linux kernel on your device. Almost nothing will work at this point, except for initializing RAM and serial output. We will work our way to enabling one feature after another throughout the process.
Adjust DTS Makefile
Open arch/{arm,arm64}/boot/dts/Makefile
in an editor and add one line for your new device tree. First find the right location by searching for the prefix in the file (e.g. all qcom-
lines are in the dtb-$(CONFIG_ARCH_QCOM) += \
section). Then insert the name of your dts
file there, but use dtb
as extension and don't forget the backslash \
at the end of the line. Save, check the diff (it should be similar to the one below) and commit your change:
$ git diff
diff --git a/arch/{arm,arm64}/boot/dts/Makefile b/arch/{arm,arm64}/boot/dts/Makefile
index 3b4cc1b64a1e..af74d95b63fa 100644
--- a/arch/{arm,arm64}/boot/dts/Makefile
+++ b/arch/{arm,arm64}/boot/dts/Makefile
@@ -756,6 +756,7 @@ dtb-$(CONFIG_ARCH_QCOM) += \
qcom-apq8064-ifc6410.dtb \
qcom-apq8064-sony-xperia-yuga.dtb \
qcom-apq8064-asus-nexus7-flo.dtb \
+ qcom-apq8064-lge-nexus4-mako.dtb \
qcom-apq8074-dragonboard.dtb \
qcom-apq8084-ifc6540.dtb \
qcom-apq8084-mtp.dtb \
$ git add arch/{arm,arm64}/boot/dts/Makefile
$ git commit -m "Enable my new DTS in the Makefile"
Testing
Defconfig and compilation
Look at https://github.com/torvalds/linux/tree/master/arch/{arm,arm64}/configs
to see what defconfig you should use. Generally, for Qualcomm devices qcom_defconfig
is used. If you are confused, ask on in the channel for what defconfig to use. Make a .config
file with the following:
$ cd ~/code/linux
$ source ~/code/pmbootstrap/helpers/envkernel.sh
$ make qcom_defconfig
$ make -j5
Verification of your DTS
Before you upload the kernel to the device, it's good practice to check, if the DTS file is valid.
You'll need to grep output of the command and look for warnings related to your device DTS file.
WARNING: Currently you have to revert revert of commit "Revert "kbuild: Enable DT schema checks for %.dtb targets"" to get the checks functional on DTB |
$ pmbootstrap chroot -- apk update && pmbootstrap chroot -- apk add git python3-dev py3-pip && pmbootstrap chroot -- pip3 install git+https://github.com/devicetree-org/dt-schema.git@master
$ make qcom/sdm845-oneplus-fajita.dtb # work since 5.16 kernels, DTB can be found in the directory arch/{arm,arm64}/boot/dts/
pmbootstrap
Init
Check if any devices based on your SoC have been mainlined using pmbootstrap. They are usually located in the aports/device/{community, main} directories. If there are any based on your SoC, model your APKBUILDs like the mainlined version |
We will now use pmbootstrap and your port in pmaports to our advantage in getting mainline running on your device. Obviously everyone's device is different, so your mileage may vary. It might also be helpful seeing an example of what to expect: https://gitlab.com/LogicalErzor/mainline-kernel-pmos-aports/-/commit/3f3401fc0c6c1c823c464869cd5e0edd72c6c07c
First, open both your device-<vendor>-<codename>
(referred to as "DEVICE") and linux-<vendor>-<codename>
(referred to as "LINUX") directories. We will be working in them heavily.
Do the following in order:
- Open DEVICE/APKBUILD and LINUX/APKBUILD and up the pkgrel version by 1. Save the file and run
pmbootstrap checksum device-<vendor>-<codename>
- Open LINUX/APKBUILD and change the following:
- pkgver=5.16 # mainline kernel version that you are using
- pkgdesc=... # include mainline in the string
- change makedepends to the following:
makedepends="bash bc bison devicepkg-dev flex openssl-dev perl gmp-dev mpc1-dev mpfr-dev findutils postmarketos-installkernel"
. If there are any errors duringpmbootstrap install or pmbootstrap build --force
then you will most likely be editing this - _repository="linux"
- _commit="<kernel commit number>"
- in source="" change the following:
- $pkgname-$_commit.tar.gz::https://github.com/torvalds/$_repository/archive/$_commit.tar.gz
- remove all patches listed here. You used that for downstream, which isn't needed for mainline
- replace
. downstreamkernel_prepare
withcp "$srcdir/config-$_flavor.$arch" .config
- make package() like the following:
package() { mkdir -p "$pkgdir"/boot make zinstall modules_install dtbs_install \ ARCH="$_carch" \ INSTALL_MOD_STRIP=1 \ INSTALL_PATH="$pkgdir"/boot \ INSTALL_MOD_PATH="$pkgdir" \ INSTALL_DTBS_PATH="$pkgdir/usr/share/dtb" install -D "$builddir"/include/config/kernel.release \ "$pkgdir/usr/share/kernel/$_flavor/kernel.release" }
- Remove the huge GCC check (Don't need that for mainline)
- Save the file and run
pmbootstrap checksum linux-<vendor>-<codename>
- Look at DEVICE/deviceinfo and see if any of the variable listed in https://gitlab.com/postmarketOS/boot-deploy/-/blob/master/boot-deploy-functions.sh are needed for your device. For example, for the MSM8960 SoC device, it needs
deviceinfo_dtb
anddeviceinfo_append_dtb
as the bootloader doesn't support dtbs - Replace the config file in your LINUX folder with the .config file. Make sure it's the same name and run
pmbootstrap checksum linux-<vendor>-<codename>
Once you have set these basic parameters, it's time to see if it'll boot.
Building and Running
Run pmbootstrap install
. This will fetch the kernel source, compile it, and package it for your device. pmbootstrap flasher flash_kernel
should get the mainline kernel onto your device
Rebuilds
In order to rebuild, run pmbootstrap zap -p
. This will zap your compiled kernel, and now you can run pmbootstrap install
.
See also
- https://wiki.postmarketos.org/wiki/User:Alexeymin/Kernel_development_in_chroot_using_abuild
- https://wiki.postmarketos.org/wiki/Troubleshooting:kernel
- pmaports#175 Google Galaxy Nexus (samsung-maguro): Mainlining progress (initial tricks with RAM and some sleep calls before the reboots in the code to figure out where it was failing will also be useful for other devices)
- pmaports#153 Google Pixel 3 XL (google-crosshatch): mainlining attempt: progress and questions (useful for newer SoCs, useful info about force-reboot code, stub dtbo partition)