8

I'm curious. Is it possible to install a 64 bit program on a 32 bit OS with a 64 bit processor?

I'm running Linux on a raspberry pi 3 and I try to install a newer version of MongoDB:

armv7l GNU/Linux
PRETTY_NAME="Raspbian GNU/Linux 9 (stretch)"
NAME="Raspbian GNU/Linux"
VERSION_ID="9"
VERSION="9 (stretch)"
ID=raspbian
ID_LIKE=debian
1

5 Answers 5

21

Is it possible to install a 64 bit program on a 32 bit OS with a 64 bit processor?

In principle yes, but the processor and the OS have to support it.

On ARMv8, a 32-bit (Aarch32) kernel cannot run 64-bit (Aarch64) processes. This is a limitation of the processor.

There are other processors that don't have this limitation, for example it is possible to run x86_64 processes on top of an x86_32 kernel on an x86_64 processor, but few kernels support it, presumably because it's of limited utility (mostly, you save a bit of RAM in the kernel by making it 32-bit). Linux doesn't support it, but Solaris does.

You can keep your existing 32-bit OS if you run a 64-bit kernel. An Aarch64 Linux kernel can run Aarch32 processes. Raspbian doesn't support this out of the box, so you'd need to maintain both a 32-bit OS and a 64-bit OS. You can use either one as the main OS (i.e. the one that runs init and system services) and the other to run a specific program using chroot. See How do I run 32-bit programs on a 64-bit Debian/Ubuntu? for a practical approach.

Note that you will need to install all the libraries that the 64-bit program requires. Any given process must be either wholly 32-bit or wholly 64-bit, so you can't use a 32-bit library in a 64-bit executable.

Unless you have strong reasons to keep a 32-bit system, if you need to run a 64-bit executable, it would be easier to install a 64-bit system.

Note that the only thing that 64-bit programs can do but 32-bit programs can't is address more than about 3GB of virtual memory, which is of limited utility on a system with 1GB of RAM. You may get performance benefits from the extra, larger registers, but you'll also lose performance from the extra memory accesses.

13
  • 3
    @Wildcard In a nutshell, at any given time, either the processor is in 32-bit mode (“Aarch32 execution state”) and expecting Aarch32 instructions, or in 64-bit mode expecting Aarch64 instructions. The only way to switch modes is to switch between process and kernel (or kernel and hypervisor, or hypervisor and monitor). Switching to a lower-privilege mode can't switch from 32-bit to 64-bit, and switching to a higher-privilege mode always restores the previous mode. So it's impossible to arrange to have a 32-bit code running at a higher privilege than 64-bit code. Dec 11, 2017 at 20:32
  • 2
    @Wildcard (cont.) Presumably the reason for this restriction is that there's quite a lot of Aarch64-specific processor state and that Aarch32 code can't access. For example an Aarch32 kernel would be unable to save the registers of an Aarch64 process. Dec 11, 2017 at 20:34
  • 2
    @crellee, Gilles: You don't need to look at exotic OSes to find examples of 32-bit kernels with 64-bit userlands. The extremely popular Mac OS X 10.4 "Tiger", 10.5 "Leopard" and 10.6 "Snow Leopard" kernels shipped in the K32 configuration for almost all Macs, save for a few server machines that were allowed to boot Snow Leopard's K64, but all of them were capable of running 64-bit userland processes (with progressively fewer restrictions). Dec 12, 2017 at 0:36
  • 3
    @Serge: What you describe is true for 286 -> 386: you can use 32-bit operand size in 16-bit real mode with prefixes, where the default operand size is 16. But Intel didn't even develop x86-64; that was AMD (which is why it's still sometimes called AMD64). And no, you can't use 64-bit operand-size in 32-bit mode, at all. REX prefixes repurpose the one-byte inc/dec register opcodes (0x40 .. 0x4F). In long mode (64-bit mode), the default operand size is 32, but the default address size is 64. Dec 12, 2017 at 7:10
  • 2
    @Wildcard: IDK if compat-mode kernel / long-mode userspace was a design consideration at all. To save integer register state for context switches, Solaris (and OS X) must still be in long mode to access r8-r15, and the upper halves of rax-rsi. IDK if xsave / xrstor in compat mode can save the full vector state, either. So it's certainly not well supported or explicitly catered for. Probably the kernel entry points run in 64-bit (long) mode, and switch to 32-bit (compat) mode before jumping to the rest of the kernel. (x86 mode switch just takes a far jmp and doesn't affect regs.) Dec 12, 2017 at 7:14
5

On some architectures, yes. But not on ARM or x86.

You could use QEMU to emulate a 64-bit system, but you don't want to.

4
  • Would it be a disaster to use an emulator like QEMU to install and run a mongo database?
    – crellee
    Dec 11, 2017 at 15:43
  • It would be very, very slow. And not worth it, since the RPi3 only has 1GB of RAM. Consider building a 32-bit package instead. Dec 11, 2017 at 15:44
  • 3
    You can run a 64-bit program on top of a 32-bit kernel on x86 if the kernel supports it. Linux doesn't, but Solaris does. On arm it isn't possible. Dec 11, 2017 at 17:49
  • @IgnacioVazquez-Abrams Try this. It is slow, but not catastrophically. The main reason is that qemu does cpu emulation only in the user space, the kernel calls (i.e. io waiting times) remain the same. On home systems, I like to use arm or mips binaries for some tools, just for fun :-) Or, sometimes, if there is not a very big cpu load, some security-critical, but not cpu-intensive tools could use some exotic architecture, to decrease the probability of buffer overrun attacks.
    – peterh
    Dec 12, 2017 at 7:01
4

Upgrade only your kernel to a 64-bit one, so you will be able to run 64-bit binaries. Essentially, it will run your whole distribution in 32-bit compat mode, and your only 64-bit mongodb will be its normal mode.

But it doesn't deserve its price. Better to switch your mongodb to 32 bit. However, in this case there is a limitation, that your database cannot be bigger as 2GB, as it directly maps the whole thingy in virtual memory. If your db is bigger, only the kernel upgrade remains. (Thanks @duskwuff the extension!)

Btw, if your db doesn't want a very big load, or you can use some caching solution before it (for example: another, but 32bit mongo), then a cpu emulation could work. For that, start a googling for "qemu qemu-system-x86_64". Although such a solution would have likely an infeasible work need and it could be considered weird in productive environment.

In your place, I would use 32 bit mongo if it is for my db enough, or a 64 bit kernel if it is not.

11
  • Makes sense, but how would you switch your mongodb to 32bit?
    – crellee
    Dec 11, 2017 at 19:36
  • @crellee apt-get install mongodb:i386 or some similar?
    – peterh
    Dec 11, 2017 at 19:37
  • that will return a 'Unable to locate package mongodb:i386' error
    – crellee
    Dec 11, 2017 at 20:34
  • 1
    Running a 32-bit MongoDB is a bad idea. The database is memory-mapped, so running it on a 32-bit system limits you to <2GB of data.
    – user130738
    Dec 11, 2017 at 20:55
  • Yes, and you are limited to version: 2.4.14, which has a lot of limitations.
    – crellee
    Dec 11, 2017 at 20:59
3

I would say it's not impossible but really hard to manage. Since a so 32bit OS is usually packaged with (and accepts) 32bits only binaries and libraries, you'd need to heavily tweak the system to make it work with 64bits ones.

The main problem you'd be facing with a RPI3 is the lack of 64bits kernel (at least with raspbian).

Long story short : use 32bits binaries and you'll be fine.

EDIT :

If you want to use a 64bits kernel, you'll need to install a distro supporting the ARM64 architecture. You should take a look at ArchLinux ARM (here), but it's not fully supported.

The information you're looking for is at the bottom of the installation tab.

You also could take a look at an official debian port , however there's still big issues with the RPI3 port, so it's up to you to decide if it's worth the trouble

10
  • The problem is that the CPU is started (by the kernel) in 32-bit mode, so it looks like an old 32-bit machine. 64-bit registers and instructions are not available. Dec 11, 2017 at 15:31
  • 1
    Right, which is why you’d need a 64-bit kernel (which Thomas mentioned). Dec 11, 2017 at 15:32
  • Thanks for the nice explanation. So the solution for me would be to install another OS on my RPI3?
    – crellee
    Dec 11, 2017 at 15:38
  • I just updated my answer.
    – user264413
    Dec 11, 2017 at 15:47
  • @Thomas, some distros do support combined 32-/64-bit operation, starting with the 32-bit variant. Debian is one example, at least on x86: you can install the i386 variant, and that includes a 64-bit kernel, which allows 64-bit libraries and binaries to be installed too. The ARM support in Debian doesn’t allow this on ARM systems though (but you can install combined arm64 and armhf, if you start with arm64). Dec 11, 2017 at 15:59
1

I've used a 64bit kernel with a 32bit system for quite a while (that is the minimum prerequisite for running 64bit executables natively, plus all required 64bit libraries). I would not recommend it. What finally made me upgrade to a 64bit system wholesale was the realization that ALSA headers, particularly with regard to Midi ioctl calls, were not size agnostic, meaning that stuff compiled in 32bit mode would not interoperate well with the 64bit kernel.

Of course this can be considered a bug worth fixing, but the pace of ALSA development is all but frozen and I could not wait for a few years for mixed platform support to get fixed (and in a non-binary compatible way for non-mixed executables) when the interest in mixed platforms is dwindling fast anyway.

For some applications stuff works in mixed mode (surprisingly much actually), but if you are doing more than the basic share of interfacing to the kernel, even via external libraries, it's just overoptimistic.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .