How come a 32 bit kernel can run a 64 bit binary?

2020-05-20 07:45发布

问题:

On my OS X box, the kernel is a 32 bit binary and yet it can run a 64 bit binary. How does this work?

cristi:~ diciu$ file ./a.out
./a.out: Mach-O 64-bit executable x86_64
cristi:~ diciu$ file /mach_kernel
/mach_kernel: Mach-O universal binary with 2 architectures
/mach_kernel (for architecture i386):   Mach-O executable i386
/mach_kernel (for architecture ppc):    Mach-O executable ppc
cristi:~ diciu$ ./a.out
cristi:~ diciu$ echo $?
1

回答1:

The CPU can be switched from 64 bit execution mode to 32 bit when it traps into kernel context, and a 32 bit kernel can still be constructed to understand the structures passed in from 64 bit user-space apps.

The MacOS X kernel does not directly dereference pointers from the user app anyway, as it resides its own separate address space. A user-space pointer in an ioctl call, for example, must first be resolved to its physical address and then a new virtual address created in the kernel address space. It doesn't really matter whether that pointer in the ioctl was 64 bits or 32 bits, the kernel does not dereference it directly in either case.

So mixing a 32 bit kernel and 64 bit binaries can work, and vice-versa. The thing you cannot do is mix 32 bit libraries with a 64 bit application, as pointers passed between them would be truncated. MacOS X supplies more of its frameworks in both 32 and 64 bit versions in each release.



回答2:

It's not the kernel that runs the binary. It's the processor.

The binary does call library functions and those need to be 64bit. And if they need to make a system call, it's their responsibility to cope with the fact that they themselves are 64bit, but the kernel is only 32.

But that's not something you would have to worry about.



回答3:

Note that not all 32-bit kernels are capable of running 64-bit processes. Windows certainly doesn't have this property and I've never seen it done on Linux.



回答4:

The 32 bit kernel that is capable of loading and running 64 bit binaries has to have some 64 bit code to handle memory mapping, program loading and a few other 64 bit issues.

However, the scheduler and many other OS operations aren't required to work in the 64 bit mode in order to deal with other issues - it switches the processor to 32 bit mode and back as needed to handle drivers, tasks, memory allocation and mapping, interrupts, etc.

In fact, most of the things that the OS does wouldn't necessarily perform any faster running at 64 bits - the OS is not a heavy data processor, and those portions that are (streams, disk I/O, etc) are likely converted to 64 bit (plugins to the OS anyway).

But the bare kernel itself probably won't task switch any faster, etc, if it were 64 bit.

This is especially the case when most people are still running 32 bit apps, so the mode switching isn't always needed, even though that's a low overhead operation, it does take some time.

-Adam



回答5:

An ELF32 file can contain 64bit instructions and run in 64 bit mode. Only thing it is having is that organization of header and symbols are in 32bit format. Symbols table offsets are 32 bits. Symbol table entries are 32 bit wide etc. A file which contain both 64 bit code and 32 bit code can expose itself as 32 bit ELF file wheres it uses 64 bit registors for its internal calculations. mach_kernel is one such executable. Advantage it get is that 32 bit driver ELFs can linked to it. If it take care of passing pointers which are located below 4GBs to other linked ELF binaries it will work fine.



回答6:

For the kernel to be 64-bit would only bring the effective advantage that kernel extensions (i.e., typically drivers) could be 64-bit. In fact, you'd need to have either all 64-bit kernel extensions, or (as is the case now) all 32-bit ones; they need to be native to the architecture of the running kernel.