The output from uname:

root@debian:~ # uname -a
Linux 5asnb 2.6.32-5-amd64 #1 SMP Mon Jun 13 05:49:32 UTC 2011 x86_64 GNU/Linux

However the /sbin/init executable shows up as 32-bit:

root@debian:~ # file /sbin/init
/sbin/init: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped

Other aspects of the system seem to contradict things as well:

root@debian:~ # echo $HOSTTYPE

root@debian:~ # getconf LONG_BIT

The 64bit kernel can be installed on Debian 32bit. You can see that the amd64 kernel is available for 32bit Debian on it's package page. This can be used as an alternative to using a PAE enabled kernel to support more than 4G of total RAM. Note that 32bit binaries still can not access more than roughly 3G of RAM per process.

| improve this answer | |
  • thx! your answers is as clear as a crystal ball~ :D Never noticed Debian treat kernel package like this way before. – kiiwii Jun 4 '14 at 3:22
  • 1
    That's not true: 32 bit programs can use the whole 4Gio of their virtual address space when running on a 64-bit kernel (unless they are running with the ADDR_LIMIT_3GB personality). – ysdx May 9 '16 at 8:10
  • @ysdx So limiting to 2GB is a Windows specific thing and addresses above 0x80000000 will be allowed in 32-bit userspace? – Paul Stelian Sep 3 '19 at 11:14
  • 1
    @PaulStelian, On 32 bit Windows, you are by default limited to the lowest 2GB of virtual memory for retro-compatibility (I think some programs used to reserve pointers to the highest 2GB of virtual memory for special purpose). You can set the LARGEADDRESSAWARE flag in your executable (docs.microsoft.com/fr-fr/cpp/build/reference/…) to opt-in getting access to the whole 4GB of virtual memory. – ysdx Sep 3 '19 at 16:55

All processors that support the x64 instruction set (also known as x86_64 or amd64) also support the x86 instruction set (also known as i386 or i686, which are strictly speaking specific versions of x86). The same goes for ARM A64 (the new 64-bit instruction set appearing in ARMv8) and A32 (the name for the “classic” 32-bit instruction set), for SPARC64 and SPARC, and I believe for MIPS64 and MIPS. So on all these architecture families, if a processor can run 64-bit code, it can also run 32-bit code.

The Linux kernel supports running 32-bit userland code with a 64-bit kernel (on all the architecture families mentioned above, I think). The kernel must be homogeneous (all 64-bit or all 32-bit), and each process must be homogeneous, but you can have a mixture of 32-bit and 64-bit processes on a 64-bit kernel. The converse is not possible: with a 32-bit kernel, you cannot run 64-bit processes.

This is a design choice in Linux, motivated by the desire to run existing 32-bit binaries on 64-bit installations. Other Unix variants have made different choices: Solaris can run 64-bit programs on a 32-bit kernel as well as the other way round, while OpenBSD cannot run 32-bit programs on a 64-bit kernel.

You can get information about the CPU in /proc/cpuinfo. If your x86 CPU has the lm flag, it's a 64-bit CPU.

By default, uname -m or arch shows the architecture that the kernel was compiled for. Linux can set the “personality” of a process (with the personality) system call. You can run a subprocess in a different personality with the setarch command; setarch i686 someprogram or linux32 someprogram runs the specified program in an environment where uname -m returns i686 while setarch amd64 someprogram or linux64 someprogram runs the specified program in an environment where uname -m returns amd64.

file /sbin/init tells you what architecture the init program is compiled for. Although it's possible to mix 32-bit and 64-bit executables in an installation, usually all the core OS programs are from the same architecture, because it's a lot easier to manage.

$HOSTYPE is a bash variable and tells you what architecture the bash program was compiled for.

getconf LONG_BIT lets you know whether the default C compiler is set up to compile 32-bit or 64-bit programs. A more precise test is to compile a and run a program that prints sizeof(void*) or sizeof(size_t) — calling getconf can only give information about what getconf thinks is the default compiler.

| improve this answer | |
  • 1
    Indeed, does 32 bit Solaris switch to 64 bit mode to switch to 64-bit process and then back? This must have a huge overhead, and just makes no sense, because then the kernel is effectively 64 bit. – Ruslan Jun 4 '14 at 13:20
  • 1
    @Ruslan Why would it have a huge overhead? Switching modes on a context switch doesn't cost much (if anything, I don't know x86 at a low level well enough). The kernel remains 32-bit: 32-bit virtual addresses for kernel mappings, use of 32-bit the instruction set. – Gilles 'SO- stop being evil' Jun 4 '14 at 15:16
  • 1
    The kernel must maintain some 64-bit-specific data structures to support 64 bit apps, at least 64bit-aware page tables. This makes it not really a 32 bit kernel. I've not tried to get really deep into amd64 arch, but I think switching 64 bit support off will have considerable overhead in contrast to using specially designed compatibility mode. – Ruslan Jun 4 '14 at 15:23
  • 1
    @Ruslan Only 64-bit aware page tables and really necessary, and it's a tiny cost. Everything else can be avoided with the right kernel design. I've never dug into the Solaris kernel, I presume they arranged to make it flexible enough (they had prior experience with SPARC64). – Gilles 'SO- stop being evil' Jun 4 '14 at 15:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.