I'm studying computer architecture and I don't understand what really makes a software for one machine "compatible" with another machine. Let's take for example two machine like Mac Os and Windows that use the same intel cpu. Now, if the opcodes are the same how is it possible that their software are incompatible with each other ?
1 ) Can someone give an outline of what the compatibility word involves ?
2 ) What are the elements that make two machines compatible with each other other than the opcodes of the cpu ?
CodePudding user response:
Besides the other hardware components and as already pointed out, the software itself is a huge source of compatibility issues.
This is nothing new, you cannot always open a proprietary file format with a different application.
The format of the Linux executables is ELF, that of Windows is PE and macOS uses mach-o.
Read the linked pages and see how much the formats share and differ.
However, nothing stops an OS from supporting multiple executable formats (Linux actually does and so does Windows, probably also macOS).
If we ignore the file format issue, there's still a library problem. A program made for Linux may be written to use Linux-only libraries.
Even when there is a port, you need recompilation due to different calling conventions.
For example, calling a C standard function under Windows looks like this:
lea rdx, [REL filename]
lea rcx, [REL mode]
call fopen
Under Linux you have to use:
lea rdi, [REL filename]
lea rsi, [REL mode]
call fopen
If you ship all the needed libraries (with the right calling convention) with an application, there's still another problem.
The libraries need to talk to the OS and the way this is done is OS-specific.
For example, 32-bit applications used int 80h
under Linux and int 2eh
under Windows.
You can still fix this by porting the library, it now has to use the calling convention of the native OS but the interface of the host OS (e.g. the Linux SYS V ABI but the Windows syscall numbers).
This is already getting exponentially complex in the number of variables but, the real problem is not how to call the system calls, it's the interface they offer.
Trivially, the GUI system is pretty much a monolithic piece of Windows but under Linux you can use any Window manager you like. So if you have a program that calls a function that is specific to the Windows GUI, how do you translate that to Linux?
High-level operations, like create a window, can be translated (this is what libraries like Gtk and Qt do) but low-level operations (say: RegisterClassEx
) do not map one to one.
This is getting even messier if you consider how different are some kernel interfaces.
For example, the uid/gid/permissions thing in Linux and the SID/DACL thing in Windows.
However, you can still fix this: you have to reimplement the other OS interface. This is a massive amount of work, but can be side skipped with a trick: run the other OS in a virtual machine.
This is how WLS2 works and it's why it allows you to use Linux binary under Windows.
Note that WLS2 is possible because:
- Linux is open source, so can be modified easily.
- Linux legally allows that.
- Microsoft thought this was profitable to invest a large number of man-hours on that project.
This is not always the case, Linux cannot run a Windows kernel in a VM to support Windows binaries, it has to emulate it (see: Wine) and that's akin to reimplementing a big part of Windows!
CodePudding user response:
You can make a semi truck tire out of the exact same types of rubber and steel raw materials as a tire made for a motorcycle. But the tires are not interchangable just because they came from the same raw materials.
Just because the alphabet and the dictionary for a language are the same you can create different, incompatible, things from that alphabet and language. A biology text book and a romance novel.
Take 100 programmers and give the same programming task and you should not get a single identical answer from all of them, somewhere between two and 100 different solutions, incompatible in many ways, you cannot take one function from one persons program and randomly mix it with functions from others and have any hope of success.
The operating systems are generally written in a high level language, the underlying processor is just the language you can have a german biology book and a french biology book that say the same thing in the same order just using a different alphabet and/or dictionary and/or grammar, etc. We have seen this with both windows and macos and many others that you can to some extent just recompile and patch up the wee bitty bit of assembly for the new target.
Just like you cant mix the 100 programmers functions you cannot mix macos and windows drivers, their system calls are incompatible. As a good example of that look at this site and others for system calls for arm for example. The linux system calls for arm use certain software interrupt numbers to do certain things, the same hardware running a different operating system, maps the system calls in a different, incompatible way. (I guess mips is a better example spim vs linux).
The instruction set is just the alphabet, that same alphabet can be used to generate many different things, there is not only one bioligy book ever written using the english language, there are very many, incompatible. The same alphabet and dictionary are used to write my answer and any other answer to this question, yet they are not the same answer.
The instruction set is like standard size nuts and bolts, and you can build a great many things that do not resemble each other or have the same function using the same basic components. Can build a school or a residential house using the same types of bricks and boards and fasteners and glues. But they are not comparable buildings.