> This would make more or less any ISA implementation on higher level hardware an "OS":
I think – in practice – one of the most distinctive things an OS supplies is file management – APIs to open/close/read/write/etc files/directories, pathname syntax parsing, etc – both the VFS layer and the filesystems (if they are distinguished). I've never seen a hardware ISA (as opposed to a bytecode implemented in software) with instructions to do stuff like that. If that's the yardstick, no "ISA implementation on higher level hardware" counts as an "OS".
Most language runtimes provide those kinds of facilities, but they bulk of the implementation work is actually done by the host OS, with the language runtime often doing little more than providing pass-thru access to host OS services; sometimes adding some virtualisation layer on top (for example, Tcl VFS), but still the host OS file APIs are the by-far most common backend.
Whereas, a language runtime which actually implemented its own filesystem internally, and just asked its host for some block storage, is much closer to being an OS - how much does it matter whether the block storage is files on a host OS filesystem, or a paravirtualized block device, or a "real" block device such as SATA/SAS (which might be virtualized anyway)? The code change to switch between them is relatively small, it could even be pluggable modules. You can even talk SCSI/ATA from userspace: over network (iSCSI or ATAoE) or using SCSI/ATA-passthru support provided by the host OS.
Other features I've never seen in an ISA – a TCP/IP stack, user/group management (as opposed to some capability primitives which that could be built on top of). A language runtime which provides those itself, rather than relying on the host OS, is really a guest OS.
> Well, memory management, I/O, task scheduling, HAL, and all the other things an actual OS provides. ;-)
A lot of those things are at least partially implemented in hardware, although the hardware/software balance varies widely from architecture to architecture. Although a rare feature nowadays, several CISC ISAs include hardware-support for task switching (x86 TSS are most famous example although never saw much use; IMPI, the underlying ISA of the IBM System/38 and CISC AS/400s, is another). Some ISAs have even gone so far as to add hardware acceleration for garbage collection (Lisp machines, Intel iAPX 432). An operating system running on an ISA which provides many of those functions in hardware may delegate most of them to the hardware; what's the difference between delegating those functions to hardware versus to a host OS?
A guest OS asks for relatively few services from its host ("give me 4GB of memory, 100GB of block storage, an Ethernet interface, and here's some threads to run"). A mere language runtime expects the host to provide a filesystem (as opposed to just block storage), Berkeley sockets (as opposed to just a TUN/TAP device), a security database (NSS, PAM, /etc/passwd, Windows LSASS, etc), executable loading (here's the name of an ELF/PE-COFF/Mach-O, please load and run it as a subprocess with these arguments) – a guest OS does all that itself.
I think – in practice – one of the most distinctive things an OS supplies is file management – APIs to open/close/read/write/etc files/directories, pathname syntax parsing, etc – both the VFS layer and the filesystems (if they are distinguished). I've never seen a hardware ISA (as opposed to a bytecode implemented in software) with instructions to do stuff like that. If that's the yardstick, no "ISA implementation on higher level hardware" counts as an "OS".
Most language runtimes provide those kinds of facilities, but they bulk of the implementation work is actually done by the host OS, with the language runtime often doing little more than providing pass-thru access to host OS services; sometimes adding some virtualisation layer on top (for example, Tcl VFS), but still the host OS file APIs are the by-far most common backend.
Whereas, a language runtime which actually implemented its own filesystem internally, and just asked its host for some block storage, is much closer to being an OS - how much does it matter whether the block storage is files on a host OS filesystem, or a paravirtualized block device, or a "real" block device such as SATA/SAS (which might be virtualized anyway)? The code change to switch between them is relatively small, it could even be pluggable modules. You can even talk SCSI/ATA from userspace: over network (iSCSI or ATAoE) or using SCSI/ATA-passthru support provided by the host OS.
Other features I've never seen in an ISA – a TCP/IP stack, user/group management (as opposed to some capability primitives which that could be built on top of). A language runtime which provides those itself, rather than relying on the host OS, is really a guest OS.
> Well, memory management, I/O, task scheduling, HAL, and all the other things an actual OS provides. ;-)
A lot of those things are at least partially implemented in hardware, although the hardware/software balance varies widely from architecture to architecture. Although a rare feature nowadays, several CISC ISAs include hardware-support for task switching (x86 TSS are most famous example although never saw much use; IMPI, the underlying ISA of the IBM System/38 and CISC AS/400s, is another). Some ISAs have even gone so far as to add hardware acceleration for garbage collection (Lisp machines, Intel iAPX 432). An operating system running on an ISA which provides many of those functions in hardware may delegate most of them to the hardware; what's the difference between delegating those functions to hardware versus to a host OS?
A guest OS asks for relatively few services from its host ("give me 4GB of memory, 100GB of block storage, an Ethernet interface, and here's some threads to run"). A mere language runtime expects the host to provide a filesystem (as opposed to just block storage), Berkeley sockets (as opposed to just a TUN/TAP device), a security database (NSS, PAM, /etc/passwd, Windows LSASS, etc), executable loading (here's the name of an ELF/PE-COFF/Mach-O, please load and run it as a subprocess with these arguments) – a guest OS does all that itself.