The problem with C is that it's not memory safe. Therefore you need hardware hacks (MMU) to separate processes. If you use a memory safe language you lose the ability to do pointer arithmetic (and the speed hacks that come with it), but you don't need to remap the page table every time you switch between processes. This makes threads and processes pretty much the same thing. Code injection is impossible in a memory-safe language, which helps with security (I'm talking about buffer overflows here, not SQL injecion, XSS etc).
Using a higher-level language can also help with many other things, for example integrated garbage collection, built-in serialization and process migration, intelligent message passing (pass objects around rather than bytes), etc.
Therefore you need hardware hacks (MMU) to separate processes
I cannot apprehend the confusion of ideas that would lead you to believe this is caused by C. It's assembly, not C, that runs on your machine, and assembly is not memory safe. Microsoft's Singularity runs managed code, so there's a software layer providing memory protection.
An operating system is not defined by its preferred programming language.
"I cannot apprehend the confusion of ideas that would lead you to believe this is caused by C. It's assembly, not C, that runs on your machine, and assembly is not memory safe"
There is no confusion of ideas, but I like the Babbage reference :)
In Singularity the code is compiled first to CIL, then to x86, x64, or ARM by an AOT (ahead-of-time) compiler. Now here's the thing: the OS loader does not load Assembly code, it loads CIL code, which it then compiles further down to Assembly. Since CIL is verifiably memory safe (like Java bytecode), and assuming the AOT compiler is not buggy, the OS is memory safe. Hence no need for MMU/MPU to do memory protection.
So even though you're right that Assembly is not memory safe, the final compiler stage (in this case CIL can be seen as an intermediary language) is implemented in the OS (the loader), and the OS will reject any non-memory safe code. No code that can write outside array boundaries, violates type safety, and attempts pointer arithmetic will be allowed to execute.
So no, Singularity does not provide a software layer for memory protection, it's purely an (intermediary) language feature.
The software layer for memory protection here is the AOT compiler. As you alluded to yourself, if Mark Dowd finds one of the bugs in your AOT compiler, then you are toast.
The nice thing is that these protections can be applied ahead-of-time rather than at runtime, as the MMU does.
It has been shown (see Native Client) that even a slightly restricted subset of x86 assembler can be made verifiably-safe. In principle, you could do the same thing with C - in fact, you likely wouldn't even have to change the language definition, since the egregious abuses in C mostly result in "undefined behaviour", which allows the implementation to detect and trap them rather than hose the machine. (It is a curious fact that C itself isn't inherently "memory unsafe" - merely almost every implementation of C ever written is).
People have attempted to make C memory safe (i.e. bitc, cyclone), so you could write an OS in that, I guess. My original point however was that C itself is not, and that supporting C means supporting non-memory safe drivers, services, and programs.
If you can come up with a program that verifies whether a C program is memory safe or not (without constraining the language spec), well, hats off to you sir, I think I know a couple of security experts who might want to have a word with you :)
VM is also useful to handle fragmentation and to map parts of a large "array" to different NUMA nodes (so that it can be accessed by several threads without overloading a single memory channel). In a multi-process system, if you get rid of VM, you'll be pretty much obliged to have kernel-level relocating GC or to make array indexing involve software table lookup. I keep my TLB, thank you.
Comments
The problem with C is that it's not memory safe. Therefore you need hardware hacks (MMU) to separate processes. If you use a memory safe language you lose the ability to do pointer arithmetic (and the speed hacks that come with it), but you don't need to remap the page table every time you switch between processes. This makes threads and processes pretty much the same thing. Code injection is impossible in a memory-safe language, which helps with security (I'm talking about buffer overflows here, not SQL injecion, XSS etc).
Using a higher-level language can also help with many other things, for example integrated garbage collection, built-in serialization and process migration, intelligent message passing (pass objects around rather than bytes), etc.
A good example of an implementation of these ideas is Singularity (http://research.microsoft.com/en-us/projects/singularity/), which is written in a superset of C#.
Therefore you need hardware hacks (MMU) to separate processes
I cannot apprehend the confusion of ideas that would lead you to believe this is caused by C. It's assembly, not C, that runs on your machine, and assembly is not memory safe. Microsoft's Singularity runs managed code, so there's a software layer providing memory protection.
An operating system is not defined by its preferred programming language.
"I cannot apprehend the confusion of ideas that would lead you to believe this is caused by C. It's assembly, not C, that runs on your machine, and assembly is not memory safe"
There is no confusion of ideas, but I like the Babbage reference :)
In Singularity the code is compiled first to CIL, then to x86, x64, or ARM by an AOT (ahead-of-time) compiler. Now here's the thing: the OS loader does not load Assembly code, it loads CIL code, which it then compiles further down to Assembly. Since CIL is verifiably memory safe (like Java bytecode), and assuming the AOT compiler is not buggy, the OS is memory safe. Hence no need for MMU/MPU to do memory protection.
So even though you're right that Assembly is not memory safe, the final compiler stage (in this case CIL can be seen as an intermediary language) is implemented in the OS (the loader), and the OS will reject any non-memory safe code. No code that can write outside array boundaries, violates type safety, and attempts pointer arithmetic will be allowed to execute.
So no, Singularity does not provide a software layer for memory protection, it's purely an (intermediary) language feature.
The software layer for memory protection here is the AOT compiler. As you alluded to yourself, if Mark Dowd finds one of the bugs in your AOT compiler, then you are toast.
The nice thing is that these protections can be applied ahead-of-time rather than at runtime, as the MMU does.
It has been shown (see Native Client) that even a slightly restricted subset of x86 assembler can be made verifiably-safe. In principle, you could do the same thing with C - in fact, you likely wouldn't even have to change the language definition, since the egregious abuses in C mostly result in "undefined behaviour", which allows the implementation to detect and trap them rather than hose the machine. (It is a curious fact that C itself isn't inherently "memory unsafe" - merely almost every implementation of C ever written is).
People have attempted to make C memory safe (i.e. bitc, cyclone), so you could write an OS in that, I guess. My original point however was that C itself is not, and that supporting C means supporting non-memory safe drivers, services, and programs.
If you can come up with a program that verifies whether a C program is memory safe or not (without constraining the language spec), well, hats off to you sir, I think I know a couple of security experts who might want to have a word with you :)
VM is also useful to handle fragmentation and to map parts of a large "array" to different NUMA nodes (so that it can be accessed by several threads without overloading a single memory channel). In a multi-process system, if you get rid of VM, you'll be pretty much obliged to have kernel-level relocating GC or to make array indexing involve software table lookup. I keep my TLB, thank you.
Just to digress slightly, if I can ask a question.
Does the x86 still use a page-based memory model? I was under the impression it went to a full range addressing model with the P6.
Page-based memory was what stopped me learning x86 assembly back in the day. I loved the Z-80 (and Rodney Zacks).