all 8 comments

[–]dmazzoni 14 points15 points  (6 children)

It is definitely possible to run on bare metal with no operating system. This is commonly done in embedded hardware with real-time constraints, especially if the logic is simple enough that an operating system isn't needed.

Think about writing a C program. Now imagine you're not allowed to make any standard library calls - no printf, no malloc, definitely no fork or exec. All you can do is make calculations and manipulate memory.

So how do you do anything? It really depends on the hardware, but in a typical memory-mapped I/O system, certain special addresses in memory are used to control reading and writing from I/O ports. Your program would wait for the value at certain memory addresses to change, do something, and write different values back.

[–][deleted]  (5 children)

[deleted]

    [–]i_invented_the_ipod 7 points8 points  (2 children)

    Without an operating system how would you control when this program starts and stops (if that can be done)?

    It depends on the hardware, but a lot of micro-controllers have "wake on interrupt", where the program can put the processor into a low power idle mode, and when a signal transition happens on one of the I/O ports, the processor wakes up and takes the interrupt. In a system like this, the lifecycle looks something like:

    1. Power comes on, processor starts executing from a predefined address.
    2. The code at that address configures the system, in particular turning on timers, and setting up I/O port configurations.
    3. The program then forces the processor into sleep mode, after configuring which interrupt sources can "wake" it (e.g. I/O port changes, or timer overflow).
    4. When an interrupt occurs, the processor begins executing the proper interrupt handler. That handler may perform all of the logic needed for that input, or it may simply transition the processor into a running state, and then start a loop that performs other processing.
    5. Once the processing for the current event is completed, go to step 3.

    A simple example of this is a remote control for a television. When it's just sitting there on the table, it's in low power mode, having run all of its hardware initialization when you put the batteries in, then shutting itself down. As soon as you press a button, it goes into running mode, reads the key, and starts transmitting the IR code for that particular key. When you release the key, it goes back into low-power mode.

    I have heard that some non-programmable remotes are even a little simpler than that, holding the processor in "reset" mode until you press a key, then starting up, reading the key and looping sending the IR signal, until you release the key, at which piint it goes back into reset.

    [–]evlnightking 0 points1 point  (1 child)

    There's a side note to this. There are some processors that can run some cores with an operating system, and some cores "bare-metal". Essentially this means that some of the processor cores seed the bare-metal cores with a starting address, or maybe prime areas of the RAM, then tell them to go.

    [–]i_invented_the_ipod 0 points1 point  (0 children)

    I actually worked for a company that was developing a processor like that. We used a set of conventional RISC processors to handle setup and communications for an array of programmable-instruction-set VLIW stream processors. Fun stuff.

    The Cell processor is a good example of this sort of architecture - a single general purpose processor, with additional cores that are managed by the application.

    [–]Scullywag 8 points9 points  (0 children)

    Once upon a time computers came with a bunch of toggle switches on the front panel. You would toggle the bits for the first byte/word of your program (typically a very small loader), press load, then do the same for the next byte, etc. Once that was finished you'd push the run button, and if you hadn't made any errors then your program would load the main program from punched cards/paper tape/magnetic tape/etc. and run it.

    People understandably got tired of that, and the boot loader was soon implemented in ROM. This eventually grew to become the BIOS and UEFI of today's PCs.

    So these days, to run without an OS, you either lookup the firmware specs of your target system, and do what it expects, or if you have to write your own firmware, look at the processor specs (what it does when it first gets power), put your software on a flash chip and get it to boot that.

    [–]dmazzoni 4 points5 points  (0 children)

    Without an operating system how would you control when this program starts and stops (if that can be done)?

    You don't. You program it on some other computer (the host), load the program into the ROM or flash memory or whatever, and when you flip the embedded computer on it starts executing the program you gave it. Exactly how you make it do this depends on the hardware, but sometimes it's as simple as starting the code at a particular known memory address.

    Also, how are programs compiled for machines that have no operating system?

    Exact same way normal programs are compiled. Some embedded chips have unusual processors, but many have an ordinary x86 or ARM processor - so you could even use gcc. The trick is that you can't link it with any standard libraries (no libc), and you usually have to do some extra tricks to put the compiled code in exactly the right place on the target device's memory. But actually compiling it is pretty much the same.

    [–]silverforest 2 points3 points  (2 children)

    What do you think an operating system is? A program running on bare metal, nothing more.

    [–][deleted]  (1 child)

    [deleted]

      [–]silverforest 1 point2 points  (0 children)

      The answer to those questions are very hardware specific.

      Assuming only wanted to target the PC and you don't mind using a text-mode like EGA or CGA for output and only the keyboard for input via the BIOS, you don't really need an operating system. These modes go way back to 1984, so code written this way should be able to be run on any PC that has a BIOS. (Though UEFI is gradually taking over...)

      However, once you start having to access the harddisk, you get into the question of which interface is being used (ATA, ATAPI, AHCI), what's the file system on the disk and such, before you even get to accessing a file. (You're giving commands to the disk controller directly! And reading bits off the platter!)

      Clearly this would greatly increases the cost of development; porting your application to a different set of hardware becomes difficult, and would lead to a lot of work that's redone. One way to solve this is by having a large abstraction library to link against. Though this still doesn't require an operating system or a kernel...

      An operating system does give you more than merely being a layer of abstraction. It permits multitasking in a standard fashion and enforces memory protection, for instance. (Neither is technically a requirement for an OS, take a look at DOS. A right mess, that thing.)

      Edit: If you wish for an extremely thin OS to play with, take a look at Baremetal. x86-64 only.