Downstream kernel specific package: Difference between revisions
GrantM11235 (talk | contribs) →GCC version: Use upstream gcc6 https://gitlab.com/postmarketOS/pmaports/merge_requests/84 |
LongnoseRob (talk | contribs) update to gitlab.postmarketos.org |
||
(20 intermediate revisions by 11 users not shown) | |||
Line 1: | Line 1: | ||
Unless a device has been [[The Mainline Kernel|mainlined]], we need to package the | Unless a device has been [[The Mainline Kernel|mainlined]], we need to package the downstream kernel (also called "vendor kernel"). This is the reference for the {{alpine|APKBUILD}} files of vendor kernels. | ||
== Generate a template == | == Generate a template == | ||
Line 9: | Line 9: | ||
To recreate your vendor kernel aport on top of the latest (and therefore most readable) template, do the following steps: | To recreate your vendor kernel aport on top of the latest (and therefore most readable) template, do the following steps: | ||
<syntaxhighlight lang="shell-session"> | <syntaxhighlight lang="shell-session"> | ||
$ mv aports/device/linux-wiki-example | $ mv aports/device/testing/linux-wiki-example /tmp/linux-wiki-example-old | ||
$ pmbootstrap aportgen linux-wiki-example | $ pmbootstrap aportgen linux-wiki-example | ||
(now adjust the new aport to use the sources and patches from the "-old" | $ # (now adjust the new aport to use the sources and patches from the "-old" dir, rename $pkgname from linux-wiki-example to linux-wiki-example-old) | ||
$ pmbootstrap checksum linux-wiki-example | $ pmbootstrap checksum linux-wiki-example | ||
$ pmbootstrap build --force linux-wiki-example | $ pmbootstrap build --force linux-wiki-example | ||
(now test it on your device and make sure it boots, e.g. with 'pmbootstrap zap', 'pmbootstrap install', 'pmbootstrap flasher boot') | $ # (now test it on your device and make sure it boots, e.g. with 'pmbootstrap zap', 'pmbootstrap install', 'pmbootstrap flasher boot') | ||
$ pmbootstrap pkgrel_bump linux-wiki-example | $ pmbootstrap pkgrel_bump linux-wiki-example | ||
$ git add -A | $ git add -A | ||
Line 22: | Line 21: | ||
== downstreamkernel_prepare == | == downstreamkernel_prepare == | ||
Newly generated | <!-- short link: https://postmarketos.org/downstreamkernel-prepare --> | ||
Newly generated downstream kernel packages use the <code>downstreamkernel_prepare</code> script. That way we can share code between the APKBUILDs, so it is less redundant. To see what the function does, [https://gitlab.postmarketos.org/postmarketOS/pmaports/blob/master/main/devicepkg-dev/downstreamkernel_prepare.sh read the source over here]. | |||
It is supposed to be ''sourced'', so the content of the script gets executed ''in the current shell''. This is done with the dot in-front of the script name: | |||
<syntaxhighlight lang="bash"> | |||
prepare() { | |||
default_prepare | |||
. downstreamkernel_prepare | |||
} | |||
</syntaxhighlight> | |||
Note that this behavior had changed in {{MR|1084|pmaports}}. Out of tree device ports may not have been adjusted yet and still pass arguments to the script. This is not supported anymore, adjust them like written above or consider modernizing the whole pmaport as explained earlier in this article. | |||
== GCC version == | == GCC version == | ||
The kernel gets compiled with {{wikipedia|GCC}}. Alpine Linux has been shipping version GCC 6 for a long time, but changed the default GCC version to GCC 8 in September 2018. It was discovered that at least one vendor kernel does not boot when compiled with GCC 8 ({{issue|103|pmaports}}), so we ended up packaging GCC 6 side by side with GCC 8. All existing 3.x vendor kernels that were packaged have been adjusted to use GCC 6 at this point in time, just to make sure we don't introduce any breakage there. The default for new packages is using the current GCC version that is packaged in Alpine (at time of writing: GCC 8). | The kernel gets compiled with {{wikipedia|GCC}}. Alpine Linux has been shipping version GCC 6 for a long time, but changed the default GCC version to GCC 8 in September 2018. It was discovered that at least one vendor kernel does not boot when compiled with GCC 8 ({{issue|103|pmaports}}), so we ended up packaging GCC 6 side by side with GCC 8. All existing 3.x vendor kernels that were packaged have been adjusted to use GCC 6 at this point in time, just to make sure we don't introduce any breakage there. The default for new packages is using the current GCC version that is packaged in Alpine (at time of writing: GCC 8). | ||
=== Use GCC 4 === | |||
Follow the GCC 6 instructions below, but replace 6 with 4 everywhere. | |||
=== Use GCC 6 === | === Use GCC 6 === | ||
If your new kernel port does not boot at all, please try to compile it with GCC 6 and see if it works then. | If your new kernel port does not boot at all, or [https://wiki.postmarketos.org/wiki/Troubleshooting:kernel#Kernel_compilation:_Error:_.err_encountered_in_assembler_messages it doesn't even compile], please try to compile it with GCC 6 and see if it works then. | ||
To do that, open <code>aports/device/linux-[your-device]/APKBUILD</code> and '''add these lines:''' | |||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
Line 43: | Line 49: | ||
if [ "${CC:0:5}" != "gcc6-" ]; then | if [ "${CC:0:5}" != "gcc6-" ]; then | ||
CC="gcc6-$CC" | CC="gcc6-$CC" | ||
HOSTCC="gcc | HOSTCC="gcc6-gcc" | ||
CROSS_COMPILE="gcc6-$CROSS_COMPILE" | CROSS_COMPILE="gcc6-$CROSS_COMPILE" | ||
fi | fi | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Then add <code>gcc6</code> to the kernel's <code>makedepends</code> line. | between <code>makedepends=</code> and <code># Source</code> lines. | ||
'''Then add''' <code>gcc6</code> to the kernel's <code>makedepends</code> line. | |||
<span style="font-size:80%; font-style: italic"> | <span style="font-size:80%; font-style: italic"> | ||
Line 55: | Line 63: | ||
=== Use the newest GCC from Alpine === | === Use the newest GCC from Alpine === | ||
Let's say you are using a device that has already been packaged, and you want to figure out if it also boots when compiled with a newer compiler. | Let's say you are using a device that has already been packaged, and you want to figure out if it also boots when compiled with a newer compiler. Just removing HOSTCC vars and references to them should be enough: | ||
''' | '''Remove these lines:''' | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
# Compiler: this kernel was only tested with GCC6. Feel free to make a merge | # Compiler: this kernel was only tested with GCC6. Feel free to make a merge | ||
Line 64: | Line 72: | ||
if [ "${CC:0:5}" != "gcc6-" ]; then | if [ "${CC:0:5}" != "gcc6-" ]; then | ||
CC="gcc6-$CC" | CC="gcc6-$CC" | ||
HOSTCC="gcc | HOSTCC="gcc6-gcc" | ||
CROSS_COMPILE="gcc6-$CROSS_COMPILE" | CROSS_COMPILE="gcc6-$CROSS_COMPILE" | ||
fi | fi | ||
</syntaxhighlight> | </syntaxhighlight> | ||
with the | And remove the mention of <code>HOSTCC</code> in invocation of <code>downstreamkernel_prepare</code>. | ||
Then remove the <code>gcc6</code> package from the <code>makedepends</code> line. | |||
Afterwards, remove the <code>compiler-gcc6.h</code> file from the aport dir, and from the <code>source</code> line. Instead you will probably need [https://gitlab.postmarketos.org/postmarketOS/pmaports/issues/103#note_104926654 other patches as linked here]. First try compiling without patches, then add one patch at a time to fix a specific problem. As usually, with <code>pmbootstrap checksum</code>, you can regenerate the checksums at the bottom of the file, this needs to be done whenever you change <code>source</code>. | |||
When you made it boot successfully, please increase the <code>pkgrel</code> and make a merge request. | |||
== Using GNU Make 3.x == | |||
GNU Make sometimes introduce backward-incompatible changes. While recent versions of Linux kernel requires GNU Make 4.x, building older kernels fails with GNU Make 4.x but succeeds with GNU Make 3.x. | |||
To use GNU Make 3.81, open <code>aports/device/linux-[your-device]/APKBUILD</code> and '''add these lines:''' | |||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
# | # GNU Make 3.81 | ||
PATH="/usr/make3.81/bin:$PATH" | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Then | between <code>makedepends=</code> and <code># Source</code> lines. | ||
'''Then add''' <code>make3.81</code> to the kernel's <code>makedepends</code> line. | |||
== Using a specific kernel image == | |||
By default [https://gitlab.postmarketos.org/postmarketOS/pmaports/-/blob/master/main/devicepkg-dev/downstreamkernel_package.sh downstreamkernel_package.sh] looks for a few kernel image files such as <code>Image.gz-dtb</code> and <code>*zImage</code>, but for various reasons you may want/need to look for something else; in these situations set <code>KERNEL_IMAGE_NAME</code> similar to the following: | |||
<syntaxhighlight lang="bash"> | |||
package() { | |||
KERNEL_IMAGE_NAME="Image.gz" downstreamkernel_package \ | |||
"$builddir" "$pkgdir" "$_carch" "$_flavor" "$_outdir" | |||
} | |||
</syntaxhighlight> | |||
== heimdall-isorec == | == heimdall-isorec == | ||
If you have a device that only boots with [[Deviceinfo_flash_methods#heimdall-isorec|heimdall-isorec]], you will need to adjust your linux APKBUILD as follows: | If you have a device that only boots with [[Deviceinfo_flash_methods#heimdall-isorec|heimdall-isorec]], you will need to adjust your linux APKBUILD as follows: | ||
* add <code>busybox-static-armhf</code> to makedepends | * add <code>busybox-static-armhf</code> to makedepends | ||
* copy the "init" file from [https://gitlab. | * copy the "init" file from [https://gitlab.postmarketos.org/postmarketOS/pmaports/tree/master/device/linux-samsung-i9100 <code>linux-samsung-i9100</code>] and customize the partition | ||
* add "init" to <code>source=</code> in the APKBUILD | * add "init" to <code>source=</code> in the APKBUILD | ||
* adjust your <code>prepare()</code> like it's done in <code>linux-samsung-i9100</code> and adjust the paths in there | * adjust your <code>prepare()</code> like it's done in <code>linux-samsung-i9100</code> and adjust the paths in there | ||
Line 98: | Line 125: | ||
== See also == | == See also == | ||
* [[How to properly backup downstream kernels]] | |||
* [[Troubleshooting:kernel]] | |||
* [[device specific package]] | * [[device specific package]] | ||
* {{issue|103|pmaports}} Adjust to GCC8 upgrade in Alpine edge | * {{issue|103|pmaports}} Adjust to GCC8 upgrade in Alpine edge | ||
* {{MR|30|pmaports}} device/linux-*: use GCC-6 for all 3.x kernels | * {{MR|30|pmaports}} device/linux-*: use GCC-6 for all 3.x kernels | ||
[[Category:Technical Reference]] |
Latest revision as of 07:38, 3 November 2024
Unless a device has been mainlined, we need to package the downstream kernel (also called "vendor kernel"). This is the reference for the APKBUILD files of vendor kernels.
Generate a template
Usually you would generate both a new device specific package and a new vendor kernel package by running pmbootstrap init
and typing in a new device name. In case you should only have a device package, but not a kernel package, you can regenerate the latter with pmbootstrap aportgen linux-changeme-changeme
(you guessed it, changeme needs to be adjusted).
The template gets improved every now and then to make porting easier, so don't be surprised when you are looking at older ports and their APKBUILDs look a bit more complicated than what gets generated from the latest pmbootstrap
version. Essentially they are doing the same thing.
Modernize your aport
To recreate your vendor kernel aport on top of the latest (and therefore most readable) template, do the following steps:
$ mv aports/device/testing/linux-wiki-example /tmp/linux-wiki-example-old
$ pmbootstrap aportgen linux-wiki-example
$ # (now adjust the new aport to use the sources and patches from the "-old" dir, rename $pkgname from linux-wiki-example to linux-wiki-example-old)
$ pmbootstrap checksum linux-wiki-example
$ pmbootstrap build --force linux-wiki-example
$ # (now test it on your device and make sure it boots, e.g. with 'pmbootstrap zap', 'pmbootstrap install', 'pmbootstrap flasher boot')
$ pmbootstrap pkgrel_bump linux-wiki-example
$ git add -A
$ git commit -m "device/linux-wiki-example: modernize aport"
downstreamkernel_prepare
Newly generated downstream kernel packages use the downstreamkernel_prepare
script. That way we can share code between the APKBUILDs, so it is less redundant. To see what the function does, read the source over here.
It is supposed to be sourced, so the content of the script gets executed in the current shell. This is done with the dot in-front of the script name:
prepare() {
default_prepare
. downstreamkernel_prepare
}
Note that this behavior had changed in pmaports!1084. Out of tree device ports may not have been adjusted yet and still pass arguments to the script. This is not supported anymore, adjust them like written above or consider modernizing the whole pmaport as explained earlier in this article.
GCC version
The kernel gets compiled with GCC. Alpine Linux has been shipping version GCC 6 for a long time, but changed the default GCC version to GCC 8 in September 2018. It was discovered that at least one vendor kernel does not boot when compiled with GCC 8 (pmaports#103), so we ended up packaging GCC 6 side by side with GCC 8. All existing 3.x vendor kernels that were packaged have been adjusted to use GCC 6 at this point in time, just to make sure we don't introduce any breakage there. The default for new packages is using the current GCC version that is packaged in Alpine (at time of writing: GCC 8).
Use GCC 4
Follow the GCC 6 instructions below, but replace 6 with 4 everywhere.
Use GCC 6
If your new kernel port does not boot at all, or it doesn't even compile, please try to compile it with GCC 6 and see if it works then.
To do that, open aports/device/linux-[your-device]/APKBUILD
and add these lines:
# Compiler: GCC 6 (doesn't boot when compiled with newer versions)
if [ "${CC:0:5}" != "gcc6-" ]; then
CC="gcc6-$CC"
HOSTCC="gcc6-gcc"
CROSS_COMPILE="gcc6-$CROSS_COMPILE"
fi
between makedepends=
and # Source
lines.
Then add gcc6
to the kernel's makedepends
line.
Technical detail: the if...
guard around setting the variables is necessary, because the CC
and CROSS_COMPILE
variables extend themselves. abuild
will parse the APKBUILD
a second time while running the package()
step (inside fakeroot). So without the if
statement, we will end up with CC="gcc6-gcc6-gcc"
instead of CC="gcc6-gcc"
which gets problematic if you are calling make
to install kernel modules in the package section (as done in linux-asus-tf101
for example). Interestingly, only CC
and CROSS_COMPILE
gets passed through, hence we can't simply check the HOSTCC
variable.
Use the newest GCC from Alpine
Let's say you are using a device that has already been packaged, and you want to figure out if it also boots when compiled with a newer compiler. Just removing HOSTCC vars and references to them should be enough:
Remove these lines:
# Compiler: this kernel was only tested with GCC6. Feel free to make a merge
# request if you find out that it is booting working with newer GCCs as
# well. See <https://postmarketos.org/vendorkernel> for instructions.
if [ "${CC:0:5}" != "gcc6-" ]; then
CC="gcc6-$CC"
HOSTCC="gcc6-gcc"
CROSS_COMPILE="gcc6-$CROSS_COMPILE"
fi
And remove the mention of HOSTCC
in invocation of downstreamkernel_prepare
.
Then remove the gcc6
package from the makedepends
line.
Afterwards, remove the compiler-gcc6.h
file from the aport dir, and from the source
line. Instead you will probably need other patches as linked here. First try compiling without patches, then add one patch at a time to fix a specific problem. As usually, with pmbootstrap checksum
, you can regenerate the checksums at the bottom of the file, this needs to be done whenever you change source
.
When you made it boot successfully, please increase the pkgrel
and make a merge request.
Using GNU Make 3.x
GNU Make sometimes introduce backward-incompatible changes. While recent versions of Linux kernel requires GNU Make 4.x, building older kernels fails with GNU Make 4.x but succeeds with GNU Make 3.x.
To use GNU Make 3.81, open aports/device/linux-[your-device]/APKBUILD
and add these lines:
# GNU Make 3.81
PATH="/usr/make3.81/bin:$PATH"
between makedepends=
and # Source
lines.
Then add make3.81
to the kernel's makedepends
line.
Using a specific kernel image
By default downstreamkernel_package.sh looks for a few kernel image files such as Image.gz-dtb
and *zImage
, but for various reasons you may want/need to look for something else; in these situations set KERNEL_IMAGE_NAME
similar to the following:
package() {
KERNEL_IMAGE_NAME="Image.gz" downstreamkernel_package \
"$builddir" "$pkgdir" "$_carch" "$_flavor" "$_outdir"
}
heimdall-isorec
If you have a device that only boots with heimdall-isorec, you will need to adjust your linux APKBUILD as follows:
- add
busybox-static-armhf
to makedepends - copy the "init" file from
linux-samsung-i9100
and customize the partition - add "init" to
source=
in the APKBUILD - adjust your
prepare()
like it's done inlinux-samsung-i9100
and adjust the paths in there
You can search for more examples of heimdall-isorec deviecs with grep:
$ grep -r 'deviceinfo_flash_method="heimdall-isorec"' aports
aports/device/device-samsung-i9070/deviceinfo:deviceinfo_flash_method="heimdall-isorec"
aports/device/device-samsung-i9100/deviceinfo:deviceinfo_flash_method="heimdall-isorec"
See also
- How to properly backup downstream kernels
- Troubleshooting:kernel
- device specific package
- pmaports#103 Adjust to GCC8 upgrade in Alpine edge
- pmaports!30 device/linux-*: use GCC-6 for all 3.x kernels