Upgrade/crossgrade a system to a different architecture (e.g. convert system from i386 to amd64). For more information about multi-architecture systems, see CategoryMultiarch. For other up/downgrade topics, see Install, remove, and change software versions.
Note that crossgrading is not officially supported!
Attempts to do so may result in very broken system. If one is not quite experienced Debian sysadmin, quite competent at untangling and fixing broken Debian package situations, and quite competent at fixing broken unbootable Debian systems, it is recommended one does not attempt crossgrading (or at least on any systems that actually matter).
This page primarily uses examples of switching from i386 to amd64, but the same approach should work for any pair of architectures that work on the same machine (e.g. armel and armhf).
Contents
-
Preparation
- Important introductory notes
- Recommended: Upgrade to the latest update of ...
- References to additional recommended, etc. preparation steps
- Recommended: specific files/state backup
- Recommended: check/purge obsolete
- Suggested: have ar, curl, and wget
- dpkg configuration for from and target architectures
- APT configuration for target architecture
- Highly recommended: do crossgrade operations from (relatively) safe environment
- kernel
- dpkg/apt architectures
- read the documentation, then select with or without crossgrader
- Continue via crossgrader (highly advised)
- Continue without using crossgrader
- Caveats and Known Problems
- See also
- Sample cross-grade script
This wiki page is and may always continue to be a(n unfinished) work-in-progress. Strongly recommend to at least consider reinstall, or certainly at least create a full backup before attempting crossgrading.
Preparation
Important introductory notes
It is highly advised to use the crossgrader package if at all feasible. It first entered Debian in 2020.
See: https://salsa.debian.org/crossgrading-team/debian-crossgrading/-/blob/master/INSTRUCTIONS.md
and also content below. Using crossgrader will make crossgrading on the order of magnitude(s) easier, more (semi-)automated, and generally less prone to errors/breakage. Only question on order of magnitude(s) may be in what base number system ... base-64, ... base-16, base-8, ... base-2 ... certainly orders of magnitude better if we're talking base-2.
Crossgrading in many ways is similar to major release version upgrade. It's a major operation on the system. But unlike major release version upgrades, is not officially supported, and it's much more highly prone to breakage and one is almost guaranteed to encounter some moderate to more significant breakage or other issues along the way. One should be well prepared for and competent to handle that, otherwise crossgrading may not be for you, at least on any systems that particularly matter.
Almost all of the preparation steps for a major version upgrade also quite apply for crossgrading, both in (strongly) suggested/recommended, and required steps. So, will first cover here the preparation that's relevant whether or not one will crossgrade via crossgrader (highly advised, and will call out where that makes a difference in preparation). Presume steps in this section are required, unless stated otherwise. One should also
read through all of the relevant documentation before proceeding, as not all matters of relevance are covered here.
Recommended: Upgrade to the latest update of ...
Suggested: To avoid potential issues with available package versions changing while one is crossgrading, one may wish to reconfigure apt to use snapshot.debian.org and configure that in apt for a specific point in time.
E.g.:
# awk '{if($1 ~ /^deb/)print;}' /etc/apt/sources.list
deb http://deb.debian.org/debian/ bookworm main contrib non-free non-free-firmware
deb-src http://deb.debian.org/debian/ bookworm main contrib non-free non-free-firmware
deb http://security.debian.org/debian-security bookworm-security main contrib non-free non-free-firmware
deb-src http://security.debian.org/debian-security bookworm-security main contrib non-free non-free-firmware
deb http://deb.debian.org/debian/ bookworm-updates main contrib non-free non-free-firmware
deb-src http://deb.debian.org/debian/ bookworm-updates main contrib non-free non-free-firmware
# ex /etc/apt/sources.list
/etc/apt/sources.list: unmodified: line 18
:%s/deb\.debian\.org\/debian/snapshot.debian.org\/archive\/debian\/20250804T024817Z/p
deb http://snapshot.debian.org/archive/debian/20250804T024817Z/ bookworm main contrib non-free non-free-firmware
deb-src http://snapshot.debian.org/archive/debian/20250804T024817Z/ bookworm main contrib non-free non-free-firmware
deb http://snapshot.debian.org/archive/debian/20250804T024817Z/ bookworm-updates main contrib non-free non-free-firmware
deb-src http://snapshot.debian.org/archive/debian/20250804T024817Z/ bookworm-updates main contrib non-free non-free-firmware
:%s/security\.debian\.org\/debian-security/snapshot.debian.org\/archive\/debian-security\/20250804T032340Z\//p
deb http://snapshot.debian.org/archive/debian-security/20250804T032340Z/ bookworm-security main contrib non-free non-free-firmware
deb-src http://snapshot.debian.org/archive/debian-security/20250804T032340Z/ bookworm-security main contrib non-free non-free-firmware
:wq
/etc/apt/sources.list: 18 lines, 1328 characters
#
In the above, we first used awk to note the lines we want to change.
We then used the ex(1) command to do the substitutions to use snapshot.debian.org for a specific point in time for each of our repositories. For more information on snapshot.debian.org and how to use it, see: https://snapshot.debian.org/
If the ex(1) part might be a bit confusing, the ex command is same program as vi(1), but invoking it as ex starts it directly in ex (line oriented colon (:) prompt) mode, rather than visual mode. In vi's/ex's visual mode, any time one starts a command with : one is in fact giving an ex command, here we just go directly to that, notably to better capture and show our output line-by-line, rather than visual mode. In vi/ex in visual mode, one can enter those ex commands exactly the same; just enter the leading : as shown (whereas in ex mode, ex prompts with that : so one wouldn't enter that leading : character when in ex mode).
Also, in these examples, using ex(1) as provided by the nvi package, rather than one of the vim (e.g. vim-tiny or vim) packages. Commands shown in either case are same, but output format will be a moderate bit different (most notably the vim flavors being more verbose).
Recommended: upgrade to the latest update of Debian stable (or the last update of earlier release as necessary) from one's configured repository(/ies) that supports the architectures one is crossgrading from and to as fully installed and installable running systems, e.g. Debian 12 "bookworm" for crossgrading from i386 to amd64 (or vice versa) architectures.
E.g. be sure to successfully complete:
# apt update && apt upgrade && apt full-upgrade
References to additional recommended, etc. preparation steps
Preparation that's not specific to crossgrading.
For that, most notably refer to the Debian's release notes. It's suggested that for Debian N (e.g. N=12 ("bookworm")), one review the release notes for Debian N+1 (e.g. "trixie"), as notably that well covers preparing N for upgrade (highly applicable likewise for crossgrade). Just be sure to stop short of any portions which update apt configuration from N to N+1 (e.g. from bookworm to trixie). Also, if release notes for N+1 aren't available or not yet in suitable form (e.g when that's testing, and not fairly close to becoming the next new stable), then the release notes for N should be an excellent next best, and still highly applicable. Also, on release notes, select the architecture one is migrating from (if still available on that release), or if not, the architecture one is migrating to. Likewise if not (yet) available for that release, use release notes from next older major release, continuing back as necessary. So, e.g., if one is crossgrading from 12 i386 to amd64 (must crossgrade within same major version number / release), one would use release notes for trixie (to be 13), but since i386 isn't installable on trixie, one would use the amd64 trixie release notes for most preparation steps.
Preparation that's specific to crossgrading.
Won't generally cover here what's covered in the immediately above, but may include some recommendations/suggestions from such. Will cover here what's common to both doing the upgrade via crossgrader (highly advised), or without using crossgrader, and will call out any portions that differ between those approaches.
Recommended: specific files/state backup
Recommended: Mostly as per release notes, backup particularly important information about packages and states.
# (cd / && tar -cf - etc var/lib/dpkg var/lib/apt/extended_states) > var-lib-dpkg_var-lib-apt-extended_states.tar
$ dpkg --get-selections '*' > dpkg_--get-selections_'*'
Suggested: if one will or may be using crossgrader, due to a certain bug that may be present in one's version of crossgrader,
it may be particularly convenient to first create a backup of the file:
/usr/share/initramfs-tools/hook-functions
presuming one has that file, via, e.g.:
# (cd / && tar -cf - ./usr/share/initramfs-tools/hook-functions) > usr.share.initramfs-tools.hook-functions.tar
Recommended: Notably if one may later wish to restore or compare/review, also save the apt-mark auto/manual status information:
$ apt-mark showauto > apt-mark_showauto; apt-mark showmanual > apt-mark_showmanual
Recommended: check/purge obsolete
Recommended: Check for and purge obsolete packages:
$ apt list '~o'
# apt purge '~o'
Suggested: have ar, curl, and wget
Suggested, have ar (in package binutils), curl, and wget installed and available. Requesting apt to install them if already installed does no harm, e.g.:
# apt install binutils curl wget
dpkg configuration for from and target architectures
dpkg needs to be configured for both the architecture one is crossgrading from, and crossgrading to. Later after dpkg is replaced (itself a critical operation), those two architectures will flip as far as dpkg is concerned, and the APT system likewise follows dpkg in that regard.
Recommended: check the current situation:
$ dpkg --print-architecture; dpkg --print-foreign-architectures
The first output line from that will show dpkg's current architecture, it needs be the architecture one is crossgrading from (at least to be able to follow what's generally documented on this wiki page). Any subsequent line(s) should include the architecture one is crossgrading to. If that's not already the case, add that architecture, e.g. for target of amd64 as shown below:
Add the target architecture (required if not already set, no harm in running this additional times), e.g.:
# dpkg --add-architecture amd64
APT configuration for target architecture
Required if not using crossgrader,
if using crossgrader only possibly suggested - read the immediately below information if using crossgrader, otherwise one can skip the immediately below informational point, and continue right beyond that, as in that case it's required.
If using crossgrader: reconfiguring apt for target architecture is entirely unneeded! But read on.
For significant convenience on kernel step,
one may well wish to implement this (further below) change before kernel step (e.g. now),
then immediately after kernel step revert it (example) if one is using the crossgrader procedures.
Rationalle: crossgrader apparently highly well handles target architecture without need to configure apt for that or multiarch at all. And if using crossgrader, it's much better to use crossgrader for any needed crossgrading to or installation of target architecture packages, whereas it's comparatively much more hazardous to make manual use of apt commands or dpkg. Hence not configuring multiarch in apt may reduce the probability of errors/accidents/breakage (at least before dpkg and apt have been successfully crossgraded, may not matter as much after that), most notably to avoid potential use of apt or dpkg, by accident, e.g. out of habbit, where one should really be using crossgrader instead (notably also including it's -p option as may be appropriate).
Required if not using crossgarder: Configure apt to include target architecture. E.g. for the older style apt configuration, for each deb (ignore deb-src) configuration line, set architecture specification to include both the migrating from and target architectures. E.g. set 2nd field to: [arch=amd64,i386], example so setting:
# ex /etc/apt/sources.list
/etc/apt/sources.list: unmodified: line 18
:%s/deb h/deb [arch=amd64,i386] h/p
deb [arch=amd64,i386] http://snapshot.debian.org/archive/debian/20250804T024817Z/ bookworm main contrib non-free non-free-firmware
deb [arch=amd64,i386] http://snapshot.debian.org/archive/debian-security/20250804T032340Z/ bookworm-security main contrib non-free non-free-firmware
deb [arch=amd64,i386] http://snapshot.debian.org/archive/debian/20250804T024817Z/ bookworm-updates main contrib non-free non-free-firmware
:wq
/etc/apt/sources.list: 18 lines, 1382 characters
#
apt update
Required after updating apt configuration such as the immediately above, so it can know about, e.g. available packages and versions, changes in architecture(s) configuration and/or repositories, etc.:
# apt update
Highly recommended: do crossgrade operations from (relatively) safe environment
Highly recommended:
Do crossgrade operations from (relatively) safe environment, similar to as stated in release notes, but here we want to restrict a bit further, due to higher probability of issues that may need repair. The crossgrading operations should be done locally or at least with equivalent access. One may not only require console access, but also, e.g. access to power cycle the system, boot from alternative media, enter special sequences on locally attached keyboard, etc. So, via ssh or other connection that may break remotely and not be reestablished without local access should be avoided. If one does attempt over ssh, one should do so under tmux or screen session, so that may be reattached to, but no guarantees that won't fail. Likewise one should not attempt crossgrade via X11 or Wayland or the like, or any type of graphic environment provides by the host. So, e.g. direct use of display output with no graphics, and directly attached keyboard would typically be best. Serial console may also be quite acceptable, but as feasible, one should have the other local access/control as noted. Network console is not recommended. One should also well heed the preparation steps, including those recommended here, and in release notes, etc.
kernel
Install suitable kernel of target architecture.
E.g. for target architectures amd64:
# apt install linux-image-amd64:amd64
Do not reboot (may be (in)advisable) before properly reviewing the below.
Scenario A: The most common scenario, where from architecture is runnable subtype of target architecture,
but not vice versa, e.g. i386 to amd64 crossgrading (and which is used for most of the examples on this wiki page), we will generally want to reboot to kernel of target architecture as soon as feasible, e.g. once it and its dependencies have been successfully installed.
Scenario B: Less common scenario, where target architecture is runnable subtype of from architecture,
but not vice versa, e.g. amd64 to i386 crossgrading, we will generally want to defer: rebooting, rebooting to target architecture kernel, and removing of from architecture kernels to much later in the procedures. Most notably will want most all from architecture packages to have their corresponding target architecture packages installed before rebooting or booting to target architecture kernel, and likewise for removing/purging of from architecture kernel(s).
Scenario C: More complex scenario than the above, e.g. hardware can run either architecture, but neither is a runnable subtype of the other, crossgrader package may well be able to assist with that by the VM type package(s) it will want to bring in to deal with such scenario, but any details of that scenario haven't been documented on this wiki page. Likewise in such case, one may (e.g. without crossgrader procedures) install and use relevant qemu and/or other VM package(s) to be able to handle such a case.
For Scenario A above: shutdown and boot kernel of target architecture.
Note it may not be the default boot kernel, so one may need to select it.
For Scenario B or Scenario C above, do not (re)boot at this time, will want to defer that as mentioned in Scenario B above, and likewise applies to Scenario C.
dpkg/apt architectures
Suggested: if one is using crossgrader and earlier added target architecture to apt configuration, one can now strip that as earlier suggested. To do that, see e.g.: strip explicit architecture configurations from apt (but just that one part in that set of post-crossgrade cleanup, etc. procedures)
Important note:
(Don't attempt to crossgrade these yet - covered in more detail in sections further below)
Crossgrading dpkg changes the non-foreign architecture to that of dpkg, and what was the non-foreign architecture then becomes a foreign architecture. So that effectively flips those as far as dpkg is concerned. Note also that breaking dpkg can make things quite challenging.
apt's default architecture and logic regarding additional architectures is compiled in, but those can also be configured. However, typically that portion of configuration hasn't been set/changed/customized, in which case apt behaves similar to dpkg. Note that also means if at any time the apt package itself is not of same architecture as dpkg, that can make things quite challenging. See also: apt.conf(5):THE APT GROUP
So, it's generally quite important to cover crossgrading of dpkg and apt and their [Pre-]Depends: packages in the right grouping and sequence to avoid quite challenging situations. Fortunately the crossgrader package well handles this, and many other matters.
read the documentation, then select with or without crossgrader
Suggested to read all materials, but as for procedural ordering, if
using crossgrader (highly advised), continue with the
Continue via crossgrader (highly advised) section below, if
not using crossgrader, skip to
Continue without using crossgrader section.
Continue via crossgrader (highly advised)
Before first stage
Install crossgrader (current/from architecture)
# apt install crossgrader
Recommend run crossgrade-package-check exactly once:
# crossgrade-package-check
A few notes on crossgrader (at least as of version 0.0.3+nmu3):
with crossgrader, in general do not use apt programs or dpkg to attempt to work around any issues or failures, most notably for cross-grading any packages. Resist the temptation, and instead, use crossgrader's -p option and that will generally well do exactly what's needed to crossgrade specific package(s), including handling all dependencies, etc. Note also that the man page syntax may not be quite correct on that option. When that option is used, it must be last, and only that option's arguments follow, and the architecture must be given before that option
- one can generally repeat command for/at same stage in that step along the sequence, without harm, and in some cases that may be exactly what's needed, and crossgrader may even inform one of that. It's also a good check, as when doing so, if it earlier already quite fully and cleanly completed, repeating command will generally have quite clean output.
- the stdout/stderr from crossgrader may be quite verbose, and though many of its reported errors and failures (often from underling programs) may in many cases be safe to ignore (e.g. many things it will retry or apply work-arounds, etc.), one shouldn't entirely ignore such output, as it may well contain relevant important information, e.g. exactly which package failed and (probably) why, or that one should in fact run same step again.
First stage
Recommended, preview first stage:
# crossgrader --dry-run amd64
Run first stage:
# crossgrader amd64
Note that it may (partly) fail, but may also give highly useful information as part of its (often verbose) output, e.g.:
Please re-run the first stage to continue the crossgrade
So, e.g. in such case, run it again as before.
One may get quite useful information in stdout/stderr, e.g.:
crossgrader initramfs hook: (WARNING) initramfs binary /sbin/logsave
might not be in the correct architecture.
crossgrader initramfs hook: Ensure that it can be executed or crossgrade
the package containing it, then update the initramfs again.
crossgrader initramfs hook: output of `file /sbin/logsave`:
/usr/share/initramfs-tools/hooks/fsck: 273: file: not found
In, e.g., that case, by inspection, we can see that
we lack the file(1) program (provided by the file package in our case here),
/sbin/logsave belongs to package that hasn't been crossgraded yet,
but apparently we should have those both available and installed in target architecture,
for the first stage to complete successfully in its entirety,
so then the fix/work-around for that is
not to use dpkg or apt commands, but rather
use crossgrader itself, e.g.:
# crossgrader amd64 -p file logsave
In such a case as that, one should be able to repeat until run of first stage, e.g. repeating:
# crossgrader amd64
gives quite clean successful output.
Suggested: At the conclusion of clean completion of first stage, we can confirm that apt and dpkg have been crossgraded, and that the roles of our dpkg non-foreign and target foreign architectures have flipped:
$ dpkg -l apt dpkg | grep '^ii '; dpkg --print-architecture; dpkg --print-foreign-architectures
ii apt 2.6.1 amd64 commandline package manager
ii dpkg 1.21.22 amd64 Debian package management systemv
amd64
i386
$
And with that, henceforward, dpkg defaults to our target architecture, and typically apt is well set to behave likewise.
Second stage
Once the above is quite cleanly completed, we're ready to proceed to second stage.
# crossgrader --second-stage amd64
In, e.g. our case, that fails, notably because name for the kernel packages between the two different architectures isn't the same. Finding no other errors, we basically tell it not to worry about that, and continue regardless (notably as we've already installed and are running the needed target architecture kernel):
# crossgrader --second-stage --force-unavailable amd64
And again, repeat running the second stage, as needed, until it completes quite cleanly.
Third (optional) stage and additional recommended/suggested cleanup
Once that's quite cleanly completed, we can proceed to the
optional third stage, which removes packages of the migrated from architecture (in our example case here i386):
# crossgrader --third-stage i386 --dry-run amd64
# crossgrader --third-stage i386 amd64
Note however, once that last command has cleanly completed, running it again, at least as of version 0.0.3+nmu3, will throw an error, including e.g.:
dpkg: error: --purge needs at least one package name argument
if there are no remaining packages of the migrated from architecture. (merged fix)
See also the immediately below.
And likewise optional: One can use, e.g.:
$ dpkg -l | grep -F i386
to check if any i386 architecture packages remain.
Recommended: And if was run before, can run it exactly one more time:
# crossgrade-package-check
In our i386 --> amd64 case, it complains about our old kernel package name(s), since name doesn't match on target architecture. That complaint can be ignored in our example case. Other than that, should generally report no issues about packages that existed in migrated from architecture that don't have corresponding packages installed for target architecture of same package name. But note that in some cases there may be exceptions (e.g. libraries not named identically between two different architectures, or package not available in target architecture).
Further suggested/recommended cleanups:
Recommended:
# crossgrader --cleanup amd64
Suggested, and one may want to use -s or --simulate option first, or very carefully review before replying in the affirmative (default), and not give the -y option:
# apt purge crossgrader
Note that there is bug ?#1114664 in crossgrader, notably at least version 0.0.3+nmu3,
may possibly also apply to versions 0.0.3+nmu4 and 0.0.3+nmu5 (and possibly later),
and may in same or similar manner apply to some or all earlier versions.
Notably using (but not merely installing) crossgrader, with that bug alters file:
/usr/share/initramfs-tools/hook-functions
belonging to package:
initramfs-tools-core
causing it to depend upon the crossgrader package,
so once crossgrader package is removed or purged, then various initramfs operations fail.
Even, e.g.:
# crossgrader --dry-run amd64
causes crossgrader to alter the file:
/usr/share/initramfs-tools/hook-functions
Work-around:
This can be remedied by restoring the
/usr/share/initramfs-tools/hook-functions
file to as it was before the crossgrader package altered it
(and preferably after crossgrader has been removed or purged, so it won't repeat that issue).
One can also restore that file by (re)installing the package that provides it, e.g.:
# apt --reinstall install initramfs-tools-core
After that, one may still have packages in (semi-)broken states,
notably due to configuration failures when making use of initramfs operations while the bug was active.
That can then generally be remedied, after restoring the file as noted above, by, e.g.:
# dpkg --configure -a
Suggested, and one may want to use -s or --simulate option first, or very carefully review before replying in the affirmative (default), and not give the -y option, and continue cleanup with:
# apt autopurge
Suggested: Installing crossgrade may have pulled in many packages that weren't there before, and that may have also gotten marked as manually installed. One may want to remove or purge those, or mark them as having been automatically installed. E.g. with this
$ apt -s purge $({ awk '{print; print;}' apt-mark_showauto apt-mark_showmanual; { apt-mark showauto; apt-mark showmanual; } | sort -u; } | sort | uniq -u | grep -v '^linux-image-')
where we'd (optionally) saved the data before, simulation run to purge packages that weren't there before, but filtering out kernel so we don't remove that. May want to review that, possibly exclude more packages, and then remove or purge (or mark as having been automatically installed).
Suggested: If one no longer has any packages installed from the migrated from architecture, and wishes to remove that architecture, one may do so: First reconfigure apt to remove that architecture.
To, e.g. strip explicit architecture configurations from apt:
# ex /etc/apt/sources.list
/etc/apt/sources.list: unmodified: line 18
:%s/ \[arch=[^ ]*\] / /p
deb http://snapshot.debian.org/archive/debian/20250804T024817Z/ bookworm main contrib non-free non-free-firmware
deb http://snapshot.debian.org/archive/debian-security/20250804T032340Z/ bookworm-security main contrib non-free non-free-firmware
deb http://snapshot.debian.org/archive/debian/20250804T024817Z/ bookworm-updates main contrib non-free non-free-firmware
:wq
/etc/apt/sources.list: 18 lines, 1328 characters
#
Suggested: if apt is already suitably configured, and one no longer wishes dpkg to be configured for our from (now foreign) architecture or all such, we can remove that (or any and/or all) foreign architectures from dpkg, e.g.:
removing just one (e.g. i386) foreign architecture from dpkg's configuration:
# dpkg --remove-architecture i386
removing all foreign architectures from dpkg's configation:
# (for foreign in $(dpkg --print-foreign-architectures); do dpkg --remove-architecture "$foreign"; done)
Recommended: if one (temporarily) reconfigured repositories in apt (e.g. to snapshot.debian.org) during the crossgrading procedure, one may wish to change those back to the nominal repositories one generally wishes to use, e.g.:
# ex /etc/apt/sources.list
/etc/apt/sources.list: unmodified: line 18
:%s/snap.*-security.*Z\//security.debian.org\/debian-security/p
deb http://security.debian.org/debian-security bookworm-security main contrib non-free non-free-firmware
deb-src http://security.debian.org/debian-security bookworm-security main contrib non-free non-free-firmware
:%s/snap[^ ]*/deb.debian.org\/debian\//p
deb http://deb.debian.org/debian/ bookworm main contrib non-free non-free-firmware
deb-src http://deb.debian.org/debian/ bookworm main contrib non-free non-free-firmware
deb http://deb.debian.org/debian/ bookworm-updates main contrib non-free non-free-firmware
deb-src http://deb.debian.org/debian/ bookworm-updates main contrib non-free non-free-firmware
:wq
/etc/apt/sources.list: 18 lines, 1156 characters
#
Optional: apt-mark status restore: If one earlier saved apt-mark auto/manual state information, one may wish to restore that. Most notably through the crossgrade process, many packages that were earlier marked as automatically installed, will often have their status changed to manually installed, and perhaps even vice versa. If one created and saved the files as earlier recommended, these commands can be run to revert the settings on the applicable installed packages to their corresponding earlier apt-mark auto/manual settings, e.g. in this example our migrated from architecture is i386 and our migrated to architecture is amd64. In the below, our first command restores mark of auto where applicable, and the second likewise restores mark of manual where applicable. They are independent, so one can run none, either, or both of them, and they can be run repeatedly without harm:
# (if [ -f apt-mark_showauto ]; then mkauto=$({ { grep -v ':amd64$' apt-mark_showauto; dpkg -l | awk '{if($1 ~ /^ii$/ && $4 !~ /^i386/)print $2;}'; } | sort | uniq -d; apt-mark showauto | awk '{print; print;}'; } | sort | uniq -u); [ -z "$mkauto" ] || apt-mark auto $mkauto; else echo missing file: apt-mark_showauto 1>&2; ! :; fi)
# (if [ -f apt-mark_showmanual ]; then mkmanual=$({ { grep -v ':amd64$' apt-mark_showmanual; dpkg -l | awk '{if($1 ~ /^ii$/ && $4 !~ /^i386/)print $2;}'; } | sort | uniq -d; apt-mark showmanual | awk '{print; print;}'; } | sort | uniq -u); [ -z "$mkmanual" ] || apt-mark manual $mkmanual; else echo missing file: apt-mark_showmanual 1>&2; ! :; fi)
Optional: One may also want to review the mark status of packages now present that weren't present before, and possibly adjust their mark status. The bit of code below may be quite handy for that.
Some notes on this code example:
- It is in fact two lines, it contains a single quoted embedded newline.
- I show the customary non-root PS1='$ ' prompt on the first line, notably to indicate it doesn't require root to run,
however, I ommit showing customary PS2='> ' prompt one would see after the first line of shell prompting for remainder of command to complete the command. I do that notably so one can copy/paste it, but in that case, do ommit the shown leading PS1 prompt on the first line.
In present form, it uses bash style <(list) process substitution syntax, so will generally require bash shell.
- It's relatively flexible regarding the from(=) and target (to=) architectures. Notably in the outputs
from dpkg -l (Name field), and apt-mark showauto and apt-mark showmanual where the package names may have a traling :architecture indicator, where that architecture is our from or target (to=) architecture, those portions are stripped off for doing our comparisons. Notably for ease of flexiblity on these various data sources, regardless which architecture was/is non-foreign, and if foreign architecture(s) were/are present at the times, it still will essentially do the right thing. But that does also mean, in its output, it won't show those architectures (but if there are additional foreign architecture(s) at the time, those parts aren't stripped off, and will show), but just the package name, without that portion. That also means a package may show as both auto and manual for the same package, notably if both the from and target (to=) versions of the package are installed, and one is marked auto, and one manual.
- for each package present (based on package name as noted above), that wasn't present when the earlier (recommended) file data was collected, one output line will display, with that package name for the first field, and second field of auto or manual, showing its present status, or in the case of both from and target (to=) architectures being currently installed, if one is set to auto and the other manual, it will still give a single line, but in that case, there will be three field, second field being auto and third being manual.
$ (from=i386 to=amd64 nl='
'; { [ -f apt-mark_showauto ] || { echo missing file: apt-mark_showauto 1>&2; ! :; }; } && { [ -f apt-mark_showmanual ] || { echo missing file: apt-mark_showmanual 1>&2; ! :; }; } && { auto="$(apt-mark showauto | sed -e 's/:'"$from"'$//;t;s/:'"$to"'$//;' | sort -u)"; manual="$(apt-mark showmanual | sed -e 's/:'"$from"'$//;t;s/:'"$to"'$//;' | sort -u)"; new="$( { sed -e 's/:'"$from"'$//;t;s/:'"$to"'$//;' apt-mark_showauto apt-mark_showmanual | sort -u | awk '{print;print;}'; dpkg -l | awk '{if($1 ~ /^ii$/) print $2;}' | sed -e 's/:'"$from"'$//;t;s/:'"$to"'$//;'; } | sort | uniq -u)"; newauto=; [ -n "$new" ] && [ -n "$auto" ] && newauto="$(comm -12 <(printf '%s\n' "$auto") <(printf '%s\n' "$new"))"; newmanual=; [ -n "$new" ] && [ -n "$manual" ] && newmanual="$(comm -12 <(printf '%s\n' "$manual") <(printf '%s\n' "$new"))"; if [ -n "$newauto" ]; then if [ -n "$newmanual" ]; then { comm -23 <(printf '%s' "${newauto:+$newauto$nl}") <(printf '%s' "${newmanual:+$newmanual$nl}") | sed -e 's/$/ auto/'; comm -13 <(printf '%s' "${newauto:+$newauto$nl}") <(printf '%s' "${newmanual:+$newmanual$nl}") | sed -e 's/$/ manual/'; comm -12 <(printf '%s' "${newauto:+$newauto$nl}") <(printf '%s' "${newmanual:+$newmanual$nl}") | sed -e 's/$/ auto manual/'; } | sort; else printf '%s' "${newauto:+$newauto$nl}" | sed -e 's/$/ auto/'; fi; elif [ -n "$newmanual" ]; then printf '%s' "${newmanual:+$newmanual$nl}" | sed -e 's/$/ manual/'; fi; })
And here's the output of an example run:
linux-image-6.1.0-37-amd64 auto
linux-image-amd64 manual
In that particular case, the only "new" packages (different package names) are our kernel related packages, as the packages names, and not even with any trailing :architecture portion for our from or target (to=) architectures, contain architecture (or related) specific strings as part of the name of the package itself, so of course they don't match the kernel package names from the from architecture in such case.
Optional: If one created extra backup files of package state, etc., one may wish to remove those (or schedule removal for future, e.g. via at(1)).
(strongly) recommended: Reboot soon, to target architecture kernel, to check/ensure that all works properly, and that one is no longer using (unlinked open) files from packages that were removed.
If you've successfully made it to here in the procedures, congratulations! You've successfully crossgraded the system(s)! In any case, still quite advised to be sure to review Caveats and Known Problems for known issues that may be present or show up, and in many cases with the information how to check and fix.
Continue without using crossgrader
CAUTION!/WARNING!/DANGER!
It is STRONGLY ADVISED ONLY EXPERT DEBIAN (or at least APT based) SYSADMINS ATTEMPT THIS SECTION at least on any systems that matter. To be reasonably likely to succeed one will almost certainly need to be highly skilled at:
APT and dpkg package management, notably well including how to well analyze and fix even potentially critical broken and semi-broken and inconsistent states, without further damage.
CLI use to well analyze and summarize relevant data, most notably status of various packages of various architectures, dependencies, pre-dependencies, logical ordering of steps, including how to fix things and not break things, how to take appropriate actions from such information in appropriate sequence, and highly preferably how to do so for reasonable scale / (semi-)automation.
If you don't meet that criteria, you are advised to stop, and not attempt this procedure on any systems that matter.
Required: reminder: be sure to cover the Preparation section before continuing here.
Make sure all packages are in sync between architectures
Check all the versions of packages to be crossgraded in this step, to make sure all e.g. amd64/i386 packages have matched package name and version between the from and target architectures. Some minor exceptions may be okay (and may need some additional manual handling or attention). More generally though, if packages and versions don't match, crossgrade is probable to seriously break.
Crossgrade dpkg, apt, etc.
dpkg, apt, and all their [Pre-]Depends: need to be crossgraded, and in correct ordering and grouping, manually, and/or by dpkg, or (in part) apt (apt here more useful to resolve and download, not install/crossgrade), or possibly other means.
Failure to get that right can result in breakage that's challenging to recover from.
Get all the packages needed to replace dpkg, apt, and all [Pre-]Depends: thereof. Then install them for the new architecture in appropriate sequence/grouping so it all works.
The [Pre-]Depends: are different in different Debian releases. Be sure to also see examples further below, they may be quite usefully informative, even if they don't match one's specific release. Here's some higher-level information on the (additional) needed:
sid: (updated needed, ~2020-10 it was: add add tar:amd64 apt:amd64 apt-utils:amd64 perl-base:amd64 libsystemd0:amd64, see also more detailed example further below)
trixie: (update needed)
bookworm: (see more detailed examples further below)
bullseye: add tar:amd64 apt-utils:amd64 perl-base:amd64 (see also more detailed example further below)
buster: add just tar:amd64
To install packages in the correct grouping/sequencing, first gather them locally (e.g. download them with apt) and then install them with dpkg. See examples further below.
Example, this one from Debian 12.11 "bookworm", on a relatively minimally installed system, and including moderate bit of the information/steps to figure out the sequencing/grouping:
We review
$ apt-cache show dpkg:amd64
$ apt-cache show apt:amd64
Most notably reviewing any Pre-Depends: and Depends:
From that, we try some
$ apt -s install ...
possibilities looking for a likely solution. We want to replace dpkg and apt and install their dependencies in a single go (or as close to that as feasible). We decide based upon that to go with these commands:
# apt clean
# cd /var/cache/apt/archives
# apt -d install dpkg:amd64 dpkg- tar:amd64 tar- apt:amd64 apt-
Note that with an apt or dpkg install/remove/purge command, appending - character to the end of a package argument requests that package be removed. Likewise appending a + character requests that the package be installed. This is sometimes necessary when, e.g. two packages conflict (such as same package and version, but different architectures, and they can't both be in installed state at same time), but one needs to always be present and installed (e.g. because it's essential, or because of dependencies upon it, etc.). See also: apt-get(8)
$ dpkg --dry-run -i *.deb
Above gives us Pre-Depends: issues, so, based on that:
$ dpkg --dry-run -i libbz2-1.0_* libacl1_*
That looks good, so
# dpkg -i libbz2-1.0_* libacl1_*
That looks good, so:
$ dpkg --dry-run -i $(ls *.deb | grep -v -e '^libbz2-1\.0' -e '^libacl1')
Above gives us Pre-Depends: issues, so, based on that:
$ dpkg --dry-run -i liblzma5_* libselinux1_*
That looks good, so:
# dpkg -i liblzma5_* libselinux1_*
But that gives us errors, so, based upon those diagnostics:
$ dpkg --dry-run -i liblzma5_* libselinux1_* libpcre2-8-0_*
That looks good, so:
# dpkg -i liblzma5_* libselinux1_* libpcre2-8-0_*
That looks good, so:
$ dpkg --dry-run -i $(ls *.deb | grep -v -e '^libbz2-1\.0' -e '^libacl1' -e '^liblzma5' -e '^libselinux1' -e '^libpcre2-8-0')
Above gives us Pre-Depends: issues, so, based on that:
$ dpkg --dry-run -i libmd0_*
That looks good, so:
# dpkg -i libmd0_*
That looks good, so:
$ dpkg --dry-run -i $(ls *.deb | grep -v -e '^libbz2-1\.0' -e '^libacl1' -e '^liblzma5' -e '^libselinux1' -e '^libpcre2-8-0' -e '^libmd0')
Above gives us Pre-Depends: issues, so, based on that:
$ dpkg --dry-run -i libzstd1_*
That looks good, so:
# dpkg -i libzstd1_*
That looks good, so:
$ dpkg --dry-run -i zlib1g_*
That looks good, so:
# dpkg -i zlib1g_*
That looks good, so:
$ dpkg --dry-run -i $(ls *.deb | grep -v -e '^libbz2-1\.0' -e '^libacl1' -e '^liblzma5' -e '^libselinux1' -e '^libpcre2-8-0' -e '^libmd0' -e '^libzstd1' -e '^zlib1g')
That looks good, so:
# dpkg -i $(ls *.deb | grep -v -e '^libbz2-1\.0' -e '^libacl1' -e '^liblzma5' -e '^libselinux1' -e '^libpcre2-8-0' -e '^libmd0' -e '^libzstd1' -e '^zlib1g')
And:
# dpkg -l dpkg apt | grep '^ii '
ii apt 2.6.1 amd64 commandline package manager
ii dpkg 1.21.22 amd64 Debian package management system
# dpkg --print-architecture; dpkg --print-foreign-architectures
amd64
i386
#
That all looks good, dpkg crossgraded, so our target architecture is now dpkg's non-foreign, and our from architecture is now configured as foreign with dpkg, and apt is now also crossgraded. If we don't mess up, the rest should be fairly straight-forward.
And here and (often) elsewhere on this wiki page, showing
comments with a leading ": # ",
root/superuser/UID 0 prompt as a customary leading "# ",
and where root not needed, prompt as customary leading "$ " (for at least some POSIX-ish compatible shell, e.g. dash or bash)
A more concise code/example/approach for sid (2020-10) / bookworm / bullseye:
: # Remove files in /var/cache/apt/archives/ : # to make the "*_amd64.deb" below do the right thing: # apt clean : # Download packages you will definitely need: # apt --download-only install dpkg:amd64 tar:amd64 apt:amd64 : # Add extra packages for your version of Debian: : # sid (tested 2020-10): # apt --download-only install dpkg:amd64 tar:amd64 apt:amd64 libsystemd0:amd64 : # bookworm: # apt --download-only install dpkg:amd64 tar:amd64 apt:amd64 dpkg:i386- tar:i386- apt:i386- : # bullseye: # apt --download-only install apt-utils:amd64 perl-base:amd64 : # Due to pre-dependencies you may have to run this more than once : # to unpack and configure all packages: # dpkg --install /var/cache/apt/archives/*_amd64.deb : # Should print "amd64": $ dpkg --print-architecture : # Should include "i386": $ dpkg --print-foreign-architectures # apt update # apt upgrade # apt full-upgrade
If you get errors about a missing libsystemd0 and can no longer run apt, you can still directly download libsystemd0, put the .deb in /var/cache/apt/archives/, and rerun dpkg --install /var/cache/apt/archives/*_amd64.deb. If apt upgrade still doesn't work, try apt install -f (might work without needing to type the 'Yes, do as I say').
Crossgrade all other architecture-dependent packages
If you got this far you are now effectively mostly running the target architecture, e.g. amd64, but with mostly from architecture, e.g. i386, packages. However one may still be running kernel of from rather than target architecture, e.g. if target is architecture subtype of from architecture, rather than vice versa.
Well note that there's more than one way to proceed, and more than one set of examples on how to proceed in this section. It's suggested to carefully read them all through, from here up to the start of the optional recommended/suggested cleanup section, before deciding how to proceed.
In brief, we thus far have:
for apt-mark auto/manual there's a method with side effects (package installation), and there's another method which only touches the mark status and does nothing else.
Then for most of the crossgrading, notably getting the desired target architecture packages installed, we have two sets of examples.
One shows a safer slower iterative approach, but is likely somewhat more challenging to carry out.
Another uses a faster simpler more brute force approach, but is more likely to cause breakage.
Preserving the "auto" mark, etc.
There's more than one possible way to approach this.
In any case, saving apt-mark state is
recommended, but not required and preserving/restoring is optional.
Suggested to read all the approaches, then decide which one(s), if any or more than one, one wishes to apply.
Here's one approach (and continue to read following it for additional/alternative way(s)):
Note that this approach takes mark status from currently still installed from architecture, e.g. i386, packages that are still installed (at least some will have already been removed by this point in the process), and uses that to (attempt to) ensure that corresponding target architecture packages are installed, then set to auto those that were set to auto on their from architecture packages we pulled status from that were set to auto.
Also, even though this example approach will almost certainly install packages, it still remains optional, as subsequent portions of this Continue without using crossgrader section will still cover installing those packages.
Manually upgrading packages will clear the "automatically installed" flag for those packages that were automatically installed on i386.
If it works for you, one way to do the swap that preserves all of dpkg and apt state regarding manual vs automatic package selection is:
: # Get auto-installed packages:
$ apt-mark showauto | sed -n -e 's/:i386$//p' > auto-package-list
: # Reinstall everything:
# apt install $(dpkg -l | awk '$1 ~ /^.i/ && $2 ~ /:i386$/ { sub(":i386", ""); print $2 }')
: # Or for bookworm:
# apt install --allow-remove-essential $(dpkg -l | awk '$1 ~ /^.i/ && $2 ~ /:i386$/ { sub(":i386", ""); print $2; print $2 ":i386-" }')
: # Reset the "auto" mark:
# xargs apt-mark auto < auto-package-listYou may have to type in 'Yes, do as I say' to get apt to do this, so make sure each package in the warning is actually going to get installed with the new architecture.
This method also has the advantage that if you have packages installed that are only available on i386, they will be kept installed rather than throwing an error about unavailable packages.
Notes 2020-10: I needed to edit the list to remove the pae kernel references and then use that edited list from a file for apt install. You will experience various errors regardless. I needed to for example manually dpkg -i bash and dash, symlink /bin/sh to the existing one a couple of times, and try again and again. Expect needing to do a lot of apt install -f, dpkg --configure -a, and manual dpkg -i from /var/cache/apt/archives/ and apt autoremove --purge (to remove replaced :i386 binaries). However using above and these notes I ended up with a functional system and there were big portions that just ran without interruptions.
At least another approach that can be used (not mutually exclusive of the above approach):
If one has earlier (or still does so now - though won't be quite as complete in that case) saved the state as recommended in the section:
Preparation: Recommended: specific files/state backup: Recommended: also save the apt-mark auto/manual status information:
then one can use that to restore relevant corresponding state. In that case, however, we don't restore that state at this point in time, but do so towards the very end (this section includes reminder about that at appropriate point in sequence). Notably as that procedure does no installation of packages, but only sets auto/manual state. If you want to presently peek ahead at that restore procedure, it's here: Optional: apt-mark status restore: within section Third (optional) stage and additional recommended/suggested cleanup within section Continue via crossgrader (highly advised)
crossgrade of all remaining from architecture packages
Multiple alternative approaches/examples shown below.
Our first below shows a safer slower iterative approach, but is likely somewhat more challenging to carry out.
The one following that uses a faster simpler more brute force approach, but is more likely to cause breakage.
This approach/example shows a safer slower iterative approach, but is likely somewhat more challenging to carry out.
And, after some iterations of simulation runs, this looks highly promising
(note that
<(list) and >(list) process substitution syntax is in bash and may not be present in other shells):
$ apt -s install $(comm -23 <(dpkg -l | awk '{if($1 ~ /^ii$/ && $4 ~ /^i386$/ && $2 ~ /:i386$/)print $2;}' | sed -e 's/:i386$//' | sort -u) <(dpkg -l | awk '{if($1 ~ /^ii$/ && $4 ~ /^amd64$/ && $2 ~ /:amd64$/)print $2;}' | sed -e 's/:amd64$//' | sort -u) | sed -e '/^linux-image-.*686/d;s/.*/& &:i386-/') binutils-x86-64-linux-gnu
That essentially takes list of all the installed i386 architecture packages that are multi-arch, and if they don't have a corresponding amd64 installed, would install the amd64 and remove the i368, excepting we filter out kernels (already covered that), and one dependency has different name of package under amd64 architecture, so we explicitly add that. First we stage the files, in case things go sideways:
# apt -d install $(comm -23 <(dpkg -l | awk '{if($1 ~ /^ii$/ && $4 ~ /^i386$/ && $2 ~ /:i386$/)print $2;}' | sed -e 's/:i386$//' | sort -u) <(dpkg -l | awk '{if($1 ~ /^ii$/ && $4 ~ /^amd64$/ && $2 ~ /:amd64$/)print $2;}' | sed -e 's/:amd64$//' | sort -u) | sed -e '/^linux-image-.*686/d;s/.*/& &:i386-/') binutils-x86-64-linux-gnu
That looks good, so:
# apt install $(comm -23 <(dpkg -l | awk '{if($1 ~ /^ii$/ && $4 ~ /^i386$/ && $2 ~ /:i386$/)print $2;}' | sed -e 's/:i386$//' | sort -u) <(dpkg -l | awk '{if($1 ~ /^ii$/ && $4 ~ /^amd64$/ && $2 ~ /:amd64$/)print $2;}' | sed -e 's/:amd64$//' | sort -u) | sed -e '/^linux-image-.*686/d;s/.*/& &:i386-/') binutils-x86-64-linux-gnu
But apt doesn't want to do that because critical system packages. Let's try, but filtering out and the dependencies thereof that apt complains about:
# apt install $(comm -23 <(dpkg -l | awk '{if($1 ~ /^ii$/ && $4 ~ /^i386$/ && $2 ~ /:i386$/)print $2;}' | sed -e 's/:i386$//' | sort -u) <(dpkg -l | awk '{if($1 ~ /^ii$/ && $4 ~ /^amd64$/ && $2 ~ /:amd64$/)print $2;}' | sed -e 's/:amd64$//' | sort -u) | grep -v -e '^(base-files|base-passwd|bash|bsdutils|coreutils|dash|debianutils|diffutils|e2fsprogs|findutils|grep|gzip|hostname|init|libattr1|libaudit1|libblkid1|libc-bin|libcap-ng0|libcom-err2|libcrypt1|libdebconfclient0|libext2fs2|libmount1|libpam-modules|libpam0g|libsmartcols1|libss2|libtinfo6|libuuid1|login|logsave|ncurses-bin|perl-base|sed|systemd-sysv|sysvinit-utils|util-linux-extra|util-linux)$' | sed -e '/^linux-image-.*686/d;s/.*/& &:i386-/') binutils-x86-64-linux-gnu
Still same issue. Let's try with dpkg, libgpg-error-l10n_1.46-1_all.deb is file with newest ctime that was used to cover dpkg, tar, apt, and dependencies thereof, so the newer ctimes are for everything that remains after that (and before that we had started with an
# apt clean
)
$ dpkg --dry-run -i $(find *.deb -type f -prune -cnewer libgpg-error-l10n_1.46-1_all.deb -print)
Above gives us Pre-Depends: issues, so, based on that:
$ dpkg --dry-run -i libattr1_* libaudit1_* libblkid1_* libcrypt1_* libtinfo6_* perl-base_*
Above gives us Pre-Depends: issues, so, based on that:
$ dpkg --dry-run -i libcrypt1_*
That looks good, so:
# dpkg -i libcrypt1_*
That looks good, so:
$ dpkg --dry-run -i libattr1_* libaudit1_* libblkid1_* libcrypt1_* libtinfo6_* perl-base_*
That looks good, so:
# dpkg -i libattr1_* libaudit1_* libblkid1_* libcrypt1_* libtinfo6_* perl-base_*
Above gives us Pre-Depends: issues, so, based on that:
$ dpkg --dry-run -i libcap-ng0_*
That looks good, so:
# dpkg -i libcap-ng0_*
That looks good, so:
# dpkg -i libattr1_* libaudit1_* libblkid1_* libcrypt1_* libtinfo6_* perl-base_*
That looks good, so:
$ apt -s install $(comm -23 <(dpkg -l | awk '{if($1 ~ /^ii$/ && $4 ~ /^i386$/ && $2 ~ /:i386$/)print $2;}' | sed -e 's/:i386$//' | sort -u) <(dpkg -l | awk '{if($1 ~ /^ii$/ && $4 ~ /^amd64$/ && $2 ~ /:amd64$/)print $2;}' | sed -e 's/:amd64$//' | sort -u) | sed -e '/^linux-image-.*686/d;s/.*/& &:i386-/') binutils-x86-64-linux-gnu
That looks good, so:
# apt install $(comm -23 <(dpkg -l | awk '{if($1 ~ /^ii$/ && $4 ~ /^i386$/ && $2 ~ /:i386$/)print $2;}' | sed -e 's/:i386$//' | sort -u) <(dpkg -l | awk '{if($1 ~ /^ii$/ && $4 ~ /^amd64$/ && $2 ~ /:amd64$/)print $2;}' | sed -e 's/:amd64$//' | sort -u) | sed -e '/^linux-image-.*686/d;s/.*/& &:i386-/') binutils-x86-64-linux-gnu
But apt doesn't want to do that because critical system packages. Let's try dpkg:
$ dpkg --dry-run -i $(find *.deb -type f -prune -cnewer libgpg-error-l10n_1.46-1_all.deb -print | grep -E -v '^(libattr1|libaudit1|libblkid1|libcap-ng0|libcrypt1|libcrypt1|libtinfo6|perl-base)$')
Above gives us Pre-Depends: issues, so, based on that:
$ dpkg --dry-run -i libcom-err2_* libdb5.3_* libmount1* libpam0g*
That looks good, so:
# dpkg -i libcom-err2_* libdb5.3_* libmount1_* libpam0g_*
That looks good, so:
$ dpkg --dry-run -i $(find *.deb -type f -prune -cnewer libgpg-error-l10n_1.46-1_all.deb -print | grep -E -v '^(libattr1|libaudit1|libblkid1|libcap-ng0|libcom-err2|libcrypt1|libdb5.3|libmount1|libpam0g|libtinfo6|perl-base)$')
Above gives us Pre-Depends: issues, so, based on that:
$ dpkg --dry-run -i libext2fs2_* libpam-modules_* libsmartcols1_* libssl3_*
That looks good, so:
# dpkg -i libext2fs2_* libpam-modules_* libsmartcols1_* libssl3_*
That looks good, so:
$ dpkg --dry-run -i $(find *.deb -type f -prune -cnewer libgpg-error-l10n_1.46-1_all.deb -print | grep -E -v '^(libattr1|libaudit1|libblkid1|libcap-ng0|libcom-err2|libcrypt1|libdb5.3|libext2fs2|libmount1|libpam-modules|libpam0g|libsmartcols1|libssl3|libtinfo6|perl-base)$')
Above gives us Pre-Depends: issues, so, based on that:
$ dpkg --dry-run -i libss2_* libuuid1_*
That looks good, so:
# dpkg -i libss2_* libuuid1_*
That looks good, so:
$ dpkg --dry-run -i $(find *.deb -type f -prune -cnewer libgpg-error-l10n_1.46-1_all.deb -print | grep -E -v '^(libattr1|libaudit1|libblkid1|libcap-ng0|libcom-err2|libcrypt1|libdb5.3|libext2fs2|libmount1|libpam-modules|libpam0g|libsmartcols1|libss2|libssl3|libtinfo6|libuuid1|perl-base)$')
That looks good, so:
# dpkg -i $(find *.deb -type f -prune -cnewer libgpg-error-l10n_1.46-1_all.deb -print | grep -E -v '^(libattr1|libaudit1|libblkid1|libcap-ng0|libcom-err2|libcrypt1|libdb5.3|libext2fs2|libmount1|libpam-modules|libpam0g|libsmartcols1|libss2|libssl3|libtinfo6|libuuid1|perl-base)$')
That looks good. And checking, e.g.:
$ comm -23 <(dpkg -l | awk '{if($1 ~ /^ii$/ && $4 ~ /^i386$/)print $2;}' | sed -e 's/:i386$//' | sort -u) <(dpkg -l | {{{awk '{if($1 ~ /^ii$/ && $4 ~ /^amd64$/)print $2;}' | sed -e 's/:amd64$//' | sort -u)
linux-image-6.1.0-35-686-pae
linux-image-6.1.0-37-686-pae
linux-image-686-pae
$
all our from architecture (i386) packages now have target architecture (amd64) packages of same name, excepting where the names differ (in our example case kernel package(s) and one other package). Regardless, in all cases, we've got our corresponding target architecture packages installed at this point, whether names are the same (almost all cases) or not (small number of exceptions).
This approach/example uses a faster simpler more brute force approach, but is more likely to cause breakage.
Another more brutal way to do the swap is:
# dpkg --get-selections | sed -ne 's/:i386\(\t*install$\)/:amd64\1/p' | dpkg --set-selections # apt -f install
You may have to type in 'Yes, do as I say' to get apt to do this.
optional recommended/suggested cleanup
Well note that there's again more than one way to proceed, and more than one set of examples on how to proceed in this section. It's suggested to carefully read them all through, before deciding how to proceed. In brief, we thus far have:
For (optional) removing all from (e.g. i386) architecture packages, we have two sets of examples.
One shows a safer slower iterative approach, but is likely somewhat more challenging to carry out.
Another uses a faster simpler more brute force approach, but is more likely to cause breakage.
This approach/example shows a safer slower iterative approach, but is likely somewhat more challenging to carry out.
If under kernel, etc. architecture Scenario A and already running target architecture kernel, let's purge our from (e.g. i386) architecture kernel(s) (which we may not be able to successfully boot now anyway). However, if we're under Scenario B or C, we would presently skip these following kernel related remove/purge steps:
$ apt -s purge linux-image-6.1.0-35-686-pae:i386 linux-image-6.1.0-37-686-pae:i386 linux-image-686-pae:i386
apt doesn't want to do that due to missing dependency state of some i386 architecture packages, so let's use dpkg again:
$ dpkg --dry-run -P linux-image-6.1.0-35-686-pae:i386 linux-image-6.1.0-37-686-pae:i386 linux-image-686-pae:i386
That looks good, so:
# dpkg -P linux-image-6.1.0-35-686-pae:i386 linux-image-6.1.0-37-686-pae:i386 linux-image-686-pae:i386
That looks good, so:
$ comm -23 <(dpkg -l | awk '{if($1 ~ /^ii$/ && $4 ~ /^i386$/ && $2 ~ /:i386$/)print $2;}' | sed -e 's/:i386$//' | sort -u) <(dpkg -l | awk '{if($1 ~ /^ii$/ && $4 ~ /^amd64$/ && $2 ~ /:amd64$/)print $2;}' | sed -e 's/:amd64$//' | sort -u)
That gives us exactly no output, so that means we have no i386 multi-arch packages installed that don't have matching amd64 packages installed. With a bit more careful cross-checking, we not only confirm that, but also confirm there are no i386 architecture packages at all that don't have a corresponding amd64 package that's installed (but the reverse isn't necessarily the case, due to conflicts). So, now we're ready to start getting rid of i386 architecture packages, but to play it safe(er), if under kernel, etc. architecture Scenario A (otherwise not), let's first reboot, so then should no longer be using any i386 binaries - most notably from removed packages (unlinked open files).
After rebooting (likewise if not under Scenario A, may need to further filter some of the from architecture packages to otherwise be removed or purged at this time):
$ dpkg --dry-run -P $(dpkg -l | awk '{if($1 ~ /^ii$/ && $4 ~ /^i386$/)print $2;}' | sed -e '/:i386$/!s/$/:i386/')
Above gives us some dependency issues, so, based on that:
$ dpkg --dry-run -P libcrypt1:i386 libgcc-s1:i386
That complains about protected packages, so, based on that:
$ dpkg --dry-run --force-all -P $(dpkg -l | awk '{if($1 ~ /^ii$/ && $4 ~ /^i386$/)print $2;}' | sed -e '/:i386$/!s/$/:i386/')
That looks reasonable, so:
# dpkg --force-all -P $(dpkg -l | awk '{if($1 ~ /^ii$/ && $4 ~ /^i386$/)print $2;}' | sed -e '/:i386$/!s/$/:i386/')
That looks pretty good, but checking we find:
$ dpkg -l | awk '/^Desired/,/^\+\+\+/; /^.. / {if($4 ~ /^i386$/)print;}'
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-============================-==============================-============-========================================================================
pi libcrypt1:i386 1:4.4.33-2 i386 libcrypt shared library
pi libgcc-s1:i386 12.2.0-14+deb12u1 i386 GCC support library
$
So:
$ dpkg --dry-run --force-all -P libcrypt1:i386 libgcc-s1:i386
That looks good, so:
# dpkg --force-all -P libcrypt1:i386 libgcc-s1:i386
And after that and checking, we confirm we no longer have any from (e.g. i386 in this case) architecture packages still installed.
This approach/example uses a faster simpler more brute force approach, but is more likely to cause breakage.
Once the swap is complete, you can remove all the redundant libraries and drop the old architecture with
# apt purge $(dpkg -l | sed -ne 's/^.i \([^ ]*:i386\).*/\1/p') # dpkg --remove-architecture i386 # apt update
Optional: one may restore apt-mark auto/manual status if desired and that data was (recommended) saved earlier. Note also this does not conflict with other procedures that may have set apt-mark auto/manual status, so it can be (additionally) run, if desired. That restore procedure is here: Optional: apt-mark status restore: within section Third (optional) stage and additional recommended/suggested cleanup within section Continue via crossgrader (highly advised)
Optional, but suggested to at least review:
At this point, all of the steps/procedures (with some noted exceptions) in the section
Third (optional) stage and additional recommended/suggested cleanup can be applied. Except for the exceptions noted, one can apply all, any, or none of what's in that section.
If one chooses to apply any of them, these are the
exceptions from that section to skip/ignore/not apply:
- do not make any use of the crossgrader package commands (crossgrader and crossgrade-package-check)
- do not attempt to remove or purge the crossgrader package (which presumably if you're following procedure here you don't have installed anyway).
That's it. Other than those exceptions, one can optionally apply nothing, anything, and/or everything in that section.
If you've successfully made it to here in the procedures, congratulations! You've successfully crossgraded the system(s)! In any case, still quite advised to be sure to review Caveats and Known Problems for known issues that may be present or show up, and in many cases with the information how to check and fix.
Caveats and Known Problems
crossgrader bugs/issues
Not intended to be a comprehensive list, but these are the more likely of relevance one may encounter. One may want to review bugs for a more complete list of the known and reported bugs, etc.
crossgrader use breaks initramfs-tools-core
At least certain version(s) of crossgrader break(s) initramfs-tools-core after use of crossgrader, most notably when crossgrader is subsequently removed or purged. See information further above for more details and work-arounds, relevant context, etc.
crossgrader minor third stage reporting bug
For at least certain version(s) of crossgrader (including 0.0.3+nmu3, likely also earlier but subsequently fixed), third stage may improperly complain when it has nothing left to do, e.g.:
# crossgrader --third-stage i386 amd64
may complain, throwing an error, including e.g.:
dpkg: error: --purge needs at least one package name argument
if there are no remaining packages of the migrated from architecture. That can be safely ignored. And presumably fixed in newer versions: merged fix
Caution with systemd
systemd may not like being cross-graded, possibly it is safer to cross-grade it from a liveCD. Make sure to cross-grade udev at the same time, otherwise various units will fail.
APT dependency resolver wants to revert apt itself
If the system had packages that depend on apt like apt-utils, it's possible to run into a situation where apt -f install wants to revert apt itself to i386. Aborting and doing another operation apt autoremove will illustrate the reason better:
The following packages have unmet dependencies: apt-utils:i386 : Depends: apt:i386 (= 1.4.8) but it is not installed
In such a case, the solution is to temporarily remove apt-utils:i386 from the system, and install apt-utils afterwards. Note: this new apt-utils will be amd64, but once you switch apt to amd64, using the :amd64 suffix will not work.
Apt dependency resolver generates broken solutions
It might happen that apt's resolver emits an unworkable solution:
E: Error, pkgProblemResolver::Resolve generated breaks, this may be caused by held packages. E: Unable to correct dependencies
In this case you can inspect what packages are marked as Broken and decide what to do:
# apt -o Debug::pkgProblemResolver=1 -f install
KDE
The KDE desktop environment creates the file ~/.config/Trolltech.conf, which contains locations of shared libraries and, more problematic, their architecture. This causes panel widgets to crash. The file can apparently be safely removed or renamed to fix these problems.
iamerican, ibritish (and possibly others/similar)
Similar to KDE, some package(s) (e.g. iamerican on at least Debian 7.5 and iamerican and ibritish at least through Debian 12.11) may have saved caches/hashes that need updating. E.g.:
echo cat | spell
may result in:
/usr/bin/ispell: Illegal format hash table
corrected with e.g.:
# dpkg-reconfigure iamerican ibritish
which updates /var/lib/ispell/american.hash and /var/lib/ispell/british.hash
See also
Announce by Guillem Jover, dpkg Maintainer (see "Cross-grading" at the bottom of the message)
Howto amd64 an i386 Debian installation with multiarch by Marc Haber
Crossgrading Debian in 2017 by Simon Richter
Upgrading Debian from 32-bit to 64-bit - AKA crossgrading from i386 to amd64 by anarcat
i386 to amd64 - Debian 7.5 from i386 to amd64, discussion + links to edited script(1) capture, etc., by Michael Paoli
- Articles by Jose M. Calhariz:
Migrate a 32-bit debian installation to 64-bit one (i386 to amd64)
Migrate/Upgrade Debian 7 Wheezy GNU/Linux from 32 bit to 64 bit HowTo
Sample cross-grade script
The script below was written in 2015, and may not have been tested on any supported version of Debian. Highly advised to use crossgrader instead. In any case, with or without crossgrader, do also well see the information on and referenced by this wiki page.
#! /bin/bash
# scary script to crossgrade your debian machine between arches.
# usage crossgrade <final-architecture>
set -e
if [ -z "$1" ]; then
echo "Usage: crossgrade <architecture> (debian architecture to convert to)"
exit 1
fi
#validate arch
if ! TO=$(dpkg-architecture -qDEB_HOST_ARCH -a$1); then
echo "$1 is not a recognized architecture name"
exit 1
fi
FROM=$(dpkg --print-architecture)
echo "Crossgrading from $FROM to $TO"
#check for a compatible kernel
# should check $FROM and $TO harder
# allow for switching kernel over too to minimal one if requested?
case $TO in
amd64)
TO_KERN=amd64
;;
i386)
TO_KERN=amd64
;;
armhf)
TO_KERN=armhf
;;
armel)
TO_KERN=armhf
;;
arm64)
TO_KERN=arm64
;;
mips)
TO_KERN=mips64le
;;
mipsel)
TO_KERN=mips64le
;;
mips64le)
TO_KERN=mips64le
;;
ppc)
TO_KERN=ppc64el
;;
powerpc)
TO_KERN=ppc64el
;;
ppc64el)
TO_KERN=ppc64el
esac
dpkg --add-architecture $TO
# check that dpkg --print-foreign-architectures is $TO
apt update
apt upgrade
# Install a kernel capable to run the new architecture with the old
# architecture in userspace
KERNEL=$(uname -m)
echo "Current kernel arch is $KERNEL"
if [ "$KERNEL" != "$TO_KERN" ]; then
if apt install linux-image-$TO:$TO; then
echo "There should be a reboot here"
exit 1
#reboot
else
echo "kernel updating to linux-image-$TO:$TO failed"
fi
fi
echo Crossgrading dpkg and apt
apt clean
apt --download-only install dpkg:$TO apt:$TO tar:$TO
#check every package to be installed is available in same version for amd64 if installed (multiarch sync is needed)
#for pkg in /var/cache/apt/archives/*_$TO.deb
#do
# file=$(basename $pkg)
# pkgname= ${file%%_.*}
# version= ${file##*._}
# if dpkg -l $($pkgname)
#done
#in practice this needs to run twice (do it more? is there a better way?)
if ! dpkg --install /var/cache/apt/archives/*_$TO.deb; then
dpkg --install /var/cache/apt/archives/*_$TO.deb
fi
test $(dpkg --print-architecture) = $TO
test $(dpkg --print-foreign-architectures | grep $FROM) = $FROM
echo "Yay! dpkg and apt crossgrade completed successfully"
echo "Updating core packages"
apt upgrade
apt full-upgrade
echo "Removing obsolete packages"
apt install aptitude:$TO
aptitude purge '?obsolete'
echo "Mass reinstalling $TO packages -- double check installed packages match warned-about packages"
apt install $(dpkg -l | grep '^.i.*:'"$FROM" | grep ":$FROM" | sed -e "s/:$FROM/:$TO/" | awk '{print $2}')
echo "Removing redundant libraries"
apt purge $(dpkg -l | grep '^.i.*:'"$FROM" | awk '{print $2}')
echo "Removing $FROM"
dpkg --remove-architecture "$FROM"
apt update
CategoryPackageManagement | CategoryMultiarch | CategoryPermalink: mentioned in the Release Notes for trixie
