A few drawings about Linux
jvns.ca
jvns.ca
There's no reason to restrict this to kernel objects. FUSE also allows user processes to implement a file system but it's clunky as it breaks a lot of old assumptions.
See the Plan 9 operating system for an earlier clean implementation of this concept, including programmatic interaction with your text editor through file APIs.
https://en.wikipedia.org/wiki/Plumber_(program) http://www.mostlymaths.net/2013/04/just-as-mario-using-plan9...
http://www3.sympatico.ca/n.rieck/docs/Windows-NT_is_VMS_re-i...
- Linux trusts their users to know what they are doing. They do not build layers of abstractions to make things "easy". These abstractions create complexity and just get in the way, especially if you know what you're doing technically.
- There is significant influence on the technical decisions by nontechnical people for business, personal, and political goals. Quarterly profits are the main motivator for Windows development. If it turned out that abandoning Windows would make Microsoft more money, they would do it. With Linux, the incentive is to have a "good" operating system. Money is important in the sense that it keeps Linux dev healthy, but making money is not the primary objective of the project.
- Because money is the main motivator, Windows is beholden to the people with the most cash. Often this is large enterprise organizations which make poor technical decisions. Microsoft in turn, must provide support for these technical decisions, forcing Microsoft itself to make poor technical decisions. I'm sure Windows developers would love if everyone stopped using old crufty tech from 2001, but since there's a lot of money riding on that tech, the show must go on.
I'd assume the situation would probably be roughly the same with comparable open source and commercial operating systems i.e. macOS/OS X, FreeBSD, iOS, Android(???) and implies the same for any piece of software...
In my opinion, the key is that Linux is libre software.
Windows has to deal with lots of old drivers and userland software that are arcane binary blobs. In the Linux world, most software running on it is libre and the community can evolve it to work with newer systems. This is specially true for drivers, since most drivers are GPL and kept in the kernel source tree. This promotes a healthier relationship between the companies and individuals involved where, through shared ownership, everybody is on the same boat.
On Linux, if no one wants to maintain the old driver, it doesn't get maintained and the manufacturer does it or people stop using it and use something else. Poof no more old driver!
Agreed on libre software, wouldn't be possible without that of course. But I think money has had a large impact as well.
Much of the budget for coding this stack has to be spent on maintaining this easy to use GUI instead of things like developing package managers, filesystems like ZFS, powerful software raid, etc. Because GNU/Linux assumes the user will have some coding skill and technical knowledge, it can spend less time building easy to use stuff and focus on overcoming technical challenges. I guess my point should have said GNU/Linux stack overall vs Windows stack.
Paradoxically, this allows Linux to be an almost universal ABI, since linux binaries can be run on FreeBSD, Illumos/SmartOS, Solaris, and even Windows.
When software devs ask for a consistent toolkit, they are not asking for a single toolkit across the range of Linux installs. But a toolkit that is by policy stable for a decade or more on the API/ABI level.
Second view on the matter (which is more hearsay than hard fact) is that with the relatively advanced kernel WinNT team had built they were running into critical performance issues. This probably was exacerbated by Windows more often running on weak PC hardware at a time when UNIX systems were heftier workstations and servers. These perf issues required them to make major compromises to the system to make it sellable.
Another more minor reason might be that WinNT was from the ground up designed to be both portable (at least to Alpha in additon to i386) and flexible enough to provide different userland interfaces (in addition to Windows, it also had POSIX and OS/2 interfaces), whereas Linux was very much i386 and POSIX only early on.
edit: oops, forgot one more thing: Windows offers an API for drivers whereas in Linux drivers are generally considered a part of the kernel itself and the APIs they use are not public. This design decision makes Windows API surface inherently larger.
Fundamentally, the WinNT kernel and the Linux kernel both use preemptive multitasking, virtual memory addresses, paged memory, file and process abstractions, and so on. WinNT is written in a weirdly limited dialect of C++; Linux is written in a weirdly augmented dialect of C. Most people would have to agree that they're more similar than different.
It's true that Linux was originally i386-only, but that didn't really affect the kernel design much. It was always written in portable C, with just a bare minimum of assembly language where needed.
Probably the worst things about the WindowsNT kernel were: * The decision to bolt on vestigial OS/2 and POSIX interfaces (mostly done for political reasons, to get contracts where "POSIX-compatible" was a requirement). * The decision to push parts of the Window Manager into the kernel, making life harder for servers. * NTFS is overly complex (streams, anyone?) and has mediocre performance. * All the horrible hacks to keep old proprietary software running (though a lot of these were in userspace, not the kernel) * Horrible coding style-- using macros instead of void*, for example, and hungarian notation everywhere.
Augmented to the point where it feels very much like an Object Oriented language.
I do agree that there are some object-oriented-like features in Linux, like the use of tables of function pointers as VTables.
To get around this, we have the ioctl subsystem, which adds a whole lot of complexity. Modern I/O programming involves heavy use of ioctl and thus isn't nearly as simple as those drawings suggest. Per Wikipedia, "A kernel that provides several hundred system calls may provide several thousand ioctl calls."
FILE *fh = fopen("/dev/cd/do", "w");
fputs("eject\n", fh);
AFAIU, people use ioctl because it's a more strongly typed interface compared to juggling strings (usually the implementation defines the interface via /usr/include headers, useful from C), and because historically implementing an ioctl interface for a new device was easier in kernel implementations, including early Linux (and arguably still).Linux developers look at the Win32 API and think it's too complex. But Win32 developers might look at Linux (or any POSIX) and think it just pushes the complexity out into user code.
Someone in this thread brought up process creation (fork/exec vs. CreateProcess). fork/exec is simple, but there are a lot of pitfalls you have to be aware of. If you don't care about the result of the process, too bad, you still have to set up a SIGCHLD handler to waitpid or whatever or else you'll end up with a zombie process--which you probably won't notice, but your customers eventually will, at the most inconvenient moment.
Or if your process is running as root and you want to launch a child process as a different user, you have to do this VERY carefully (calling setsid, setgid, setgroups in exactly the right order--oh and I almost forget about seteuid and setresuid, setegid and setresgid).
Or take a look at writing to a socket; the individual APIs involved are all very simple but you have to know to ignore SIGPIPE or else your process will terminate if the connection is broken while you're writing.
Bottom line is that when I write against Windows I spend more time reading docs, and when I write against POSIX I spend more time googling and debugging.
Your disk is like... music disks. You seek to a position, read... and when you read the position advances.