Jump to content

Mainlining Guide: Difference between revisions

From postmarketOS Wiki
Okias (talk | contribs)
update to gitlab.postmarketos.org
 
(16 intermediate revisions by 10 users not shown)
Line 1: Line 1:
{{note|Parts of this page with useful information are slowly integrated into the [[Mainlining]] page instead.}}
{{note|General information about Mainlining is on the [[Mainlining]] page.}}


== Introduction ==
== Introduction ==
{{note|Please have realistic expectations: Booting mainline even if nothing else is working is already a great achievement!}}
{{note|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. Starting by collecting all required information, setting up your build environment and picking a mentor that will guide you through the tricky parts. 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!
The kernel fork used in Android is different from the kernel at [https://kernel.org kernel.org]. The former is downstream kernel (aka. baseline kernel) and the latter is upstream kernel.
Carrying around forks of the kernel is not sustainable as it becomes impossible to provide security patches after a short time. The only way to truly fix this for a device is <i>mainlining</i> it.
Making a device boot with the upstream kernel is colloquially referred to as mainlining.
 
When it comes to postmarketOS, we want to get as many devices working with one shared kernel package (based on upstream).
 
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!
 
 
== Getting Help ==
Read [[Mainlining_FAQ]] first to check if there provides some tips for your progress.
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 [https://en.wikipedia.org/wiki/System_on_a_chip SoC] and they know how to help you out efficiently. Head over to your device's wiki page (as linked in the [[devices|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 [[Matrix_and_IRC|#postmarketOS-mainline]] if it's supported in mainline Linux.
 


== Requirements ==
== Requirements ==
=== postmarketOS port ===
=== postmarketOS port ===
To make the instructions easier, this guide assumes that postmarketOS was already ported with a downstream kernel to your device, and that you can [[USB_Network|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 [[Porting_guide|new port]] if necessary.
This guide assumes that postmarketOS was already ported with a downstream kernel to your device, and that you can [[USB_Network|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 [[Porting_guide|new port]] if necessary.


{{note|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.}}
{{note|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.}}


=== Mentor ===
=== Serial cable ===
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 [https://en.wikipedia.org/wiki/System_on_a_chip SoC] and they know how to help you out efficiently. Head over to your device's wiki page (as linked in the [[devices|device overview]]) and look at the chipset the device has (infobox on the top right).
It is recommended to have a working [[Serial_debugging|serial cable]] for your device. In case you can not make one, it might be possible to [[Mainlining_FAQ#Writing_dmesg_to_RAM_and_reading_it_out_after_reboot|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.


Where to ask for help/mentors? Check [[Mainlining#Getting_help]]
=== Kernel packaging ===
 
To make the kernel work with multiple devices, it no longer appends the <code>dtb</code> file to the kernel image. Instead, it puts all <code>dtb</code> files for the current architecture in <code>/usr/share/dtb</code>. The <code>postmarketos-mkinitfs</code> package appends the <code>dtb</code> file defined in the [[deviceinfo]] to the linux image in the boot partition.
Make sure that your SoC is in the list (if it isn't then we don't have an easy way for mainlining right now, sorry). Let's do some more preparation now, so everything is in place before you kindly ask your mentor to help you with the process.


=== Cooperative firmware ===
=== Cooperative firmware ===
Some firmware, especially bootloader, trustzone etc., doesn't play nice with mainline 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.
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.
{{Note | There are some second stage bootloader (like [[lk2nd]]) for dealing this kind of hacks. }}
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.


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.
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.
=== Device tree source  ===
To make your device boot, you will need a device tree source (<code>dts</code>) file (which will get compiled to a <code>dtb</code> mentioned above). The guide would tell you about how to make a device tree from existing file provided by soc.


== Preparation ==
== Preparation ==
=== Serial cable ===
''Before proceeding, make sure that you know that your device is supported by the mainline kernel. Otherwise use the source code of a vendor's fork of the kernel, which is known to work as described in the [[porting guide]].''
It is recommended to have a working [[Serial_debugging|serial cable]] for your device. In case you can not make one, it might be possible to [[Mainlining_FAQ#Writing_dmesg_to_RAM_and_reading_it_out_after_reboot|use a workaround]] for retrieving log messages but that isn't straight forward.


=== pmbootstrap setup ===
=== pmbootstrap setup ===
If you have not done this already, please download and initialize <code>pmbootstrap</code>. You can stay with the defaults, just make sure to select the right device, and (to save you some time) <code>none</code> as user interface. Replace <code>~/code</code> with the path where you would like to store the source code.
If you have not done this already, please download and initialize <code>pmbootstrap</code>. You can stay with the defaults. Just make sure to select the right device, and (to save you some time), select <code>none</code> as the user interface. Replace <code>~/code</code> with the path where you would like to store the source code.
<syntaxhighlight lang="shell-session">
<syntaxhighlight lang="shell-session">
$ cd ~/code
$ cd ~/code
$ git clone https://gitlab.com/postmarketOS/pmbootstrap.git
$ git clone https://gitlab.postmarketos.org/postmarketOS/pmbootstrap.git
$ cd pmbootstrap
$ cd pmbootstrap
$ alias pmbootstrap=$PWD/pmbootstrap.py
$ alias pmbootstrap=$PWD/pmbootstrap.py
Line 43: Line 60:
<syntaxhighlight lang="shell-session">
<syntaxhighlight lang="shell-session">
$ pmbootstrap initfs hook_add debug-shell
$ pmbootstrap initfs hook_add debug-shell
$ pmbootstrap export
</syntaxhighlight>
</syntaxhighlight>


=== Kernel ===
=== Kernel ===
{{note|The kernel source code is several gigabytes in size, this will take a while!}}
Download a copy of <code>linux-next</code>. If your device's SoC has a git repository with active development, use that instead of <code>https://github.com/torvalds/linux.git</code>:
Download a copy of <code>linux-next</code>:
<syntaxhighlight lang="shell-session">
<syntaxhighlight lang="shell-session">
$ cd ~/code
$ cd ~/code
$ git clone https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git linux
$ git clone https://github.com/torvalds/linux.git --depth 1
$ cd linux
$ cd linux
</syntaxhighlight>
</syntaxhighlight>
Line 63: Line 78:
</syntaxhighlight>
</syntaxhighlight>


After running the commands of one of the two blocks above, add a new branch for your device (replace <code>lg-mako</code> with your device's name):
After running the commands of one of the two blocks above, add a new branch for your device:
<syntaxhighlight lang="shell-session">
<syntaxhighlight lang="shell-session">
$ cd ~/code/linux
$ cd ~/code/linux
$ git checkout -b "device-lg-mako"
$ git checkout -b "device-<vendor>-<codename>"
</syntaxhighlight>
</syntaxhighlight>


Line 81: Line 96:
  * architecture:  arm (samsung-i9100 is armhf)
  * architecture:  arm (samsung-i9100 is armhf)
  * aliases: make, kernelroot, pmbootstrap, pmbroot (see 'type make' etc.)
  * aliases: make, kernelroot, pmbootstrap, pmbroot (see 'type make' etc.)
$ make defconfig
*** 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'
</syntaxhighlight>
</syntaxhighlight>


envkernel.sh has grown to be quite powerful, read more about it at the [[compiling kernels with envkernel.sh]] wiki page.
envkernel.sh has grown to be quite powerful, read more about it at the [[compiling kernels with envkernel.sh]] wiki page.


=== Got everything? ===
=== Reminder ===
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 [[Matrix_and_IRC|in the channel]] or [https://github.com/postmarketOS/pmbootstrap/issues on GitHub] as usually.
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 [[Matrix_and_IRC|in the channel]] or [https://gitlab.postmarketos.org/postmarketOS/pmbootstrap on GitLab].


* [[#Serial_cable|Serial cable]] (or suitable workaround)
* [[#Serial_cable|Serial cable]] (or suitable workaround)
* [[#pmbootstrap setup|Device ported to postmarketOS]]
* [[#pmbootstrap setup|Device ported to postmarketOS]]
* [[#Mentor|Mentor]]
* [[#pmbootstrap setup|Initramfs with debug-shell generated]]
* [[#pmbootstrap setup|Initramfs with debug-shell generated]]
* [[#envkernel.sh|envkernel.sh test run]]
* [[#envkernel.sh|envkernel.sh test run]]


== Contact your mentor ==
Hop on [[Matrix_and_IRC|Matrix or IRC]] and ask the mentor if they have time to walk you through the further steps. This should be obvious, but remember to be nice and understanding if the mentor does not have time right away, they are supporting you for free so you'll need to be grateful and patient.
The following steps are meant to be taken together with the mentor.


== Device Tree Source ==
== Device Tree Source ==
The [[DTS]] file describes how the peripherals of the device are connected to the SoC. [[Device_Tree_(dtb)#Writing_a_device_tree | Here]] is a short description of the process you are guided through here.
The [[DTS]] file describes how the peripherals of the device are connected to the SoC. [[Device_Tree_(dtb)#Writing_a_device_tree | Here]] is a short description of the process you are guided through here.
=== Before start ===
If you are having trouble, ask [[Matrix_and_IRC|in the channel]].
When it comes to DT, it's best to start with one that already works. Look under <code>arch/{arm,arm64}/boot/dts</code> in the kernel source code for relevant files ([https://elixir.bootlin.com/linux/latest/source/arch/arm/boot/dts browse online]) with your device's codename.
You may want to use source code host services (GitLab, github, etc.) to search for your dts for your specific SoC.
The general file naming is <code>$chipset_vendor-$chipset-$vendor-$codename.dts</code>.
Examples:
* <code>qcom-msm8974-lge-nexus5-hammerhead.dts</code>
* <code>qcom-msm8974-sony-xperia-honami.dts</code>
* <code>qcom-apq8064-sony-xperia-yuga.dts</code>
* <code>qcom-apq8064-asus-nexus7-flo.dts</code>
When you don't have a result, try to find a <code>dts</code> file with the same chipset as your device (e.g. <code>msm8974</code>). Try to create a new one for your device based on that by [[How_to_create_a_patch_when_packaging_software|creating a patch]] for <code>linux-postmarketos-stable</code>.
If there is not even a <code>dts</code> file for the same chipset, you need to create one from scratch (''no idea how to do that, good luck and please extend the wiki''). If you have no idea but the faith, you may check the [[#Other guides]] about DT at the page below to pick up some ideas.


=== Start with an existing file ===
=== Start with an existing file ===
Your mentor probably knows which file you should use to start your work on. This may either be a file in the existing Linux source tree, or a file your mentor uploaded somewhere.
Now we have got source DT <code>qcom-apq8064-asus-nexus7-flo.dts</code> for our target device <code>apq8064-lge-nexus4-mako</code>. Copy it and rename to your device name.


Example for copying an existing file:
Example for copying an existing file:
Line 153: Line 159:
</syntaxhighlight>
</syntaxhighlight>


In the example, we replace <code>model</code> with <code>"LGE Nexus4 (mako)"</code> and the first string after compatible with <code>"lge,nexus4-mako</code> (we leave the second string in place, as this is the name of the SoC, which is the same).
In the example, we replace <code>model</code> with <code>"LGE Nexus4 (mako)"</code> and the first string after compatible with <code>"lge,nexus4-mako"</code> (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:
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:
Line 178: Line 184:
};
};
</syntaxhighlight>
</syntaxhighlight>
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/qcom-msm8960-cdp.dts#L39-L273


=== Minimal booting version ===
=== Minimal booting version ===
Your mentor will instruct you how to modify the file further, so you have a minimal configuration that allows you to boot into the mainline kernel if everything went right. 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.
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 ==
== Adjust DTS Makefile ==
Open <code>arch/arm/boot/dts/Makefile</code> 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 <code>qcom-</code> lines are in the <code>dtb-$(CONFIG_ARCH_QCOM) += \</code> section). Then insert the name of your <code>dts</code> file there, but use <code>dtb</code> as extenssion and don't forget the backslash <code>\</code> at the end of the line. Save, check the diff (it should be similar to the one below) and commit your change:
Open <code>arch/{arm,arm64}/boot/dts/Makefile</code> 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 <code>qcom-</code> lines are in the <code>dtb-$(CONFIG_ARCH_QCOM) += \</code> section). Then insert the name of your <code>dts</code> file there, but use <code>dtb</code> as extension and don't forget the backslash <code>\</code> at the end of the line. Save, check the diff (it should be similar to the one below) and commit your change:


<syntaxhighlight lang="shell-session">
<syntaxhighlight lang="shell-session">
$ git diff
$ git diff
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
diff --git a/arch/{arm,arm64}/boot/dts/Makefile b/arch/{arm,arm64}/boot/dts/Makefile
index 3b4cc1b64a1e..af74d95b63fa 100644
index 3b4cc1b64a1e..af74d95b63fa 100644
--- a/arch/arm/boot/dts/Makefile
--- a/arch/{arm,arm64}/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
+++ b/arch/{arm,arm64}/boot/dts/Makefile
@@ -756,6 +756,7 @@ dtb-$(CONFIG_ARCH_QCOM) += \
@@ -756,6 +756,7 @@ dtb-$(CONFIG_ARCH_QCOM) += \
         qcom-apq8064-ifc6410.dtb \
         qcom-apq8064-ifc6410.dtb \
Line 199: Line 208:
         qcom-apq8084-ifc6540.dtb \
         qcom-apq8084-ifc6540.dtb \
         qcom-apq8084-mtp.dtb \
         qcom-apq8084-mtp.dtb \
$ git add arch/arm/boot/dts/Makefile
$ git add arch/{arm,arm64}/boot/dts/Makefile
$ git commit -m "Enable my new DTS in the Makefile"
$ git commit -m "Enable my new DTS in the Makefile" # See Submitting_Patches for how to write commit messages
</syntaxhighlight>
</syntaxhighlight>


== Testing ==
== Testing ==
=== Defconfig and compilation ===
=== Defconfig and compilation ===
Ask your mentor for the right defconfig to use. Then configure the kernel to use the defconfig and finally build it. Example:
Look at <code>https://github.com/torvalds/linux/tree/master/arch/{arm,arm64}/configs</code> to see what defconfig you should use. Generally, for Qualcomm devices <code>qcom_defconfig</code> is used. If you are confused, ask on [[Matrix_and_IRC|in the channel]] for what defconfig to use. Make a <code>.config</code> file with the following:


<syntaxhighlight lang="shell-session">
<syntaxhighlight lang="shell-session">
Line 213: Line 223:
$ make -j5
$ make -j5
</syntaxhighlight>
</syntaxhighlight>
there is also a defconfig in linux-postmarketos-qcom that used by postmarketOS, you can run <code>pmbootstrap kconfig edit postmarketos-qcom</code> to inspect it.
After you get the correct defconfig for your device:
# adjust the kernel config to add the drivers for the device if they are not enabled yet.
# Set as many drivers to build as external module as possible so the main vmlinuz filesize doesn't increase too much.
# Replace <code>qcom</code> with the kernel config you want to modify (see <code>ls aports/main/linux-postmarketos-*</code>).


=== Verification of your DTS ===
=== Verification of your DTS ===
Line 218: Line 236:


You'll need to grep output of the command and look for warnings related to your device DTS file.
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}}


<syntaxhighlight lang="shell-session">
<syntaxhighlight lang="shell-session">
$ 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
$ pmbootstrap chroot -- apk update && pmbootstrap chroot -- apk add git python3-dev py3-pip swig && pmbootstrap chroot -- pip3 install dtschema
$ make -j3 dtbs_check
$ make qcom/sdm845-oneplus-fajita.dtb # work since 5.16 kernels, DTB can be found in the directory arch/{arm,arm64}/boot/dts/
</syntaxhighlight>
</syntaxhighlight>


Beware, it may fire a false-positive warning.
=== Deal with packages ===
==== Init ====
{{note|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}}


=== Execute on the device ===
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
This greatly depends on your device, and you can figure out the correct method by looking at your [[deviceinfo]] and at the <code>postmarketos-mkinitfs</code> code if necessary. But typically for fastboot based Android devices, you can patch the <code>boot.img</code> and boot it as follows.


==== Patch boot.img ====
In general, you would need to create a new kernel package for your device. You can do following to create a new kernel package:
Prepare your current shell session once:
# copy a existing kernel package under <code><workdir>/cache_git/device/{community testing}/linux-*</code>, rename it to your device model, and place it under <code>testing</code> folder mentioned above.
<syntaxhighlight lang="shell-session">
# create a new package with [[pmbootstrap]]. You would need to create a <code>device</code> package and a <code>linux-*<package></code> if your device is not in pmaports.
$ pmbootstrap chroot -- apk add abootimg android-tools mkbootimg dtbtool
$ export DEVICE="$(pmbootstrap config device)"
$ export WORK="$(pmbootstrap config work)"
$ export TEMP="$WORK/chroot_native/tmp/mainline/"
$ mkdir -p "$TEMP"
</syntaxhighlight>


Then run one of the following every time you would like to replace the kernel inside the <code>boot.img</code> file. The non-[[QCDT]] version is easier, so check if you have a QCDT or not in the <code>deviceinfo</code> first.
After creating kernel package, specifying device to use the new kernel package (or existing mainline kernel package), use the command below to build the kernel:


===== non-QCDT devices =====
Now append the DTB (device tree blob), which has been generated from your DTS file, to the kernel, then create a bootimage from it. Replace <code>qcom-apq8064-lge-nexus4-mako</code> accordingly, and mind the <code>dtb</code> at the end instead of <code>dts</code>:
<syntaxhighlight lang="shell-session">
<syntaxhighlight lang="shell-session">
$ cd ~/code/linux/.output/arch/arm/boot
pmbootstrap build --envkernel linux-postmarketos-<soc> # or linux-<brand>-<device> which is your package name
$ cat zImage dts/qcom-apq8064-lge-nexus4-mako.dtb > ~/code/linux/.zImage-dtb
$ cp ~/code/linux/.zImage-dtb "$TEMP"/zImage-dtb
$ cp "/tmp/postmarketOS-export/boot.img-$DEVICE" "$TEMP/boot.img"
$ pmbootstrap chroot
# abootimg -u /tmp/mainline/boot.img  -k /tmp/mainline/zImage-dtb
reading kernel from /tmp/mainline/zImage-dtb
Writing Boot Image /tmp/mainline/boot.img
# exit
[20:00:00] Done
</syntaxhighlight>
If you are getting
<syntaxhighlight lang="shell-session">
/tmp/mainline/boot.img: updated is too big for the Boot Image (7323648 vs 5853184 bytes)
</syntaxhighlight>
error, and it can fit on boot partition, add '''-c "bootsize=<boot partition size>"''' to abootimg command:
<syntaxhighlight lang="shell-session">
# abootimg -u /tmp/mainline/boot.img  -k /tmp/mainline/zImage-dtb -c "bootsize=12582912"
</syntaxhighlight>
</syntaxhighlight>


===== QCDT devices =====
Once you have set these basic parameters, it's time to see if it'll boot.
{{Note|On Ubuntu, make sure to install libfdt-dev}}
 
All flasher offsets must be replaced with the values from the [[deviceinfo]] (you might want to save the command as a shell script for quick usage).
==== Building and Running ====
<syntaxhighlight lang="shell-session">
Run <code>pmbootstrap install</code>. This will fetch the kernel source, compile it, and package it for your device. <code>pmbootstrap flasher flash_kernel</code> should get the mainline kernel onto your device
$ cp ~/code/linux/.output/arch/arm/boot/zImage  "$TEMP"/zImage
$ cp "/tmp/postmarketOS-export/boot.img-$DEVICE" "$TEMP/boot.img"
$ cp "/tmp/postmarketOS-export/initramfs-$DEVICE" "$TEMP/initramfs"
$ $WORK/chroot_native/usr/bin/dtbTool -s 2048 -p ~/code/linux/scripts/dtc/ -o "$TEMP/dt.img" ~/code/linux/.output/arch/arm/boot/dts
$ pmbootstrap chroot -- mkbootimg-osm0sis \
--kernel "/tmp/mainline/zImage" \
--ramdisk "/tmp/mainline/initramfs" \
--dt "/tmp/mainline/dt.img" \
--base "0x00000000" \
--second_offset "0x00f00000" \
--cmdline "console=ttyMSM0,115200,n8 PMOS_NO_OUTPUT_REDIRECT" \
--kernel_offset "0x00008000" \
--ramdisk_offset "0x02000000" \
--tags_offset "0x01e00000" \
--pagesize "2048" \
-o "/tmp/mainline/boot.img"
</syntaxhighlight>


==== Boot ====
==== Rebuilds ====
First start <code>dmesg -w</code> (see below). Then bring your device into fastboot mode, connect it via USB and boot (or flash) the kernel:
In order to rebuild, run <code>pmbootstrap zap -p</code>. This will zap your compiled kernel, and now you can run <code>pmbootstrap install</code>.
<syntaxhighlight lang="shell-session">
$ pmbootstrap flasher list_devices
$ pmbootstrap chroot -- fastboot boot /tmp/mainline/boot.img
</syntaxhighlight>


The <code>list_devices</code> line instructs <code>pmbootstrap</code> to mount the USB device nodes inside the chroot, so without this line being executed at least once in the session, fastboot will not find any devices (see {{github|1345}}).
=== Prepare for production ===
First, open both your <code>device-<vendor>-<codename></code> (referred to as "DEVICE") and <code>linux-<vendor>-<codename></code> (referred to as "LINUX") directories. We will be working in them heavily.


=== dmesg on your PC ===
Do the following in order:
Before booting the first time, run <code>dmesg -w</code> on your PC. If everything went right, you should see something like the following as soon as the device boots:


* Open DEVICE/APKBUILD and LINUX/APKBUILD and up the pkgrel version by 1. Save the file and run <code>pmbootstrap checksum device-<vendor>-<codename></code>
* 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: <code>makedepends="bash bc bison devicepkg-dev flex openssl-dev perl gmp-dev mpc1-dev mpfr-dev findutils postmarketos-installkernel"</code>. If there are any errors during <code>pmbootstrap install or pmbootstrap build --force</code> 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 <code>. downstreamkernel_prepare</code> with <code>cp "$srcdir/config-$_flavor.$arch" .config</code>
** make package() like the following:
<pre>
<pre>
[27166.665566] usb 3-9: new high-speed USB device number 16 using xhci_hcd
package() {
[27166.793111] usb 3-9: New USB device found, idVendor=0525, idProduct=a4a7
mkdir -p "$pkgdir"/boot
[27166.793117] usb 3-9: New USB device strings: Mfr=1, Product=2, SerialNumber=0
make zinstall modules_install dtbs_install \
[27166.793121] usb 3-9: Product: Gadget Serial v2.4
ARCH="$_carch" \
[27166.793125] usb 3-9: Manufacturer: Linux 4.16.0-rc5-next-20180314-dirty with ci_hdrc_msm
INSTALL_MOD_STRIP=1 \
[27166.809593] cdc_acm 3-9:2.0: ttyACM0: USB ACM device
INSTALL_PATH="$pkgdir"/boot \
[27166.809777] usbcore: registered new interface driver cdc_acm
INSTALL_MOD_PATH="$pkgdir" \
[27166.809778] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
INSTALL_DTBS_PATH="$pkgdir/usr/share/dtb"
 
install -D "$builddir"/include/config/kernel.release \
"$pkgdir/usr/share/kernel/$_flavor/kernel.release"
}
</pre>
</pre>
** Remove the huge GCC check (Don't need that for mainline)
** Save the file and run <code>pmbootstrap checksum linux-<vendor>-<codename></code>
* Look at DEVICE/deviceinfo and see if any of the variable listed in https://gitlab.postmarketos.org/postmarketOS/boot-deploy/-/blob/master/boot-deploy-functions.sh are needed for your device. For example, for the MSM8960 SoC device, it needs <code>deviceinfo_dtb</code> and <code>deviceinfo_append_dtb</code> 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 <code>pmbootstrap checksum linux-<vendor>-<codename></code>


= TODO =
* Mention this is ARM only
* Explain how to get dmesg from the device via telnet (<code>dhcpcd interface --nohook ipv6</code> might be necessary etc.)
* Add steps to upstream the changes made into the kernel (there are already good tutorials out there)
* Add step to integrate the changes with the pmbootstrap source tree (might need changes in pmbootstrap architecture for that)
* Describe how to add a "Mainline section" to each device specific page (with a template!) - something like [http://elektranox.org/droid4/ this overview] would be great to have for every device. This can be done while doing the first kernel compilation when following this guide, because that takes a while anyway. Get the components from:
** downstream dts or teardown results like from ifixit
** decipher from downstream dmesg
** <code>grep compatible</code> in downstream DTS decompiled also works


= See also =
= See also =
=== General ===
* [[Mainlining FAQ]] various information collected from #postmarketOS
* Guides in [[Qualcomm mainline porting]]
* [[User:Alexeymin/Kernel_development_in_chroot_using_abuild]]
* [[Troubleshooting:kernel]]
* [[Submitting_Patches#Linux]] guide on submitting patches to Linux
* [https://gitlab.postmarketos.org/postmarketOS/pmbootstrap/-/issues/91 #91: &quot;The Mainline Kernel&quot;]
=== Misc ===
* [http://kroah.com/log/blog/2018/02/05/linux-kernel-release-model/ Linux Kernel Release Model] (reasons why we should all be using mainlined kernels)
* [https://nickdesaulniers.github.io/blog/2017/05/16/submitting-your-first-patch-to-the-linux-kernel-and-responding-to-feedback/ Submitting your first patch to the Linux kernel and responding to feedback]
* [https://redmine.replicant.us/projects/replicant/wiki/Upstream Replicant upstream kernel and upstream bootloader wiki]
* [https://www.youtube.com/watch?v=LPG4EkXK9Us Linux Foundation youtube video] ARM64 SoC Linux Support Check-List (what needs to be done to get an arm64 soc to work on mainline)
== Other guides ==
* [https://forum.xda-developers.com/android/software-hacking/reference-how-to-upstream-android-kernel-t3626913 A XDA thread] about How to get an Android kernel up to date with Linux upstream
* {{issue|191|pmaports}} Getting started tips from zhuowei
* [https://elinux.org/Device_Tree_Usage Device Tree usage] on elinux.org
* [https://elinux.org/Device_Tree_Reference Device Tree reference] on elinux.org
* [https://elixir.bootlin.com/linux/latest/source/Documentation/devicetree Documentation of devicetree bindings] on bootlin.com
* opendata26 walking alibabzo through mainlining aries [https://matrix.to/#/!clcCCNrLZYwdfNqkkR:disroot.org/$152104340146547HXnql:matrix.org]
== Device specific ==
* {{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)
* Blog about [http://elektranox.org/droid4/ mainline kernel support for the Motorola Droid 4]
* [http://n900.elektranox.org/index.html Debian on N900]
* [https://developer.sony.com/develop/open-devices/guides/kernel-compilation-guides/how-to-build-mainline-linux-kernel-for-xperia-devices Build Mainline for Xperia devices]
* [https://talk.maemo.org/showthread.php?t=99357 Documenting devices with mainline Linux support] A thread on maemo forums, provide a list of mainline device DTs
== SoC-specific ==
* [http://linux-sunxi.org/Linux_mainlining_effort Allwinner mainline effort]
* [https://github.com/efidroid/projectmanagement/wiki/%5BReference%5D-Chipsets probably a list of which qualcomm socs are similar]
== Display ==
* [https://github.com/freedreno/freedreno/wiki/DSI-Panel-Driver-Porting Freedreno wiki: Display driver porting]
* [http://elixir.free-electrons.com/linux/v3.17/source/include/video/mipi_display.h#L28 List of DTSI -> panel driver function translations]
[[Category:Technical Reference]]


[[Category:Guide]]
[[Category:Guide]]

Latest revision as of 06:48, 3 November 2024

Note General information about Mainlining is on the Mainlining page.

Introduction

Note Please have realistic expectations: Booting mainline even if nothing else is working is already a great achievement!

The kernel fork used in Android is different from the kernel at kernel.org. The former is downstream kernel (aka. baseline kernel) and the latter is upstream kernel. Carrying around forks of the kernel is not sustainable as it becomes impossible to provide security patches after a short time. The only way to truly fix this for a device is mainlining it. Making a device boot with the upstream kernel is colloquially referred to as mainlining.

When it comes to postmarketOS, we want to get as many devices working with one shared kernel package (based on upstream).

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!


Getting Help

Read Mainlining_FAQ first to check if there provides some tips for your progress.

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.


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.

Note 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.

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.

Kernel packaging

To make the kernel work with multiple devices, it no longer appends the dtb file to the kernel image. Instead, it puts all dtb files for the current architecture in /usr/share/dtb. The postmarketos-mkinitfs package appends the dtb file defined in the deviceinfo to the linux image in the boot partition.

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.

Note There are some second stage bootloader (like lk2nd) for dealing this kind of hacks.

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.

Device tree source

To make your device boot, you will need a device tree source (dts) file (which will get compiled to a dtb mentioned above). The guide would tell you about how to make a device tree from existing file provided by soc.

Preparation

Before proceeding, make sure that you know that your device is supported by the mainline kernel. Otherwise use the source code of a vendor's fork of the kernel, which is known to work as described in the porting guide.

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.postmarketos.org/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.)

envkernel.sh has grown to be quite powerful, read more about it at the compiling kernels with envkernel.sh wiki page.

Reminder

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.


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.

Before start

If you are having trouble, ask in the channel. When it comes to DT, it's best to start with one that already works. Look under arch/{arm,arm64}/boot/dts in the kernel source code for relevant files (browse online) with your device's codename. You may want to use source code host services (GitLab, github, etc.) to search for your dts for your specific SoC.

The general file naming is $chipset_vendor-$chipset-$vendor-$codename.dts. Examples:

  • qcom-msm8974-lge-nexus5-hammerhead.dts
  • qcom-msm8974-sony-xperia-honami.dts
  • qcom-apq8064-sony-xperia-yuga.dts
  • qcom-apq8064-asus-nexus7-flo.dts

When you don't have a result, try to find a dts file with the same chipset as your device (e.g. msm8974). Try to create a new one for your device based on that by creating a patch for linux-postmarketos-stable.

If there is not even a dts file for the same chipset, you need to create one from scratch (no idea how to do that, good luck and please extend the wiki). If you have no idea but the faith, you may check the #Other guides about DT at the page below to pick up some ideas.

Start with an existing file

Now we have got source DT qcom-apq8064-asus-nexus7-flo.dts for our target device apq8064-lge-nexus4-mako. Copy it and rename to your device name.

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/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"  # See Submitting_Patches for how to write commit messages


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

there is also a defconfig in linux-postmarketos-qcom that used by postmarketOS, you can run pmbootstrap kconfig edit postmarketos-qcom to inspect it. After you get the correct defconfig for your device:

  1. adjust the kernel config to add the drivers for the device if they are not enabled yet.
  2. Set as many drivers to build as external module as possible so the main vmlinuz filesize doesn't increase too much.
  3. Replace qcom with the kernel config you want to modify (see ls aports/main/linux-postmarketos-*).


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 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 swig && pmbootstrap chroot -- pip3 install dtschema
$ make qcom/sdm845-oneplus-fajita.dtb # work since 5.16 kernels, DTB can be found in the directory arch/{arm,arm64}/boot/dts/

Deal with packages

Init

Note 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

In general, you would need to create a new kernel package for your device. You can do following to create a new kernel package:

  1. copy a existing kernel package under <workdir>/cache_git/device/{community testing}/linux-*, rename it to your device model, and place it under testing folder mentioned above.
  2. create a new package with pmbootstrap. You would need to create a device package and a linux-*<package> if your device is not in pmaports.

After creating kernel package, specifying device to use the new kernel package (or existing mainline kernel package), use the command below to build the kernel:

pmbootstrap build --envkernel linux-postmarketos-<soc> # or linux-<brand>-<device> which is your package name

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.

Prepare for production

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 during pmbootstrap install or pmbootstrap build --force then you will most likely be editing this
    • _repository="linux"
    • _commit="<kernel commit number>"
    • in source="" change the following:
    • replace . downstreamkernel_prepare with cp "$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.postmarketos.org/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 and deviceinfo_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>


See also

General

Misc


Other guides


Device specific

SoC-specific

Display