Skip to content
This repository has been archived by the owner. It is now read-only.

New kernel porting workflow (incl. APKBUILD template, refactor existing device/linux- APKBUILDs) #688

Open
ollieparanoid opened this Issue Oct 3, 2017 · 8 comments

Comments

Projects
None yet
4 participants
@ollieparanoid
Copy link
Member

commented Oct 3, 2017

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)
  • (documentation, no PR): adjust the porting guide to use that instead of manually copying APKBUILDs
  • when we detect the "qcdt" (appended dtb to the boot.img instead of the kernel) in bootimg analyzing, add this and that to the generated linux APKBUILD (#1125)
  • refactor deviceinfo and device-* package template
    • Remove external_disk_install and external_disk, only use external_storage instead (#1301)
    • Make all deviceinfo files like the template (changes)
  • create a postmarketos-kernelport package, provides a default_prepare_kernelport function with the easy features from here
    • it checks if the pkgver is 3.x.x
    • it uses default_prepare to apply patches, that provides a common prepare() function which verifies the pkgver, applies all patches via default_prepare
    • it removes all -Werror flags from Makefiles (as in linux-ouya-ouya)
    • it runs silentoldconfig with yes
    • depend on that package and use default_prepare_kernelport in the linux APKBUILD generated by pmbootstrap init
  • refactor the whole linux- APKBUILD template (as generated by pmbootstrap init) based on what is here
    • add a wiki page describing everything
    • add the shorturl, as used in the APKBUILD
  • add additional checks to default_prepare_kernelport, which depend on the refactoring (and only execute them for the refactored APKBUILDs, add a _templatever=1 variable for that).
    • use that version to show when the package uses an outdated template
  • put all patches in a shared folder (#542)
  • implement 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.
  • add a check that finds the busybox binary, and checks if the kernel works for isorec (e.g. own init script)
  • do the same thing for qcdt
  • refactor all existing device/linux- packages to use the template

Read 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:

  • using abuild's default_prepare for applying the patches (like @drebrez did, example)
  • include commonly used patches by default (fix return address, timeconst fix, msm driver fix). it's much easier to remove patches that do not apply than finding which patch is necessary to fix a specific compilation error.
  • using "_commit" instead of "_hash", because "_hash" is confusing
  • use .tar.gz (not zip!) sources from LineageOS
  • add useful comments everywhere
  • in general: throw out everything that we do not need
  • use KBUILD_BUILD_VERSION="$((pkgrel + 1 ))-postmarketOS" instead of ...-Alpine
  • Instead of make 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)
  • Do not depend on postmarketos-mkinitfs, we already pull that in with postmarketos-base
  • Automatically use zImage-dtb if found
  • Convert the GCC6 header file to a patch file
  • patching out -Werror* by default in prepare() (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!).

@MartijnBraam

This comment has been minimized.

Copy link
Member

commented Oct 3, 2017

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

@ollieparanoid ollieparanoid changed the title Create a kernel package template Create a kernel package template, then adjust existing packages Oct 4, 2017

@ollieparanoid

This comment has been minimized.

Copy link
Member Author

commented Oct 7, 2017

Alright, I have given this a lot of thought and came up with a whole new porting workflow around this template:

  1. pmbootstrap init: user types in new device
  2. Do you want to start a new port to $vendor-$name? [Y/n] y
  • To prevent typos in the device name causing the wizard to run by accident
  • (We could also ask for the architecture here)
  1. OK, copying default files
  • Creates the device-{device} and linux-{device} package (see template below, {device} gets automatically replaced in the template) with extended aportgen code
  • Displays steps on how to continue with the port, and a link to the porting guide.

Furthermore, 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}')'
@ollieparanoid

This comment has been minimized.

Copy link
Member Author

commented Oct 21, 2017

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:

  • In prepare, check the kernel source for a busybox binary. If it was found, we probably have an isorec device, and the APKBUILD should depend on busybox-static-$arch and bring its own init.sh file.
  • Actually, why don't we put the whole custom code in 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:

aports
	.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
@z3ntu

This comment has been minimized.

Copy link
Member

commented Oct 21, 2017

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.

@ollieparanoid

This comment has been minimized.

Copy link
Member Author

commented Oct 21, 2017

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.

@ollieparanoid ollieparanoid changed the title Create a kernel package template, then adjust existing packages New kernel porting workflow (incl. APKBUILD template, refactor existing device/linux- APKBUILDs) Oct 21, 2017

@ollieparanoid

This comment has been minimized.

Copy link
Member Author

commented Oct 21, 2017

Updated the initial post with a TODO list.

MayeulC added a commit to MayeulC/pmbootstrap that referenced this issue Jan 15, 2018

pmbootstrap: add qcdt generation to the linux aportgen APKBUILDs
This checks the next box in postmarketOS#688
When the device has bootimg_qcdt set to true, the following is done to
the linux APKBUILD:

 * Add dtbtool to makedepends
 * Call dtbTool during build() to generate dt.img
 * Add the generated dt.img in the package's boot/dt.img

Signed-off-by: Mayeul Cantan <mayeul.cantan@gmail.com>

MayeulC added a commit to MayeulC/pmbootstrap that referenced this issue Jan 15, 2018

pmbootstrap: add qcdt generation to the linux aportgen APKBUILDs
This checks the next box in postmarketOS#688
When the device has bootimg_qcdt set to true, the following is done to
the linux APKBUILD:

 * Add dtbtool to makedepends
 * Call dtbTool during build() to generate dt.img
 * Add the generated dt.img in the package's boot/dt.img

Signed-off-by: Mayeul Cantan <mayeul.cantan@gmail.com>

MayeulC added a commit to MayeulC/pmbootstrap that referenced this issue Jan 16, 2018

pmbootstrap: add qcdt generation to the linux aportgen APKBUILDs
This checks the next box in postmarketOS#688
When the device has bootimg_qcdt set to true, the following is done to
the linux APKBUILD:

 * Add dtbtool to makedepends
 * Call dtbTool during build() to generate dt.img
 * Add the generated dt.img in the package's boot/dt.img

This commit also changes the device parser so that it parses "true" and
"false" (the strings) as True and False (the Python booleans).

Signed-off-by: Mayeul Cantan <mayeul.cantan@gmail.com>

MayeulC added a commit to MayeulC/pmbootstrap that referenced this issue Jan 16, 2018

pmbootstrap: add qcdt generation to the linux aportgen APKBUILDs
This checks the next box in postmarketOS#688
When the device has bootimg_qcdt set to true, the following is done to
the linux APKBUILD:

 * Add dtbtool to makedepends
 * Call dtbTool during build() to generate dt.img
 * Add the generated dt.img in the package's boot/dt.img

This commit also changes the device parser so that it parses "true" and
"false" (the strings) as True and False (the Python booleans).

Signed-off-by: Mayeul Cantan <mayeul.cantan@gmail.com>

MayeulC added a commit to MayeulC/pmbootstrap that referenced this issue Jan 16, 2018

pmbootstrap: add qcdt generation to the linux aportgen APKBUILDs
This checks the next box in postmarketOS#688
When the device has bootimg_qcdt set to true, the following is done to
the linux APKBUILD:

 * Add dtbtool to makedepends
 * Call dtbTool during build() to generate dt.img
 * Add the generated dt.img in the package's boot/dt.img

This commit also changes the device parser so that it parses "true" and
"false" (the strings) as True and False (the Python booleans).

Signed-off-by: Mayeul Cantan <mayeul.cantan@gmail.com>

MayeulC added a commit to MayeulC/pmbootstrap that referenced this issue Jan 16, 2018

pmbootstrap: add qcdt generation to the linux aportgen APKBUILDs
This checks the next box in postmarketOS#688
When the device has bootimg_qcdt set to true, the following is done to
the linux APKBUILD:

 * Add dtbtool to makedepends
 * Call dtbTool during build() to generate dt.img
 * Add the generated dt.img in the package's boot/dt.img

This commit also changes the device parser so that it parses "true" and
"false" (the strings) as True and False (the Python booleans).

Signed-off-by: Mayeul Cantan <mayeul.cantan@gmail.com>

MayeulC added a commit to MayeulC/pmbootstrap that referenced this issue Jan 16, 2018

pmbootstrap: add qcdt generation to the linux aportgen APKBUILDs
This checks the next box in postmarketOS#688
When the device has bootimg_qcdt set to true, the following is done to
the linux APKBUILD:

 * Add dtbtool to makedepends
 * Call dtbTool during build() to generate dt.img
 * Add the generated dt.img in the package's boot/dt.img

Signed-off-by: Mayeul Cantan <mayeul.cantan@gmail.com>

MayeulC added a commit to MayeulC/pmbootstrap that referenced this issue Jan 16, 2018

pmbootstrap: add qcdt generation to the linux aportgen APKBUILDs
This checks the next box in postmarketOS#688
When the device has bootimg_qcdt set to true, the following is done to
the linux APKBUILD:

 * Add dtbtool to makedepends
 * Call dtbTool during build() to generate dt.img
 * Add the generated dt.img in the package's boot/dt.img

Signed-off-by: Mayeul Cantan <mayeul.cantan@gmail.com>

MayeulC added a commit to MayeulC/pmbootstrap that referenced this issue Jan 16, 2018

pmbootstrap: add qcdt generation to the linux aportgen APKBUILDs
This checks the next box in postmarketOS#688
When the device has bootimg_qcdt set to true, the following is done to
the linux APKBUILD:

 * Add dtbtool to makedepends
 * Call dtbTool during build() to generate dt.img
 * Add the generated dt.img in the package's boot/dt.img

Signed-off-by: Mayeul Cantan <mayeul.cantan@gmail.com>

ollieparanoid added a commit that referenced this issue Jan 17, 2018

pmbootstrap: add qcdt generation to the linux aportgen APKBUILDs (#1125)
* pmbootstrap: __config_.py - update the deviceinfo_attributes table

Add missing attributes:
 * "screen_width"
 * "screen_height"
 * "dev_touchscreen"
 * "dev_touchscreen_calibration"
 * "dev_keyboard"
 * "bootimg_qcdt"

Reorder the list to correspond to pmb/aportgen/device.py

Add a comment in the aforementioned file to avoid forgetting to update
this list.

Signed-off-by: Mayeul Cantan <mayeul.cantan@gmail.com>

* pmbootstrap: add qcdt generation to the linux aportgen APKBUILDs

This checks the next box in #688
When the device has bootimg_qcdt set to true, the following is done to
the linux APKBUILD:

 * Add dtbtool to makedepends
 * Call dtbTool during build() to generate dt.img
 * Add the generated dt.img in the package's boot/dt.img

Signed-off-by: Mayeul Cantan <mayeul.cantan@gmail.com>

PureTryOut added a commit that referenced this issue Feb 21, 2018

pmbootstrap: add qcdt generation to the linux aportgen APKBUILDs (#1125)
* pmbootstrap: __config_.py - update the deviceinfo_attributes table

Add missing attributes:
 * "screen_width"
 * "screen_height"
 * "dev_touchscreen"
 * "dev_touchscreen_calibration"
 * "dev_keyboard"
 * "bootimg_qcdt"

Reorder the list to correspond to pmb/aportgen/device.py

Add a comment in the aforementioned file to avoid forgetting to update
this list.

Signed-off-by: Mayeul Cantan <mayeul.cantan@gmail.com>

* pmbootstrap: add qcdt generation to the linux aportgen APKBUILDs

This checks the next box in #688
When the device has bootimg_qcdt set to true, the following is done to
the linux APKBUILD:

 * Add dtbtool to makedepends
 * Call dtbTool during build() to generate dt.img
 * Add the generated dt.img in the package's boot/dt.img

Signed-off-by: Mayeul Cantan <mayeul.cantan@gmail.com>
@drebrez

This comment has been minimized.

Copy link
Member

commented Apr 26, 2018

@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?

@ollieparanoid

This comment has been minimized.

Copy link
Member Author

commented Apr 26, 2018

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.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
You can’t perform that action at this time.