What are the hidden complexities of binary compatibility?
What are the hidden complexities of binary compatibility?
Often, beginners in OSDEV imagine their OS being compatible with all the major operating systems. However... wine is the best (not an emulator!) compatibility layer we have in this field so far, and it is still notorious in 2024 for being unreliable. Sure, it's made substantial progress, but many Windows programs that many users find very important (Adobe Creative Cloud, Visual Studio, ROBLOX) still do not work reliably.
There have been many notable attempts at supporting another operating system's software, to varying degrees of success. The (esoteric) Longene project, the entirety of the 20-year-old ReactOS project, Wine, and even Managarm who aims for source compatibility rather than binary compatibility.
On the surface, it seems relatively simple. Support another system's syscall interface (of which, many do not conflict, as Linux uses interrupt 0x80, and Windows uses interrupt 0x2a IIRC, making multi-compat possible), and the rest of the cards should fall in line, right?
Obviously not, but why?
There have been many notable attempts at supporting another operating system's software, to varying degrees of success. The (esoteric) Longene project, the entirety of the 20-year-old ReactOS project, Wine, and even Managarm who aims for source compatibility rather than binary compatibility.
On the surface, it seems relatively simple. Support another system's syscall interface (of which, many do not conflict, as Linux uses interrupt 0x80, and Windows uses interrupt 0x2a IIRC, making multi-compat possible), and the rest of the cards should fall in line, right?
Obviously not, but why?
Skylight: https://github.com/austanss/skylight
I make stupid mistakes and my vision is terrible. Not a good combination.
NOTE: Never respond to my posts with "it's too hard".
I make stupid mistakes and my vision is terrible. Not a good combination.
NOTE: Never respond to my posts with "it's too hard".
Re: What are the hidden complexities of binary compatibility
"Just support the syscall layer". You say that as though it was simple.
Supporting compatibility with Linux for example would require you to support all of Linux' system calls to some degree at least. That includes SYS_fork and SYS_clone. With those alone, you have already made the choice that processes/threads are created in the fork style, as copies of their parents, with only select things changed. It also requires you to support POSIX file descriptors, and rdos has previously dumped entire buckets of bile onto that concept, so it is not always well-received.
If you want to also support Windows system calls, you also have to support Windows concepts. Such as drives. I just made a topic on BIOS updates for an HP laptop. The HP program I need to run for this has a function to write its files onto a USB stick. It somehow queries all drives in the system to find a suitable candidate to do the dumping on. Now, this does not work at all on a UNIX-like system, which handles devices completely differently.
Next problem you will have is that the actual Windows system call layer is completely undocumented. It is hidden beneath at least two layers of DLLs, which are allowed to change without notice and frequently do. Of those, only the interface of the highest layer is defined, but a lot of applications actually use the lower layers.
The info you have on the interrupt numbers is outdated; all remotely modern operating systems use syscall or sysenter. So now the system calls may intersect! Although that issue can be taken care of with a "personality" mechanism like Linux has (basically you set a flag on the process, and that flag is preserved across execve() and inherited into children by default),
The next issue you have is that many applications use undocumented "features", or just observed behavior, that you also have to implement in order to not break. For example, on Linux, there is a select() function. That function is defined in POSIX to take a struct timeval as timeout. All other functions take a timeout as a timespec structure, and all of those error if the structure given is invalid. Not select(). It will normalize the timeout argument. Or at least, it did historically. Now POSIX doesn't say that that will happen, but if you implement Linux syscall compatibility, you have to implement stuff like this as well.
And finally, sometimes emulation is just not feasible within your framework. It is no coincidence that many of the applications you mention are graphically intensive. Windows has DirectX, a proprietary graphics library. And on Linux, you have basically no good way to implement it. Emulating DirectX with OpenGL is like emulating a Gamecube with a PS2. They are just two very different approaches.
Supporting compatibility with Linux for example would require you to support all of Linux' system calls to some degree at least. That includes SYS_fork and SYS_clone. With those alone, you have already made the choice that processes/threads are created in the fork style, as copies of their parents, with only select things changed. It also requires you to support POSIX file descriptors, and rdos has previously dumped entire buckets of bile onto that concept, so it is not always well-received.
If you want to also support Windows system calls, you also have to support Windows concepts. Such as drives. I just made a topic on BIOS updates for an HP laptop. The HP program I need to run for this has a function to write its files onto a USB stick. It somehow queries all drives in the system to find a suitable candidate to do the dumping on. Now, this does not work at all on a UNIX-like system, which handles devices completely differently.
Next problem you will have is that the actual Windows system call layer is completely undocumented. It is hidden beneath at least two layers of DLLs, which are allowed to change without notice and frequently do. Of those, only the interface of the highest layer is defined, but a lot of applications actually use the lower layers.
The info you have on the interrupt numbers is outdated; all remotely modern operating systems use syscall or sysenter. So now the system calls may intersect! Although that issue can be taken care of with a "personality" mechanism like Linux has (basically you set a flag on the process, and that flag is preserved across execve() and inherited into children by default),
The next issue you have is that many applications use undocumented "features", or just observed behavior, that you also have to implement in order to not break. For example, on Linux, there is a select() function. That function is defined in POSIX to take a struct timeval as timeout. All other functions take a timeout as a timespec structure, and all of those error if the structure given is invalid. Not select(). It will normalize the timeout argument. Or at least, it did historically. Now POSIX doesn't say that that will happen, but if you implement Linux syscall compatibility, you have to implement stuff like this as well.
And finally, sometimes emulation is just not feasible within your framework. It is no coincidence that many of the applications you mention are graphically intensive. Windows has DirectX, a proprietary graphics library. And on Linux, you have basically no good way to implement it. Emulating DirectX with OpenGL is like emulating a Gamecube with a PS2. They are just two very different approaches.
Carpe diem!
Re: What are the hidden complexities of binary compatibility
I think it's worth noting that you've overlooked the whole POSIX ecosystem, of which Managarm here is just the most recent of possibly hundreds of OSs. POSIX and the preceeding Standard Unix standardised the many Unix-like and Unix-compatible OSs which appeared in the 80s if not the late 70s. Compatibility has always been source-level only and has always required patches, but at least you can patch. It has its difficulties but I find it less painful than any other form of compatibility. Well, no, there are frameworks, sometimes attached to languages, which try to work the same way on every OS they support. Those are nice, though there are gotchas such as Windows file semantics and performance characteristics being substantially different from POSIX's.austanss wrote:There have been many notable attempts at supporting another operating system's software, to varying degrees of success. The (esoteric) Longene project, the entirety of the 20-year-old ReactOS project, Wine, and even Managarm who aims for source compatibility rather than binary compatibility.
Kaph — a modular OS intended to be easy and fun to administer and code for.
"May wisdom, fun, and the greater good shine forth in all your work." — Leo Brodie
"May wisdom, fun, and the greater good shine forth in all your work." — Leo Brodie
Re: What are the hidden complexities of binary compatibility
Nitpick: Proton, which is effectively a translation from DirectX to Vulkan, works pretty fine.nullplan wrote:Windows has DirectX, a proprietary graphics library. And on Linux, you have basically no good way to implement it. Emulating DirectX with OpenGL is like emulating a Gamecube with a PS2. They are just two very different approaches.
Every good solution is obvious once you've found it.
Re: What are the hidden complexities of binary compatibility
Are you sure they do that? Windows is millions of lines of code - none of it written for fun. Who are these people who think they can replicate that on their own? I doubt many programmers who actually program would make a claim that they could write and debug millions of lines of code on their own.austanss wrote:Often, beginners in OSDEV imagine their OS being compatible with all the major operating systems.
What is your scope? I believe WINE runs anything that conforms to published specs. If you choose to run software that goes beyond the actual documented API - whose fault is that?However... wine is the best (not an emulator!) compatibility layer we have in this field so far, and it is still notorious in 2024 for being unreliable. Sure, it's made substantial progress, but many Windows programs that many users find very important (Adobe Creative Cloud, Visual Studio, ROBLOX) still do not work reliably.
Programming anything substantial is rarely simple. Are you a programmer who thinks it is simple? How much would you charge me to write a C compiler? It will require about 10,000 lines of code. Far less than the number of lines of code in Windows.There have been many notable attempts at supporting another operating system's software, to varying degrees of success. The (esoteric) Longene project, the entirety of the 20-year-old ReactOS project, Wine, and even Managarm who aims for source compatibility rather than binary compatibility.
On the surface, it seems relatively simple.
The published API for Windows is to use DLLs, not an interrupt.Support another system's syscall interface (of which, many do not conflict, as Linux uses interrupt 0x80, and Windows uses interrupt 0x2a IIRC, making multi-compat possible), and the rest of the cards should fall in line, right?
Obviously not, but why?
Regardless, what's your scope? PDOS/386 runs both Linux programs that use int 0x80, and Windows programs that use kernel32.dll or msvcrt.dll. It has the OS/2 API (also DLLs too). And another interface called PDOS-generic.
The supported API is a subset of what Windows etc supports. A subset that can be achieved by a single programmer. And sufficient to support an entire toolchain to allow self-hosting.
So yes - if you show me the programmer you refer to who wants compatibility, and show me to what extent he wants that compatibility - then yes, it can be done already. And has been done already. WINE is just one example. It already satisfies any reasonable goal. Way above what is reasonable for a single programmer to achieve.
Re: What are the hidden complexities of binary compatibility
If you allow "to some extent" ...nullplan wrote:Supporting compatibility with Linux for example would require you to support all of Linux' system calls to some degree at least. That includes SYS_fork and SYS_clone.
... then this is not strictly true.With those alone, you have already made the choice that processes/threads are created in the fork style, as copies of their parents, with only select things changed.
PDPCLIB uses:
CLONE_VFORK 0x4000
so the Unix model isn't really required.
BFN. Paul.
-
- Member
- Posts: 5496
- Joined: Mon Mar 25, 2013 7:01 pm
Re: What are the hidden complexities of binary compatibility
Yes.kerravon wrote:Are you sure they do that?austanss wrote:Often, beginners in OSDEV imagine their OS being compatible with all the major operating systems.
Often, beginners in OSdev are also beginners in programming. It's easy to underestimate the work involved when you've never done anything like it before.kerravon wrote:Windows is millions of lines of code - none of it written for fun. Who are these people who think they can replicate that on their own? I doubt many programmers who actually program would make a claim that they could write and debug millions of lines of code on their own.
Re: What are the hidden complexities of binary compatibility
That's not quoting an actual poster.Octocontrabass wrote:Yes.kerravon wrote:Are you sure they do that?austanss wrote:Often, beginners in OSDEV imagine their OS being compatible with all the major operating systems.
Really? There are people who decide that their first programming task will be to write an operating system?Often, beginners in OSdev are also beginners in programming. It's easy to underestimate the work involved when you've never done anything like it before.kerravon wrote:Windows is millions of lines of code - none of it written for fun. Who are these people who think they can replicate that on their own? I doubt many programmers who actually program would make a claim that they could write and debug millions of lines of code on their own.
I'd love to have such conversations to find out why people would be so bold. But I assume they only stick around for about 10 minutes until they realize they need to actually work to accomplish anything.
Re: What are the hidden complexities of binary compatibility
Dunning-Kruger effects, mostly. They do not know what they do not know, but figure it can't be that difficult. Then they inevitably get frustrated and give up and you never hear from them again.kerravon wrote:I'd love to have such conversations to find out why people would be so bold.
Occasionally someone comes along who sticks around long enough to start getting the message that reading documentation rather than tutorials is important. They may still get frustrated at the sheer volume of stuff to read, tho.
Carpe diem!
-
- Member
- Posts: 232
- Joined: Mon Jul 25, 2016 6:54 pm
- Location: Adelaide, Australia
Re: What are the hidden complexities of binary compatibility
They certainly exist, I remember seeing a few on this forum over the years but these days I think the osdev subreddit gets most of that sort of thing.kerravon wrote:Really? There are people who decide that their first programming task will be to write an operating system?
These are just a few posts I found quickly to demonstrate the mindset:
https://www.reddit.com/r/osdev/comments ... lop_an_os/
https://www.reddit.com/r/osdev/comments ... osdev_and/
https://www.reddit.com/r/osdev/comments ... literally/
https://www.reddit.com/r/osdev/comments ... velopment/
https://www.reddit.com/r/osdev/comments ... dows_apps/
Not to make a negative example of these people or anything. I fell victim to the same mentality when I was first learning to program, but I thought I could make a 3D game engine from scratch.
I think the most common is someone with a little experience with JS or Python who just doesn't grasp the gulf in difficulty between doing some simple programming exercises and OS development.
Re: What are the hidden complexities of binary compatibility
Oh yeah - I remember that now. I can remember a programmer explaining that lay people think that this profession is trivial to master and you can just do an online course for a couple of days and you're a genius.nullplan wrote:Dunning-Kruger effects, mostly. They do not know what they do not know, but figure it can't be that difficult.kerravon wrote:I'd love to have such conversations to find out why people would be so bold.
But they don't do that for other professions such as becoming a doctor.
And I think this programmer, on encountering one of those people (who wanted to be a programmer for the money), asked him why he didn't become a doctor, as they got good money too. "oh no - that's difficult/hard work".
I heard something else too. Business owners are forced to pay market rates for programmers, but it really pisses them off that they have to pay such a high price for an allegedly easy task. So what they do instead is make them work long hours - and that this is where the system breaks down - the programmers actually work those long hours instead of refusing.
You know how you hear on the news sometimes that the economy is improving due to "increased productivity"? Someone told me that is code for "programmers working longer hours for the same pay".
Sounds like the rot needs to stop.
Even the whole concept seems rather strange. A tutorial on how to write an operating system? Unless you can articulate some alternate goal, what's wrong with:reading documentation rather than tutorials is important.
1. Download the Linux source code.
2. Do ls -l
3. Go to the first file, and open it up.
4. Copy line number 1 into your clipboard.
5. Paste that line into a new file with the same name.
6. Repeat the process with line 2 and so on.
7. Repeat the process with the next file.
8. Compile and voila - you've created an OS unless that doesn't meet some stated requirement for your OS.
Re: What are the hidden complexities of binary compatibility
Thanks - I read all of all of them. In the first link the guy actually admits he shouldn't have asked the question in the first place.StudlyCaps wrote:They certainly exist, I remember seeing a few on this forum over the years but these days I think the osdev subreddit gets most of that sort of thing.kerravon wrote:Really? There are people who decide that their first programming task will be to write an operating system?
These are just a few posts I found quickly to demonstrate the mindset:
https://www.reddit.com/r/osdev/comments ... lop_an_os/
https://www.reddit.com/r/osdev/comments ... osdev_and/
https://www.reddit.com/r/osdev/comments ... literally/
https://www.reddit.com/r/osdev/comments ... velopment/
https://www.reddit.com/r/osdev/comments ... dows_apps/
Yeah, that reminds me of someone I introduced to programming. I was able to get them up to speed so that they could hold down a job maintaining a dicky little program that didn't do much.I think the most common is someone with a little experience with JS or Python who just doesn't grasp the gulf in difficulty between doing some simple programming exercises and OS development.
I was then surprised when they said that now that they "knew programming" that they wanted to become an analyst now - a great career move for sure!
Reality did dawn on them later. I think I might have given them a more substantial program to write to see how they went.
And they did become solid performers in due course - aware of and working within their limits - and indeed I believe they did become an analyst at a far more appropriate juncture.
But it was odd to observe.
-
- Member
- Posts: 232
- Joined: Mon Jul 25, 2016 6:54 pm
- Location: Adelaide, Australia
Re: What are the hidden complexities of binary compatibility
kerravon wrote:And I think this programmer, on encountering one of those people (who wanted to be a programmer for the money), asked him why he didn't become a doctor, as they got good money too. "oh no - that's difficult/hard work".
I can confirm this is a pretty common attitude unfortunately. The majority of people, even prospective developers and people high up in companies that rely on developers to do business, just don't respect our field. Your observations regarding how programmers are treated by employers is also something I can, unfortunately, confirm.
A funny story, with a happy ending at least.kerravon wrote:And they did become solid performers in due course - aware of and working within their limits
One of the difficult things, for me, is that because the person who just starts programming and wants to write an OS (for example) does have the passion and interested necessary to become very skilled, you don't want to put them off, but you also need to let them know that no, an OS is not an achievable goal right now. That sort of desire to push further and do more than most will likely serve them well though, if they can learn the fundamentals and pair their enthusiasm with dedication.