How does RPiOS make a single image for all

This forum is for discussion about general software issues.

How does RPiOS make a single image for all

Postby keithspg » Sun Dec 19, 2021 9:24 pm

For ArchARM, we have an armv6 image for PiB1,ZeroW, an armv7 image for Pi2B,3B,4B, Zero2W and an aarch64 image for Pi3B,4B, Zero2W yet RpiOS has a single image which I can boot as armv6, armv7, armv7l and aarch64 (on appropriate hardware) and it works. How did they do that?
I noticed that they do not use an initramfs which, I am guessing, is architecture dependent. All 4 kernels are in the /boot directory. The only thing I have to change is if I want it to boot as aarch64, I have to add 'arm_64bit=1' to config.txt.
How can I duplicate this feat but with an ArchARM install? Are all the binaries armv6h?

Keith
keithspg
 
Posts: 221
Joined: Mon Feb 23, 2015 4:14 pm

Re: How does RPiOS make a single image for all

Postby keithspg » Tue Dec 21, 2021 2:32 pm

Well, I have figured out a way to do this. It isn't 'correct', yet, but it works.

Start out with an armv6 image created like it says on the archARM install for Rpi. This installs a full basic system with the rpi-legacy (armv6) kernel. Boot this on a Pi1/Zero/Zerow initialize it like the instructions say.
Build an armv7 kernel, somehow, but edit the config such that the $this->bbcode_second_pass_code('', 'CONFIG_LOCALVERSION="-ARCH-v7"'). I added v7 because this is how Rpi do it, but as long as the LOCALVERSION is different than the normal package, you can install modules in a different folder and the kernel knows where to find them at boot. Once built install (copy files) this kernel and modules to the running armv6 image.
To do this you need to copy the files from the archive to the correct directories. I use mc to do this. I am sure there is a way to modify the PKGBUILD so that it can be installed by pacman, but have not figured that out yet.
you have to delete the /boot/initramfs.img and comment out that line in the /boot/config.txt, but at this point I have an image that will boot on all architectures of RPi.
For some treason, it has trouble booting on armv6 after booting on armv7, so I edited the /etc/fstab to add an explicit line to mount root on /
$this->bbcode_second_pass_code('', '/dev/mmcblk0p2 / ext4 defaults 0 0')
More to follow as I experiment with this.
keithspg
 
Posts: 221
Joined: Mon Feb 23, 2015 4:14 pm

Re: How does RPiOS make a single image for all

Postby keithspg » Fri Dec 24, 2021 12:24 am

Well, I have finessed the PKGBUILD to build what I want but cannot get it to install without uninstalling the linux-rpi-legacy package which is what i do not want to do.
Where I am so far:
I did not modify the config. I changed my edit back.

In PKGBUILD
$this->bbcode_second_pass_code('', 'pkgbase=linux-rpi-v7
...
provides=('kernel26-v7' "linux=${pkgver}-v7" 'WIREGUARD-MODULE-v7')')
I commented out conflicts and replaces.

This builds a package and the modules are in $this->bbcode_second_pass_code('', '/usr/lib/5.10.87-1-rpi-v7-ARCH') so it will not overwrite the v6 modules. I just want to get it to install when I modify the /etc/pacman.conf architecture to 'armv7' and leave the v6 modules in place. I can copy it all, but would rather use pacman so I can upgrade when i need to.

any help appreciated.

Keith
keithspg
 
Posts: 221
Joined: Mon Feb 23, 2015 4:14 pm

Re: How does RPiOS make a single image for all

Postby keithspg » Sat Dec 25, 2021 6:06 pm

Ok, this is a bit of a question and a plea.
Pacman is really strict for a good reason on installing packages so that they do not get out of sync and I get that. I revamped my PKGBUILD and assorted files to be able to do build a kernel and modules and will let you know where I am, but first a bit of background as to why I am so interested in this.
We have an Arch ARM based music player (mpd based) and currently have 3 versions we are maintaining, Pi1 (armv6 for PiA/B1 and Pi Zero/ZeroW) Pi2 (armv7 for Pi2Rev 1.1) and pi2 rev 1.2, Pi3 Pi4 (aarch64). We have built images according to the archARM instructions and added regualr ArchARM packages and built and added a few more custom packages to get the functionality we need and this works. We'd like to get back to a single image to distribute that will run on all Pis as maintaining 3 is a lot of work.
We have built such an image but would like to leverage pacman to install it so it could, possibly, be upgraded in teh future if needed. The armv6 image will run on all the Pis *if* the kernel7.img built under armv7 and matching modules are present and can be found by the kernel7.img. (but you already know this).
To install this armv7 kernel and modules, I
1) edit the architecture line of /etc/pacman.conf from armv6 to armv7
2) move the record (all of the files in the folder /var/lib/pacman/local/linux-rpi-legacy-5.xx.xx-x/) somewhere temporarily
3) Execute pacman -Syy
4) install the package I built with 'pacman -U linux-rpi-v7-5.10.87-1-armv7h.pkg.tar.xz'
5) edit the /etc/pacman.conf back to armv6
6) copy the record of the linux-rpi-legacy back to /var/lib/pacman/local/

I tried a lot of different things, but ended up by editing the PKGBUILD and leaving the config alone.

$this->bbcode_second_pass_code('', '# Maintainer: graysky <graysky@archlinux.us>
# Maintainer: Kevin Mihelich <kevin@archlinuxarm.org>
# Maintainer: Oleg Rakhmanov <oleg@archlinuxarm.org>
# Maintainer: Dave Higham <pepedog@archlinuxarm.org>
# Contributer: Jan Alexander Steffens (heftig) <heftig@archlinux.org>

buildarch=12

pkgbase=linux-rpi-v7
# edited config to generate suffix of -v7 or -v8
#_commit=0f6b9a3650b6823de5cc5362f338bfcb2fb863c3
#_commit=6a12ecfa52bf747678c41ef5a22cad5e73202c16
_commit=48f234641072c3619fa8c357b93e4f5131899cb6
_srcname=linux-${_commit}
_kernelname=${pkgbase#linux}
pkgver=5.10.87
pkgrel=1
pkgdesc='Linux Rune 384k'
url="http://www.kernel.org/"
arch=(armv7h aarch64)
license=(GPL2)
makedepends=(
bc kmod inetutils
)
options=('!strip')
source_armv7h=('config' 'config.txt')
source_aarch64=('config8' 'config8.txt')
source=("linux-$pkgver-$pkgrel-${_commit:0:10}.tar.gz::https://github.com/raspberrypi/linux/archive/${_commit}.tar.gz"
cmdline.txt
0001-Make-proc-cpuinfo-consistent-on-arm64-and-arm.patch
linux.preset
60-linux.hook
90-linux.hook
kernel-sound-pcm5102a-add-support-for-384k.patch
)
md5sums=('4ffd0ba5cd6510aa5ddcf4234a57ecb3'
'31c02f4518d46deb5f0c2ad1f8b083cd'
'f66a7ea3feb708d398ef57e4da4815e9'
'86d4a35722b5410e3b29fc92dae15d4b'
'0a5f16bfec6ad982a2f6782724cca8ba'
'a5e08eec357098b39a1daa6652223a5f'
'bbe9b577f385687ec4be6535783a3aa5')
md5sums_armv7h=('5ec205f35bac1cc4df6436ba3cb83b07'
'e302936d860e78ca8e965459e64b2e5b')
md5sums_aarch64=('63459a8b79a2cc6fbca8566c4ff8485f'
'e302936d860e78ca8e965459e64b2e5b')

# setup vars
if [[ $CARCH == "armv7h" ]]; then
_kernel=kernel7.img KARCH=arm _image=zImage _config=config _bconfig=config.txt
elif [[ $CARCH == "aarch64" ]]; then
_kernel=kernel8.img KARCH=arm64 _image=Image _config=config8 _bconfig=config8.txt
fi

prepare() {
cd "${srcdir}/${_srcname}"

# consistent behavior of lscpu on arm/arm64
patch -Np1 -i ../0001-Make-proc-cpuinfo-consistent-on-arm64-and-arm.patch

# Rune patches
msg2 "patching: 384k support"
# msg2 "Patch PCM-5102 384k support"
patch -Np1 -i ../kernel-sound-pcm5102a-add-support-for-384k.patch

# prepare for distccd
if [[ $CARCH == "armv7h" ]]; then
sed -i '/HAVE_GCC_PLUGINS/d' arch/arm/Kconfig
elif [[ $CARCH == "aarch64" ]]; then
sed -i '/HAVE_GCC_PLUGINS/d' arch/arm64/Kconfig
fi

echo "Setting version..."
scripts/setlocalversion --save-scmversion
echo "-$pkgrel" > localversion.10-pkgrel
echo "${pkgbase#linux}" > localversion.20-pkgname

echo "Setting config..."
cp ../"$_config" .config
make olddefconfig

make -s kernelrelease > version
echo "Prepared $pkgbase version $(<version)"
}

build() {
cd "${srcdir}/${_srcname}"

make "$_image" modules dtbs
}

_package() {
pkgdesc="RPi Foundation patched Linux kernel and modules"
depends=('coreutils' 'linux-firmware' 'kmod' 'mkinitcpio>=0.7' 'firmware-raspberrypi')
optdepends=('crda: to set the correct wireless channels of your country')
# provides=('kernel26' "linux=${pkgver}" 'WIREGUARD-MODULE')
provides=('kernel26-v7' "linux=${pkgver}-v7" 'WIREGUARD-MODULE-v7')
# conflicts=('kernel26' 'linux' 'uboot-raspberrypi')
install=${pkgname}.install
backup=('boot/config.txt' 'boot/cmdline.txt')
# replaces=('linux-raspberrypi-latest' 'linux-raspberrypi4')

cd "${srcdir}/${_srcname}"

local kernver="$(<version)"
local modulesdir="$pkgdir/usr/lib/modules/$kernver"

# Used by mkinitcpio to name the kernel
echo "$pkgbase" | install -Dm644 /dev/stdin "$modulesdir/pkgbase"

echo "Installing modules..."
make INSTALL_MOD_PATH="$pkgdir/usr" modules_install

# remove build and source links
rm "$modulesdir"/{source,build}

echo "Installing Arch ARM specific stuff..."
mkdir -p "${pkgdir}"/boot
make INSTALL_DTBS_PATH="${pkgdir}/boot" dtbs_install

if [[ $CARCH == "aarch64" ]]; then
# drop hard-coded devicetree=foo.dtb in /boot/config.txt for
# autodetected load of supported of models at boot
find "${pkgdir}/boot/broadcom" -type f -print0 | xargs -0 mv -t "${pkgdir}/boot"
rmdir "${pkgdir}/boot/broadcom"
fi

cp arch/$KARCH/boot/$_image "${pkgdir}/boot/$_kernel"
cp arch/$KARCH/boot/dts/overlays/README "${pkgdir}/boot/overlays"
install -m644 ../$_bconfig "${pkgdir}/boot/config.txt"
install -m644 ../cmdline.txt "${pkgdir}/boot"

# sed expression for following substitutions
local _subst="
s|%PKGBASE%|${pkgbase}|g
s|%KERNVER%|${kernver}|g
"

# install mkinitcpio preset file
sed "${_subst}" ../linux.preset |
install -Dm644 /dev/stdin "${pkgdir}/etc/mkinitcpio.d/${pkgbase}.preset"

# install pacman hooks
sed "${_subst}" ../60-linux.hook |
install -Dm644 /dev/stdin "${pkgdir}/usr/share/libalpm/hooks/60-${pkgbase}.hook"
sed "${_subst}" ../90-linux.hook |
install -Dm644 /dev/stdin "${pkgdir}/usr/share/libalpm/hooks/90-${pkgbase}.hook"
}

pkgname=("${pkgbase}")
for _p in ${pkgname[@]}; do
eval "package_${_p}() {
_package${_p#${pkgbase}}
}"
done')

I changed the name of the $this->bbcode_second_pass_code('', 'linux-rpi.install') to $this->bbcode_second_pass_code('', 'linux-rpi-v7.install') so that pkgbuild will build the package with the new name. I commented out the last line in 90-linux.hook to keep it from generating the initramfs thatr we are not using. Pacman still identifies that as a kernel and will not install it unless I move the record in $this->bbcode_second_pass_code('', '/var/lib/pacman/local')
Is there any other way to do this? Still looking for pointers to build a package to install the proper kernel7.img and modules to allow a single image to boot on all Pis without having to resort to tricking pacman to install it.

Keith
keithspg
 
Posts: 221
Joined: Mon Feb 23, 2015 4:14 pm

Re: How does RPiOS make a single image for all

Postby armuseru » Tue Dec 28, 2021 9:08 pm

sudo pacman -U linux-rpi-v7-5.10.87-1-armv7h.pkg.tar.xz --arch armv7h
but if it contains files with the same names (and paths) as already existing in the system, conflicts will arise (zImage, dtbs and so on)

https://wiki.archlinux.org/title/PKGBUILD#install
The postinstall and postupgrade directives can be useful for automatically updating existing configurations.

PKGBUILD that simply repackages your kernel with the arch="any" might be an option too.
armuseru
 
Posts: 34
Joined: Sat Jan 09, 2021 9:36 am

Re: How does RPiOS make a single image for all

Postby keithspg » Wed Dec 29, 2021 3:43 pm

@armuseru Thanks for the tip. I will try the --arch armv7h directive with --overwrite=*. The deal is that all the overlays are duplicate and are present in both packages. This is easier than editing the /etc/pacman.conf file. I think I will still have to move the 'record' of linux-rpi-legacy out of /var/lib/pacman/local as pacman seems to parse this and the linux-rpi-legacy package flags linux-rpi as a conflict. I will try this and see how it goes.
keithspg
 
Posts: 221
Joined: Mon Feb 23, 2015 4:14 pm

Re: How does RPiOS make a single image for all

Postby keithspg » Tue Feb 22, 2022 8:06 pm

@armuseru Thanks for the help, but now that armv6 had been removed as a supported architecture, this is moot. An armv7 kernel; seems to be able to use an armv6 user space, but an armv6 kernel cannot use an armv7 user space so we are dead in the water on this.
keithspg
 
Posts: 221
Joined: Mon Feb 23, 2015 4:14 pm

Re: How does RPiOS make a single image for all

Postby jyno » Tue Mar 22, 2022 3:31 pm

I think this is worth referring to the following post viewtopic.php?p=69221#p69221
Apparently, there are some components (I guess, drivers) missing, which constitutes a challenge.

In order to make one for all, this means that drivers of all SBCs must be included.
Alternatively, documentation for each SBC may be provided (e.g. like the *-ucode package) to complete installation with the appropriate drivers/components that is specific to the drivers in use.

$this->bbcode_second_pass_quote('', '
')Early loading
Installation
Depending on the processor, install the following package:

amd-ucode for AMD processors,
intel-ucode for Intel processors.


From: https://wiki.archlinux.org/title/Microcode#Installation
jyno
 
Posts: 67
Joined: Wed May 05, 2021 4:37 pm

Re: How does RPiOS make a single image for all

Postby darksky » Tue Mar 22, 2022 11:50 pm

Your thoughts in the OP are pretty much in line. I have been providing a turn key arch-arm satellite image for years. I thought about doing what you are trying making kernel packages but I did not want to get in the habit of keeping all of the kernels current for every one so I provided instructions in my git that basically followed RPi's kernel compile guide.

As long as you have these kernel names kernel7.img / kernel7l.img / kernel8.img in boot it knows what kernel to boot automatically. The only difference as you mentioned is have arm_64bit=1 in config.txt and it will know to boot kernel8.img.

If your kernel is compiled like RPi does you do not need an initramfs. I do not have one in my image. Seems like a few months back I installed the arch aarch64 to test something and I had to build an initramfs image with 1 module in it so it would boot off my usb ssd. I never tested with booting off a sdcard.

My thoughts when I was thinking about building kernel packages:

As mentioned above set the arch=('any') in the PKGBUILD for each kernel
Build 3 separate kernels to boot depending on device and architecture. 32bit - kernel7.img / kernel7l.img and 64 bit - kernel8.img.

Make sure the kernels built wind up in /boot with their respective names for the devices and architecture they are built for.
For informational purposes my kernel modules tree's. I need to upgrade a couple of them but have not taking the time to do so:

$this->bbcode_second_pass_code('', '[alarm@alarmpi ~]$ ls /usr/lib/modules
5.10.60-udlv7+ 5.10.60-udlv7l+ 5.15.30-2-udlv8')

Modify the PKGBUILD so nothing touches the other kernels. I had thought I might exclude at the time and build the overlays and all .dtb's as a separate package and have the kernel's PKGBUILD depend on it since they are the same anyway when building the kernels.

As you mentioned all of the pi devices are downward compatible so have the armv7 32bit image as as a base.

The 64bit kernel seems to boot and work ok here on the 32bit image on the tests I have done. I have not done a really intense test as I have another means of providing a 64bit images and my special FTA kernel but I am thinking if it is good enough for the RPi people to release their images with it it is probably ok but I personally would not boot a 64bit kernel on a 32bit OS. I don't see an advantage.

Here is a pic of my 32bit arch-arm image booted on my 64bit kernel I threw on my image today:

https://drive.google.com/file/d/19DNYr2bcUPnXoE69k3ANDGhTY9RyMc65/view?usp=sharing
darksky
 
Posts: 35
Joined: Thu Oct 15, 2020 5:57 pm


Return to General

Who is online

Users browsing this forum: No registered users and 5 guests