TODO each major item is for a standalone PR, see below for implementation details. This list is a bit dated now, consider if the changes still make sense or have been implemented in another way already before working on them.
pmbootstrap init: when specifying a new device, ask for confirmation and create default (device-, linux-) packages (base on linux-lg-mako for now)linux APKBUILD (#1125)external_disk_install and external_disk, only use external_storage instead (#1301)postmarketos-kernelport package, provides a default_prepare_kernelport function with the easy features from herepkgver is 3.x.xdefault_prepare to apply patches, that provides a common prepare() function which verifies the pkgver, applies all patches via default_preparelinux-ouya-ouya)default_prepare_kernelport in the linux APKBUILD generated by pmbootstrap initpmbootstrap init) based on what is heredefault_prepare_kernelport, which depend on the refactoring (and only execute them for the refactored APKBUILDs, add a _templatever=1 variable for that).pmbootstrap autopatch, which automatically tries to apply each patch to the source, and updates the APKBUILD to include the patches that work with the kernel.device/linux- packages to use the templateRead on for lots of brainstorming, and please contribute ideas and tell us if something doesn't make sense!
It would be nice if we had modern template somewhere in the code tree for new kernels with the following:
default_prepare for applying the patches (like @drebrez did, example)KBUILD_BUILD_VERSION="$((pkgrel + 1 ))-postmarketOS" instead of ...-Alpinemake olddefconfig, use yes "" | make olddefconfig, so the user does not have to accept the defaults manually. (make silentoldconfig does the same and is better, however this is not available in older kernels)postmarketos-mkinitfs, we already pull that in with postmarketos-basezImage-dtb if foundprepare() (as I did for linux-ouya-ouya):# Remove all -Werror statements
find . -type f -name Makefile -print0 | xargs -0 sed -i 's/-Werror-/-W/g'
find . -type f -name Makefile -print0 | xargs -0 sed -i 's/-Werror//g'
After that is done, we could adjust the existing kernel packages to that new template (in a second PR!).
I think a small improvement could to remove $_flavor for the default source url and use a $_repository variable containing the github identifier (like LineageOS/android_kernel_lge_bullhead), with the $_repository variable and the $_commit variable together you can generate the correct source .tar.gz url and the correct $kbuilddir variable every time
Alright, I have given this a lot of thought and came up with a whole new porting workflow around this template:
pmbootstrap init: user types in new devicedevice-{device} and linux-{device} package (see template below, {device} gets automatically replaced in the template) with extended aportgen codeFurthermore, I would create an empty file as kernel config file, and, as soon as the user runs pmbootstrap menuconfig for the first time, copy the appropriate default config. That way we don't need to store this information in a comment, but in an actually used variable, and we save the user from manually pulling out that file and putting it in the right place.
The guide in the wiki would need to be adjusted, and the shortlinks would need to be created.
Here's a draft (with bugs, not tested) of the kernel APKBUILD. Variables, that the user needs to customize have been moved to the top. This is to share my idea, current progress and to collect feedback, I'll make a proper PR once this is more polished.
# postmarketOS kernel APKBUILD
# Reference: <https://postmarketos.org/kAPKBUILD>
_flavor="{device}"
pkgver="3.x.x"
pkgrel="0"
arch="armhf"
# Kernel source and patches
# Update the checksums at the bottom with 'pmbootstrap checksum {device}'
_defconfig="arch/arm/configs/CHANGEME"
_commit="ffffffffffffffffffffffffffffffffffffffff"
_repo="kernel_msm"
_project="LineageOS"
url="https://github.com/${_project}/${_repo}"
source="
$pkgname-$_commit.tar.gz::${url}/archive/${_commit}.tar.gz
config-${flavor}.${arch}
00_compiler-gcc6.patch
01_fix_return_address.patch
# ... put all patches, that are necessary for at least two devices here, or maybe
# even all patches. It's easy to remove a patch, that does not apply and it can be
# done before even compiling the code. Much better than getting a strange error
# and figuring out which patch is necessary!
"
# Standard code below
pkgname="linux-$_flavor"
pkgdesc="Kernel for $_flavor"
license="GPL2"
makedepends="perl sed installkernel bash gmp-dev bc linux-headers elfutils-dev"
options="!strip !check !tracedeps"
builddir="${srcdir}/${_repo}-${_commit}"
[ "$arch" == "armhf" ] && _carch="arm"
[ "$arch" == "aarch64" ] && _carch="arm64"
HOSTCC="${CC:-gcc}"
HOSTCC="${HOSTCC#${CROSS_COMPILE}}"
_config="config-${_flavor}.${arch}"
prepare() {
# Verify builddir
if [ ! -d "$builddir" ]; then
echo "ERROR: The 'builddir' variable does not point to a valid"
echo " folder inside the kernel source archive: '$builddir'"
echo " Use 'pmbootstrap chroot' to inspect the contents of the"
echo " extracted package (in /home/user/build/src), then adjust"
echo " the 'builddir' in '$pkgname/APKBUILD' accordingly."
return 1
fi
cd "$builddir"
# Verify pkgver, _defconfig, _carch
if [ "$pkgver" == "3.x.x" ]; then
echo "ERROR: The pkgver is not the same as the kernel version."
echo " Please adjust it in '$pkgname/APKBUILD':"
echo " <https://postmarketos.org/kernelversion>"
return 1
fi
if [ ! -e "$_defconfig" ]; then
echo "ERROR: Defconfig not found inside the builddir. Please"
echo " adjust the 'defconfig' variable accordingly. See"
echo " <https://postmarketos.org/defconfig> for information on"
echo " how to find it inside the source tree."
return 1
fi
if [ -z "$_carch" ]; then
echo "ERROR: _carch variable is not set in '$pkgname/APKBUILD'."
return 1
fi
# Apply .patch files
if ! default_prepare; then
echo "ERROR: Not all patches could be applied! If you have just"
echo " started a new postmarketOS device port, this is normal."
echo " Please remove the patches, that did not get applied"
echo " correctly from the 'source=' variable in the APKBUILD"
echo " and delete these files from the $pkgname folder."
return 1
fi
# Start with the defconfig
if ! grep -q "# Automatically generated file" "$_config"; then
msg "Config $_config is empty, starting with $_defconfig"
cp "$_defconfig" "$_config"
fi
# Prepare kernel config ('yes ""' for kernels lacking olddefconfig)
cp "$srcdir"/"$_config" "$builddir"/.config
yes "" | make ARCH="$_carch" HOSTCC="$HOSTCC" silentoldconfig
}
menuconfig() {
cd "$builddir"
make ARCH="$_carch" menuconfig
cp .config "$startdir"/$_config
}
build() {
unset LDFLAGS
make ARCH="$_carch" CC="${CC:-gcc}" \
KBUILD_BUILD_VERSION="$((pkgrel + 1 ))-postmarketOS"
}
package() {
# Prefer zImage-dtb, fallback: zImage
cd "$builddir/arch/$_carch/boot/"
_zimg="zImage-dtb"
[ ! -e "$_zimg" ] && _zimg="zImage"
# Package vmlinuz and kernel.release
install -Dm644 "$_zimg" "$pkgdir/boot/vmlinuz-$_flavor"
install -Dm644 "$builddir/include/config/kernel.release" \
"$pkgdir/usr/share/kernel/$_flavor/kernel.release"
}
sha512sums="(Update with 'pmbootstrap checksum linux-{device}')'
I know this starts to look like one never ending issue with things to improve. But we really can make the porting process a lot more convenient, and if we go through the trouble and change it, I want to make it as good as possible. And we can break these ideas down into small TODO items, which may be usable on each own, before actually implementing anything.
More brainstorming:
busybox-static-$arch and bring its own init.sh file.prepare in an extra file, and source that? So we don't have to adjust it in every kernel package if we want to change something.And one more idea. @PabloCastellano proposed that we keep all patches in one directory #542. I said it was not worth the effort from my perspective. But if we're completely re-thinking the porting process anyway, I imagine to have a pmbootstrap autopatch $vendor-$name command. That would try to apply all patches from the folder automatically, and then create the necessary symlinks for all patches, that apply cleanly.
So we could keep the kernel patches in an extra folder and add symlinks:
.old-kernel-patches
0001-gcc6-...
0002-kgsl-...
0003-...
0004-...
README.md
...
main
device
linux-lg-mako
p/ # symlink to the .old-kernel-patches folder
...
The new porting workflow would look like this:
pmbootstrap init
... create new aport? [Y/n] .
-> create device- package
-> create linux- package
next steps in manual:
(git config if necessary)
git commit -m "my-device: start new port"
(adjust device package)
git commit -m "my-device: adjust device package"
(adjust kernel build)
git commit -m "my-device: adjust kernel package"
pmbootstrap autopatch $kernel # < ---- !!!
git commit -m "my-device: select kernel patches"
pmbootstrap kconfig_check # automatically uses the defconfig if the config is empty!
pmbootstrap menuconfig $kernel
git commit -m "my-device: make kconfig_check happy"
pmbootstrap checksum $kernel
pmbootstrap build $kernel
I am all for it, but that sounds like a lot like overengineering to be honest.
I think creating a good porting guide and explaining why and what for everything (e.g. appended dtb or qcdt) would be a better investment of time and effort.
The appended dtb for example would already be handled with these two lines (see the APKBUILD above, untested):
_zimg="zImage-dtb"
[ ! -e "$_zimg" ] && _zimg="zImage"
Yes, for the qcdt it won't be that easy, but if we found a pattern in the kernel sources, from which we know whether we have the "qcdt" thing or not, then we could stuff that in the prepare() and make the porting process much easier again, which lowers the entry barrier and will probably lead to more contributions coming from new people in the long run.
(I realize, that these were just randoms examples.)
Thanks for the feedback! I will break it down in small components, that are usable on their own, make PRs for them, and keep an eye on how much time I spend with implementing them. If it turns out to be too much, I'll rather skip the implementation and add more relevant steps to the porting guide as you proposed.
Updated the initial post with a TODO list.
@ollieparanoid in the steps you mention to create a postmarketos-kernelport package that provides a default_prepare_kernelport.
Since we already have the devicepkg-dev with some utility functions for the APKBUILD, what about creating a generic postmarketos-pkg-helper (or with better name) that contains all the scripts we need to simplify the creation of the device and kernel packages?
Having one package that has both devicepkg and downstream kernel utility functions sounds great!
What if we keep the devicepkg-dev name though, and add scripts like downstreamkernel_prepare to it (also maybe with a better name)?
It isn't part of the device package, but it is related to the device specific packaging, so the naming isn't that far fetched and we don't need to think of a new name then.
Most helpful comment
I think a small improvement could to remove
$_flavorfor the default source url and use a$_repositoryvariable containing the github identifier (like LineageOS/android_kernel_lge_bullhead), with the$_repositoryvariable and the$_commitvariable together you can generate the correct source .tar.gz url and the correct$kbuilddirvariable every time