Odi's astoundingly incomplete notes

New entries | Code

Migration from x86 to x86_64

If you happen to run your system on x86 and would like to switch to x86_64 (amd64) you are lucky when running Gentoo. With Gentoo this little circus trick is not very hard to to. The best thing is, while you do this you can continue working in your old environment. So downtime is negligible.

x86_64 boots x86

As you know an x86_64 kernel has an option to execute 32-bit programs:
Executable file formats > IA32 Emulation (IA32_EMULATION in .config)
It's very common to enable this option. The interesting part is: There is no reason why such a kernel shouldn't execute 32bit programs ONLY. That means such a kernel will happily boot and run any ordinary x86 userland!

So why not compile ourselves an x86_64 kernel on our x86 system. Unfortunately our gcc compiler can not produce x86_64 binaries. Only x86 code. So we need to cross-compile.


Fortunately this is no rocket science, and a fairly common thing these days. In our case, all it takes is typing in two commands and waiting a bit:
emerge -av crossdev
crossdev -S -s1 --target x86_64-pc-linux-gnu
This installs the crossdev package and creates a minimal toolchain to cross-compile the kernel.

Configuring the x86_64 kernel

Make a copy of your existing kernel tree (or emerge gentoo-sources) into /usr/src/amd64:
cd /usr/src
cp -ra linux amd64
# clean up
cd amd64
make mrproper
# copy over the config
cp ../linux/.config .
# alternatively obtain it from the running kernel
cp /proc/config.gz .
gunzip config.gz
mv config .config
Now we are ready to configure our kernel. This is quite easy as the options for x86_64 are not much different. Just answer all the questions that the script asks you. The makefile will use our existing config as a template, so you will end up with basically the same kernel that you are already running. All we have to do is tell make that we want to configure for a different architecture:
make ARCH="x86_64" oldconfig
# now compile (mind the trailing dash after gnu)
make ARCH="x86_64" CROSS_COMPILE="x86_64-pc-linux-gnu-"
make ARCH="x86_64" CROSS_COMPILE="x86_64-pc-linux-gnu-" install
Add a new entry in your boot loader and reboot.

Installing the new system

Your system should come up like before. Only that you are now running a full x86_64 kernel! This enables you to execute 64-bit binaries. You can install an amd64-Gentoo into a subdirectory (chroot) as if it was a new system. Just be careful not to accidentially change files outside of this subdirectory! When done you can do the switch and stuff your existing root into some subdirectory, then move your new Gentoo in place.

After unpacking the stage3 tarball, you must carefully merge files and directories from /etc and /var to the new root. Take special care of the HOST variable in /etc/make.conf! You should copy over everything from /usr/local and check /opt. But keep /root and /home (you can just leave them in place them when doing the switch). You should NOT copy over /var/db/pkg, /var/cache, /var/lib/portage and /var/cache.

Then mount proc and dev, chroot and compile away. You probably want to emerge all packages in your original /var/lib/portage/world file.

Before you reboot, reinstall grub!

posted on 2009-10-18 14:45 UTC in Code | 5 comments | permalink
And now gettimeofday() no longer rolls in the year 2038. Yay!

In my mind this is the single most important reason to upgrade to x86_64.

That's why:
typedef long __kernel_time_t;
x86: sizeof(long) = 4
x86_64: sizeof(long) = 8
> In my mind this [linux x86 Year 2038 bug] is the single most important reason to upgrade to x86_64.

Yeah, start upgrading in 2036, to be on the safe side ... ;-)
I followed instructions successfully but...when I reboot, it stats to boot on the x86_64 kernel but it stops during boot process (after USB detection). If I wait enough longer, I got a message saying that task has not answered during at least 120 seconds...

any idea ?

...I answer to myself... you have to disable the Enable loadable module support option to compile all modules internaly...and you have to enable IA32 emulation support... and it works ! ;-)
Thanks for the instructions. I used them and they worked very well.

Thanks again