Move the numerous "install" arguments into an own function (as it was
done with actions added later). Categorize the options and update the
help output, so the options are easier to understand.
Embed the firmware from the right chroot suffix. Previously it would
always use the rootfs_{args.device} chroot, which does not work anymore
with upcoming 'pmbootstrap install --ondev --no-rootfs' as there will
only be the installer_{args.device} chroot.
Adds QCDT templates for Spreadtrum and Exynos SoCs
When "pmbootstrap init" is executed, after the boot image analysis,
if the device is QCDT, then the user is asked about the SoC vendor.
Example:
[HH:MM:SS] SoC vendor (spreadtrum/exynos/other) [other]: exynos
After that, the corresponding template is picked.
Change 'cryptsetup luksFormat' arguments to use --use-random instead of
--use-urandom. urandom is not recommended for the generation of long-term
cryptographic keys, as it may generate weak keys in low entropy
situations.
With the default argument values removed, the step logic is more
centralized in the install method which makes the code a bit less
brittle and easier to follow.
This adds a new commandline flag -E / --extra-space for
specifying the amount of additional space to be added to
the image size to work around cases where the automatically
determined size turns out to not actually be enough.
The value is also asked for in the "Additional options"
section of the interactive mode.
Fixes: #1904
format_and_mount_root() => format_luks_root():
* Rename to reflect what it's actually doing
* Move the FDE check from format_luks_root to the only caller
* Make arguments to "cryptsetup luksFormat" more readable
format_and_mount_pm_crypt() => format_and_mount_root():
* Rename to reflect what it's actually doing
* Don't overwrite device if doing FDE; instead provide the proper device
in the caller
The old function names were for historic reasons, early on it was only
possible to create encrypted installations with pmbootstrap.
Use the dtb-appended kernel file, e.g. postmarketos-exynos4-dtb instead
of postmarketos-exynos4, if it is available. This is needed to flash a
mainline kernel with appended dtb to isorec devices.
Change the 'not value' condition raising the '...value for this variable
is None!' error to 'value is None' so it doesn't raise when the value is
something else that evaluates to boolean False, like an empty string.
Remove the special treatment for $KERNEL_CMDLINE here by making it
default to empty string.
Alpine indicates with arch="", that a package should temporarily not be
built for any architecture. Support this in postmarketOS too by not
complaining in the APKBUILD parser if arch is empty.
Adjust pmb.build.autodetect.arch and pmb.build.menuconfig.get_arch, so
both don't fail with an IndexError when encountering a disabled package.
Co-Authored-By: Luca Weiss <luca@z3ntu.xyz>
Do not verify that the architecture passed with --arch is part of the
arch variable in APKBUILD. This prepares to set 'arch=""' to temporarily
disable building packages. Users will still be able to run "pmbootstrap
menuconfig" on them by manually specifying the architecture.
Put all install_packages related lines into one block and fix up the
comments:
* The list of packages to be installed is not listed at this point (and
it does not make sense there, if we would want to list it, it should
be done in the next block at 'if args.build_pkgs_on_install).
* Remove "including the ones specified by --add", as it doesn't add any
value.
Don't have the set_user() call weirdly between multiple commands
building the install_packages list. Move it up, together with the log
message announcing that the device rootfs is being built.
Update the comment above set_user(): there is no 'build' user anymore,
and at this point we only call it before actually installing the
packages for legacy reasons.
Do not attempt to upgrade packages in the rootfs chroot when running
"pmbootstrap install".
This was responsible for placing every single package in /etc/apk/world
(which should only hold the packages explicitly installed), because the
upgrade function was literally implemented as getting a list of
installed packages and explicitly running pmb.chroot.apk.install on each
of them. The intention was to rebuild these packages if they were outdated,
I guess I didn't realize that this makes /etc/apk/world unusable when I
introduced this three years ago in 51bdc243 ("Properly rebuild/install
packages when something changed").
Remove pmb.chroot.apk.upgrade altogether, because:
1) pmb.install.install builds and upgrades outdated pmaports
2) pmb.install.install is the only user of pmb.chroot.apk.upgrade
3) 'pmbootstrap init' is warning that the chroots do not get upgraded
automatically, so let's not go against that expectation. users who
want an updated rootfs chroot can simply run zap and install again.
Replace it with a call to pmb.helpers.repo.update, because we still need
to update the APKINDEX files before attempting to build/install the
generated list of packages.
Let tail attempt to open the file again, if it becomes inaccessible.
This is useful, when writing a reproducer that deletes pmbootstrap's
log.txt while at the same time running 'pmbootstrap log'.
(027724) [17:57:34] Done
tail: '/home/user/.local/var/pmbootstrap/log.txt' has become inaccessible: No such file or directory
tail: '/home/user/.local/var/pmbootstrap/log.txt' has appeared; following new file
(003493) [17:57:35] % cd /home/user/.local/var/pmbootstrap/cache_git/pmaports; git remote -v
Packages like binutils-*, busybox-static-*, gcc-*, grub-efi-*, musl-*
are only needed for the native architecture during cross compilation.
Don't bother with trying to build them for other arches to save time and
to avoid getting stuck frequently at "armv7/binutils-aarch64" etc.
A few people like to use pmbootstrap on aarch64 hosts (e.g. PineBook
Pro), so let's make it available for aarch64 again when we can build
aarch64 packages natively in CI and bpo. (They do get stuck there right
now, because of qemu user emulation.)
Related: https://gitlab.com/postmarketOS/build.postmarketos.org/-/issues/75
Use a deterministic mirror URL instead of CDN for aportgen. Otherwise we
may generate a pmaport that wraps an apk from Alpine (e.g. musl-armv7)
locally with one up-to-date mirror given by the CDN. But then the build
will fail if CDN picks an outdated mirror for CI or BPO.
This adds support for specifying an arbitrary git ref (e.g. commits,
tags, branches) to upgrade to. This can be useful if a specific commit
needs to be packaged instead of the latest available. Alternatively you
can also specify a branch to be used if the default branch is 'stable'
but 'develop' should be packaged.
This also removes old code to use the 'bionic' branch for UBports Lomiri
(formerly Unity 8) packages.
The Nokia n900 XkbLayout is a bit peculiar and sometimes
join two keymaps into one, for example:
Option "XkbLayout" "fise"
For the combined finnish/swedish layout. Add the common
joined keymaps, even if not all of these countries are
yet supported.
For details see:
https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config/-/blob/master/symbols/nokia_vndr/rx-51
I also include this link in the code so no-one gets confused.
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Some Mediatek devices have a special 512-byte header around the zImage
which must be generated so the device boots.
Support for that exists for a while in postmarketOS but detection was
missing. Add that.
Do not fail in "pmbootstrap setup" if a keymap was selected, but no
/etc/X11/xorg.conf.d path exists in the rootfs chroot. The grep output
is not empty in that case (it would be empty if the directory exists and
there are no matches), so we need to add this extra check:
(rootfs_nokia-n900) % grep -rl XkbLayout /etc/X11/xorg.conf.d/
grep: /etc/X11/xorg.conf.d/: No such file or directory
Replace dl-cdn mirror with dl-2 temporarily to avoid "BAD signature"
errors.
This is related to the rebuild of Alpine edge x86, armhf, armv7 packages
against musl-1.2, that is currently going on. The packages are rebuilt
without a version change and therefore have the same resulting file
name, but a different checksum. Due to caching of the CDN and due to the
same file name, users may get an old package from before the rebuild.
The APKINDEX has a checksum of the new package, and so the download will
fail with a "BAD signature" error.
Alpine developers clear the cache every now and then, but this issue
will happen over and over again, until all packages are rebuilt (some
packages are still not rebuilt and have been disabled).
Let's switch back in two months or so.
Before this fix tab completion of names with hyphens were not done:
try for example to complete UI package name in 'pmbootstrap init' with
hyphen, like "plasma-mobile" / "plasma-desktop". Now this is handled
correctly (hyphen is not considered as delimeter).
Let UI meta-packages specify apps in "pmb_recommends" to be explicitly
installed by default, and not implicitly as dependency of the UI
meta-package ("depends"). Therefore make these apps uninstallable,
without removing the meta-package.
Add pmbootstrap install --no-recommends to disable this feature.
Add a question at the end of "pmbootstrap init", to ask if the user
wants to build outdated packages during "pmbootstrap install". Store the
result in the new pmbootstrap.cfg key "build_pkgs_on_install". I've put it at
the end, because it is a rather complicated question compared to the rest.
This is useful to speed up the installation for casual users who can now
avoid compiling packages. But also for the official images where we only
want to ship the official binary packages and not build anything
on-the-fly.
This is likely to fail with the new default cryptsetup cipher of
aes-xts-plain64, as many downstream kernels used in recovery OS (like
TWRP) do not have CRYPTO_XTS set.
Put a minimum version check for postmarketos-ondev in the pmbootstrap
install code and verify it before starting the installation. This avoids
using incompatible versions, similar to the pmaports.cfg version check
we already have. Set the minimum required version to 0.2.0.
Do not pass the arguments to ondev-prepare as command-line arguments in
a specific order, but instead as environment variables. New arguments
will be added in a follow-up patch.
Checkout the aports.git branch for the current channel (e.g.
3.12-stable), before trying to find the APKBUILD.
I had tried to auto-unshallow the git repository earlier, but then the
tags were missing. I decided that it's not worth to provide a migration
path: "pmbootstrap aportgen" is only used by few advanced users (to
maintain the pmaports repo).
This made sense for Alpine's aports.git repository as we were only using
the master branch. But now that we are using more branches, we need the
entire git repository with all its branches cloned.
Add the Alpine mirrordir (e.g. "edge", "v3.12") to the distfile, so
musl-*.apk files of the same version and arch but from different
mirrordirs do not collide.
Let "abuild checksum" download these apks and generate the checksums,
instead of letting apk download them as side-effect of initializing
foreign arch chroots. The latter did not work anymore, because we would
copy the apk file with a glob that may matches the hash of either mirrordir.
Essentially:
glob.glob(f"{args.work}/cache_apk_{arch}/{subpkgname}-{version}.*.apk")[0]
In the context of the on-device installer, I found that calculating this
hash is not trivial, so let's just avoid it here as well.
While at it, order the imports of musl.py alphabetically.
Add initial support for the on-device installer in pmbootstrap. Let
pmbootstrap create a regular split image, then prepare a new installer
rootfs and copy the previously generated rootfs image into the installer
rootfs. Put the installer rootfs into a new image, with reserved space.
There is more to do from here, such as disabling the generation of the
user account when using --ondev. But this requires support in
postmarketos-ondev first, so let's build that iteratively.
Related: https://wiki.postmarketos.org/wiki/On-device_installer
Related: https://gitlab.com/postmarketOS/postmarketos-ondev/-/issues
Move code that prints flashing information from install_system_image()
to its own function. For the on-device installer, we'll need to call
install_system_image() twice, without printing the flashing information
each time. While at it, add "step" and "steps" parameters.
Prepare for a future patch, that adds reserved space in MiB, by changing
size_boot and size_root from bytes to MB everywhere. This is what we need
most of the time and allows to drop some /1024**2 statements.
Add a "split" argument to the function, instead of using "args.split"
directly. "args.split" is only defined when calling "pmbootstrap install",
but the next patch will add a code path that calls the function from
"pmbootstrap chroot".
Alpine APKBUILDs have the concept of "provider priorities" that affect
the choice of the provider to install when multiple packages provide
a virtual package.
One use case for this is to allow installation of different firmware
versions. bq-paella can run unsigned firmware, therefore you have the
choice between using the original firmware from the manufacturer, or
a slightly newer version from Qualcomm for the Dragonboard 410c.
We add provides="firmware-qcom-msm8916-wcnss" (the "virtual package")
to both firmware-qcom-db410c-wcnss and firmware-bq-picmt-wcnss.
At this point, attempting to install "firmware-qcom-msm8916-wcnss"
would still fail with apk. (Because it does not know which provider
to install.)
To pick a default we can set e.g. provider_priority=100 for
firmware-qcom-db410c-wcnss (the slightly newer version).
In that case, firmware-qcom-db410c-wcnss should be installed by default.
However, the user can choose to do "apk add firmware-bq-picmt-wcnss"
to override the default choice in case of problems. In that case,
the conflicting firmware-qcom-db410c-wcnss will be automatically removed.
At the moment, pmbootstrap does not respect the "provider_priority" at all.
In the above case, it would always install "firmware-bq-picmt-wcnss"
during "pmbootstrap install" since that has the shortest name.
Extend the pmbootstrap code to pick a provider with the highest priority
(if any of the providers has a priority set).
Do not substract the estimated size of the home and boot directories
from the root directory size. While that would be the correct way if we
were able to get exact sizes, it isn't helpful with the very rough
estimates we are getting from pmb.helpers.other.folder_size. Replace
"calculate" wording with "estimate".
"Chassis" defines the what kind of device a device is. Currently the
following standardized types exist:
"desktop", "laptop", "convertible", "server", "tablet", "handset",
"watch", "embedded", "vm", "container"
This property is exposed by org.freedesktop.hostname1 (e.g.
openrc-settingsd) and can be used by applications for example to display
appropriate strings instead of "About this phone" for non-phone devices.
Migrate to workdir version 5 and move already built packages into the edge
channel subdir, for example:
$WORK/packages/x86_64/hello-world-1-r5.apk
to:
$WORK/packages/edge/x86_64/hello-world-1-r5.apk
The build.postmarketos.org code has already been adjusted to find built
packages in either directory structure.
Do not go through the pmb.chroot.init() code path when running
pmb.install.losetup.umount() inside pmb.chroot.shutdown(). This is not
necessary, as pmb.install.losetup.umount() only gets called if the
chroot is already initialized and /dev/loop-control is mounted inside
the chroot.
Not going through this code path is important for the upcoming workdir
migration patch. Without this fix, it will fail with the following if
running "pmbootstrap install" before the work migration:
ERROR: Could not figure out on which release channel the 'native' chroot is
Replace the call to this function with the almost identical
pmb.helpers.repo.apkindex_files(), so release channel related changes
only need to be done in one place.
Use mirrordir_pmos and mirrordir_alpine from channels.cfg to generate
the mirror URLs for postmarketOS and Alpine, which get written to
/etc/apk/repositories and which postmarketOS uses to download the
APKINDEX files.
Remove hardcoded "master" at the end of the postmarketOS mirror and use
mirrordir_pmos instead (which is "master" for the edge channel). Let the
postmarketOS mirror end in a '/' for consistency with the Alpine mirror
in pmb/config/__init__.py.
Remove obsolete --alpine-version. To experiment with a different Alpine
version, one should pass a custom --config-channels from now on.
Don't generate the postmarketOS mirror URLs here, let the urls()
function do it. A follow-up commit will touch this code, hence it's
important to have it de-duplicated.
Ask for release channel and switch pmaports branch to the related branch
defined in channels.cfg.
Store in pmbootstrap.cfg whether the user chose a channel (boolean). If
the user did not choose a channel yet, suggest the recommended channel
from channels.cfg (currently "edge").
Do not make the parsed pmaports.cfg from pmaports.git available as
args.pmaports anymore. This de-bloats the args variable a bit.
First I thought that we didn't even need to cache it, but it was pointed
out that later patches do access it frequently to read the current channel
from pmaports.cfg. Therefore it is using a cache now.
Related: #1879, #1855
New pmaports.cfg has the "channel" key described in [1]. This will be
used in "pmbootstrap init" to determine on which release channel a
forked branch is.
[1] https://postmarketos.org/pmaports.cfg
Prepare to base postmarketOS on Alpine stable by parsing the new
channels.cfg file in pmaports.git, that describes which channel
needs which branches and mirror dirs from postmarketOS and Alpine.
Use the information in pmb.helpers.git.get_branches_official() first,
more is coming in follow-up commits.
Read the file from origin/master, so we get the latest fetched version
even if the last checked out master branch is not up-to-date (think of
currently checked out release branch instead of master, master will
never be updated to point to latest origin/master). Allow to override
the file with a new --config-channels parameter.
Related: https://postmarketos.org/channels.cfg
Most device ports that are added to pmaports (particularly the testing
category) are not actually "maintained". Many of them are never updated
after the initial contribution. There is little reason to list a
"Maintainer:" if the device package is actually not actively maintained
by that person.
Let's stop generating the Maintainer: line by default.
Instead, contributors should add the lines themselves if they are willing
to (actively) maintain the device package for a longer period of time.
Once they no longer want to maintain the package, the Maintainer:
line should be removed again.
Let apkbuild-lint check options again, and pass the pmbootstrap specific
options with the new CUSTOM_VALID_OPTIONS variable. Add a test case and
adjust pmb.helpers.lint.check to return the output of apkbuild-lint, so
we can properly test it.
Related: https://gitlab.alpinelinux.org/Leo/atools/-/merge_requests/28
Fixes: pmaports#553
The `mesa-dri-swrast` package was merged into `mesa-dri-gallium` in Alpine.
(See 298e20d04f)
The old alias might be removed in the future, so change the generated APKBUILDs
to depend on `mesa-dri-gallium` instead.
Many of the multi-line strings already contain a new line at the
end of the file. When using .split("\n") this will result in an empty
line at the end of the file that is again followed by a new line.
In other words: we have two new lines at the end, which looks weird.
.rstrip() the whitespace at the end of the string to avoid this.
In case a package can't be built using crossdirect, add an APKBUILD
option to unconditionally disable crossdirect and use the slower
distcc approach instead. This is needed e.g. when using LD_PRELOAD during
the build as crossdirect cannot work with that.
Have explicit selection of the "native" cross compilation method with a
new "pmb:cross-native" option. Deprecate the implicit pkgname pattern
matching.
Related: #1910
The ui-extras questions will attempt to find a postmarketos-ui-<ui>
package in pmaports. If the package does not exist as "root" APKBUILD
it currently attempts to parse all APKBUILDs in case it is somewhere
defined as a subpackage. This is really slow (up to 2-3 seconds),
which feels weird during "pmbootstrap init".
For the UI packages we specifically look for the root UI package,
not the subpackage, so let's skip searching for subpackages in this
case. This makes selecting the "none" UI nice and fast again.
Fix the function, so it does not crash anymore when the
replace_subpkgnames argument is set and a dependency cannot be resolved.
Instead, print a useful warning that shows which pmaport caused the
error (that has always been a pain to figure out), and simply don't
replace the potential subpkgname with the real pkgname, just use the
dependency name as-is.
Resolve annoying crashes in bpo dependency resolving, like this one
(caused by a few linux-* pmaports for bad downstream kernels that depend
on python, not apparent at all from the message):
[09:08:15] Calculate packages that need to be built (all packages, aarch64)
[09:08:26] ERROR: Package 'python': Could not find aport, and could not find this package in any APKINDEX!
Related: https://builds.sr.ht/~postmarketos/job/184022
Previously these two commands would both print the current value:
pmbootstrap config extra_packages
pmbootstrap config extra_packages ''
With this change, the second command will instead set the given config
value to the empty string.
Prevent "pmbootstrap pull" from failing with:
NOTE: your pmaports folder has version 4, but version 6 is required.
ERROR: Run 'pmbootstrap pull' to update your pmaports.
Fixes: #1900
Use pmb.helpers.args.add_cache() with the args used during
autocompletion, so pmb.helpers.pmaports._find_apkbuilds() does not fail
when trying to access args.cache.
No build is necessary if pmaport can't be built for given arch.
pmbootstrap must use Alpine's binary package in that case, even if the
pmaport version is higher than Alpine's binary package version.
Fixes: #1897
The --no-depends option is supposed to stop pmbootstrap if it was
instructed to build a package, but a dependency must be built first. So
far, this only covers the case if there is no binary package for a dependency.
Make it stop if the binary package exists, but is outdated, too.
Fixes: #1895
At the moment we set samsung-i9100 as default device.
This is probably only for historical reasons.
For someone/something using pmbootstrap without a specific device in mind
(e.g. CI) it's really better to use a generic device. QEMU runs natively
in a virtual machine so everyone can use it for testing.
Flashes device vbmeta partition (can be overriden with
"flash_fastboot_partition_vbmeta" setting in deviceinfo)
with custom vbmeta.img which has verity flag disabled,
so device can boot postmarketOS with no problems.
The kconfig check searches the aport with the "linux-" prefix to the
package name passed as argument. This is not working with the full
package name like linux-device-name because it searches a
linux-linux-device-name and fails.
Use the timestamp of .git/FETCH_HEAD in each git repository, to
determine if too much time has passed since the last fetch/pull.
Modify pmb.helpers.git.clone, so FETCH_HEAD is always created if it does
not exist (because "git clone" would not create it).
Related: #1829
Extend "pmbootstrap status" with checks for all git repositories,
derived from relevant checks in pmb.helpers.git.pull (using shared
code):
* on official branch
* workdir is clean
* tracking proper remote
* up to date
Related: #1829
Add dummy function that only returns ["master"] for now, so we can use it
in the upcoming git checks for "pmbootstrap status". More sophisticated
logic to figure out the branches will be added soon, see project
direction 2020 issue.
Related: #1829
Device ports should be under the device/testing/* directory for now.
In the future, devices may be moved to device/{main,community} after
certain preconditions are met.
In the future, device ports will be located in a subdirectory
below device/... (e.g. device/testing/device-...).
Replace all occurrences of device/* with a glob that checks the
subdirectories instead.
Note: To ensure that this always works properly we should also add some
checks that all devices are indeed located under one of the supported
subdirectories (i.e. testing/community/main).
Change the glob for pmaports to <aports>/**/APKBUILD.
This allows using subdirectories for organization outside of device/
as well.
For KVM the code is run pretty much natively on the host CPU, so all
CPU extensions available on the host CPU can be also used inside the VM.
To expose that information to the VM we should pass "-cpu host", so the
VM is aware of which CPU is in use.
For CPU emulation, QEMU uses a rather minimal CPU on x86_64 by default.
It does not have support for SSE3/4 etc, which may be required for some
applications to work properly (e.g. Android in Anbox). Add a --cpu flag
to make the emulated CPU configurable. Useful values are for example
--cpu max to emulate all implemented CPU features.
To test QEMU's CPU emulation it is useful to have a switch to disable
KVM, even when it is available (and potentially working fine).
Add --no-kvm for that purpose.
For some reason, the SDL display backend changes the video resolution
to 1024x768, while the GTK display keeps it at 640x480.
This is annoying, because at the moment we can only set one display
resolution for a device in postmarketOS (e.g. for the splash screen).
At the moment, the resolution for the splash screen is set to 640x480,
which therefore shows up too small with the default SDL display.
It seems like the display resolution can be only changed in the guest
directly. Linux has a video= kernel parameter that can be used to
implement this. (See: https://www.kernel.org/doc/html/latest/fb/modedb.html)
Let's set 1024x768 by default, but make it configurable through --video.
The QEMU 'tablet' input device reports absolute positions instead
of relative mouse pointer movements. This can be used to automatically
grab/release the mouse pointer when entering/leaving the QEMU window,
instead of having to release it with CTRL + ALT + G manually.
This is quite convenient and should be the default option normally,
but at least on my PC the mouse pointer is reported with some vertical
offset for some reason (you can't reach the top and it extends below
the QEMU window...). Let's add it as an optional --tablet option for now.
To ensure consistent behavior for QEMU on all architectures,
it is helpful to try to use the same hardware elements where possible.
A few examples of current inconsistent behavior:
- x86_64 uses a SCSI disk, while aarch64 uses virtio-blk
- x86_64 uses e1000 network, while aarch64 uses virtio-net-device
- x86_64 uses PS/2 mouse, while aarch64 uses usb-mouse
- only x86_64 prints serial output to console
At least the virtio components are usually independent of the selected
architecture, so we can use them for both architectures.
This commit makes most of the hardware configuration shared:
- Redirect serial output to stdio
- virtio-blk for the disk image
- virtio-gpu-pci (this was already implicit for both architectures)
- virtio-net-pci for the network interface
- virtio-mouse-pci/virtio-keyboard-pci as input devices
- intel-hda for audio
We also set -nodefaults to avoid setting up unneeded devices
especially for x86_64.
Now that we try to use the IP assigned by QEMU via DHCP,
the debug-shell is no longer working via telnet.
This is because the VM does not have any IP assigned when it is running.
We would need to start a DHCP client from the initfs to make it work.
busybox provides both udhcpc (client) and udhcpd (server) so this is
not a big problem. But the question is: Is it worth it?
The debug-shell will be only used for debugging, and NetworkManager
handles starting a proper DHCP client once the rootfs is mounted.
Meanwhile the debug-shell can be also accessed via serial output/input,
(available in the pmbootstrap stdout/stdin). So overall it does not
seem worth the effort. Let's just recommend using serial instead.
The current network setup has weird side effects.
Normally, QEMU would automatically make the guest set up necessary
IP routes through its integrated DHCP server.
When running QEMU through pmbootstrap they are missing.
First, we change the DHCP range in a way that could potentially
conflict with default IPs used for QEMU's own services:
QEMU has the default gateway at <network>.2, and DNS at <network>.3.
We set the DHCP range to start at <network>.1, and will therefore
potentially give out one of these addresses (QEMU's default starts at
<network>.15).
See: https://wiki.qemu.org/Documentation/Networking#User_Networking_.28SLIRP.29
In practice this does not cause immediate problems because there is
just one guest in the network, and it will get <network>.1, which is
not used by QEMU.
More problematic is that we start a DHCP server from postmarketOS
at the same time (normally used for the USB network) and there are
actually two DHCP servers running at the same time.
QEMU's user networking is local to the process, therefore it is not
possible to access the QEMU guest through its IP from the host.
That's why we have the port forwardings so you can access SSH at
localhost:2222 for example.
In practice the network interface in the QEMU guest is only used to
access the Internet. For that, we don't care which IP address we get,
we just want to get a working setup (IP + routes + DNS) automatically
through DHCP.
To make this work nicely we just need to stop trying to fit QEMU's
network setup into our usual setup for USB networking. When we remove
the custom DHCP option, and avoid starting a DHCP server from postmarketOS
(deviceinfo_disable_dhcpd) everything is suddenly working fine. :)
device-qemu-vexpress appears to be completely broken at the moment.
I was not able to make it show anything, get a log or even just get
any indication that it is actually doing something.
In general, it does also not fit well to the other QEMU ports.
The vexpress machine type in QEMU seems to be quite limited,
e.g. it has no PCIe bus and therefore it is impossible to configure it
with virtio-gpu. (Unlike already configured for x86_64 and aarch64).
I had some success with a setup similar to aarch64 with -M virt,highmem=off
but was unable to make it work in the end:
- Alpine's virt kernel was missing some options preventing boot completely
- Alpine's lts kernel was missing PCI support for virtio-gpu
- Even after adding the options the VM usually freezed after boot
Overall it does not quite seem worth the effort at the moment,
compared to how well x86_64 and aarch64 are working.
In any case, vexpress is too different (and broken) to continue maintaining it.
When using pmbootstrap, you usually select the device you want to work
on using 'pmbootstrap init', generate the rootfs and can then run more
commands in the context of the device.
The same needs to be done before using QEMU (to generate the rootfs).
But for some reason 'pmbootstrap qemu' requires setting the --arch
parameter when running QEMU for a foreign architecture, even when the
device is still selected in pmbootstrap.
Even more confusing is that setting "--arch arm" always selects
device-qemu-vexpress, but this is not immediately clear from the name.
Let's make this a lot more intuitive by making sure there is a QEMU
device selected when running 'pmbootstrap qemu'. We can then use the
device information to infer the architecture automatically.
At the moment, the --display argument is a bit complicated to use.
A common use would be to switch between the UIs (sdl, gtk, none)
or to enable the software rasterizer. Split the two use cases
to separate arguments to make it more intuitive.
So far we tried to configure virtio-gpu using "-vga virtio" only
when the target architecture matches the host architecture.
But that's actually not what it depends on.
virtio-gpu and virgl can be also used when emulating a foreign
architecture. In fact, we already force usage of virtio-gpu for
aarch64 through "-device virtio-gpu-pci".
However, the "-vga virtio" parameter does not exist on aarch64,
no matter if we run QEMU natively on aarch64 or emulate it on x86_64.
(Apparently, -vga is mainly about legacy VGA framebuffer stuff that
we don't necessarily need. This is quite visible since the display
stays uninitialized on aarch64 until the kernel driver loads,
whereas on x86_64 it is initialized by the BIOS...)
In other words, "-vga virtio" belongs to the parameters specific to x86_64.
Now that we have removed the setup question for the Mesa driver to use
(since it was ineffective), it would still be nice to have some way to
choose if you want to use virtio-gpu/virgl or not.
But actually virtio-gpu can be also used with swrast, without virgl.
This happens automatically when QEMU is started without GL support.
We already have a --display parameter for this, so it is possible to
force swrast by using "--display sdl" (instead of the default sdl,gl=on).
Overall this allows simplifying the QEMU package setup because there is
only a single GPU driver in use (virtio-gpu) instead of the 3 we had before
(virtio, qxl, bochs).
mesa-dri-swrast and mesa-dri-virtio are both provided by mesa-dri-gallium
now, so this option does not have much use anymore. With both selections,
exactly the same packages are installed.