事实上,只要厂商愿意,操作系统本身都是相对容易做到兼容多架构的。不容易兼容多架构的是应用程序和驱动。
应用程序通常需要用源代码重新编译一下才能支持新架构。当然这个前提是有源代码。
Linux阵营因为被GPL感染的应用会强制开源的原因,大量的应用都有源代码,因此兼容多架构相对容易,哪怕是年久失修的代码,要支持新架构也是完全有可能的。
而Windows阵营的很多应用没有开放源代码,一旦开发商跑路,消失或者倒闭,这个软件可能就无法维护了(除非将代码卖给第三方)。如果你的业务依赖这样的软件,那么你不能换架构甚至也不能随意给操作系统升级。
至于驱动往往是厂商开发,厂商开发驱动的时候支持不同架构才行。如果从底层硬件层面来评价那任何操作系统都不能随意支持多处理器架构。除非自带多架构驱动。这一点恰好也是Linux里边那些开源驱动占了优势。
手机系统由于其驱动闭源,所以其系统的适配与升级都受到驱动的制约,一些老款手机难以升级新系统就与驱动有很大关系。即便操作系统厂商很想升级也要看硬件产商的意愿。
最后,java等基于虚拟机的应用,因为本身就相当于源代码,实质上是到目标机上进行编译,所以自然能够实现跨架构运行。这是另外一回事了。
在你要讨论Linux内核能做什么的时候,你至少要搞清楚“运行时”和“编译时”两个不同概念。一个操作系统内核的代码可以支持很多体系结构和硬件,但是并不是说这些支持都能同时编译并使用。
在Linux内核中,和体系结构相关的代码在arch/目录下:
[xxxx@xxxx linux]$ ls arch/ alpha arc arm arm64 c6x csky h8300 hexagon ia64 Kconfig m68k microblaze mips nds32 nios2 openrisc parisc powerpc riscv s390 sh sparc um x86 xtensa
基本上每一个目录代表一种体系结构,或者可以说代表它支持的一系列CPU,比如 x86 目录就是你日常常用的Intel/amd CPU使用的代码,mips 就是给mips的cpu用的,还有powerpc, s390, sparc,arm, arm64等等(我都附上了相关文档链接),这些都是当前的Linux支持的体系结构。
但是这是静态的代码,不是运行时的。运行时你只能选针对一个体系结构编译、加载、运行,如果你想跑在另一个体系结构上,就要重新针对另一个体系结构重新编译内核。
所以编译内核之前最首要的就是决定你要针对哪个体系结构进行编译,默认会针对你当前所用的CPU所属体系结构进行编译,当然你还可以通过指定ARCH来进行编译交叉,比如要针对arm64进行编译配置,可以使用(当然如果是交叉编译的话你还需要交叉编译的工具链CROSS_COMPILE)
make ARCH=arm64 menuconfig
需要针对powerpc体系结构进行编译的时候可以:
make ARCH=powerpc menuconfig
同时针对不同的体系结构你还可以进一步选择更具体的配置,比如:
比如:
这些都还只是编译前的配置,也就是选择要编译什么,配置之后则进行编译,编译成功后得到特定运行环境的内核(及其驱动),将内核(及其)驱动放在对应的硬件上加载运行即可。
所以返回来看你的问题:
为什么linux可以同时兼容x86和arm?
因为Linux的代码中有针对不同x86和arm体系结构的CPU的代码,可以针对性的编译出运行在x86或arm上的内核(及其驱动)。
一个操作系统不是只能对应特定的硬件系统吗?
一个面向某一体系结构编译出来的内核,只能用于这一特定体系结构,同时所携带的驱动集合不同也将决定其所支持的外设的不同。