- As far as I read, files are introduced in OS books. Before an OS is installed on a bare computer system, does the computer use files?
- In particular, executable files have formats in OSes, e.g. executable files have ELF format in Linux, which can guide the loader in the OS to load them into memory when running them. Before installation of an OS, does the computer system have the concept of executable files or something similar for storing programs?
If so, what is their format, for example, on a X86 or X86-64 bit bare computer machine?
Thanks.
I am not asking about booting but I am curious how a program is stored on a bare computer. A program may be for booting or not for booting. In particular, I am interested in how a user program is stored on a bare computer.
11
Since you’re not talking about booting, your answer is actually that the concept of “executable,” or even “files” is rather irrelevant.
The concept of files is an OS concept. Without an OS, all you have is a harddrive, with some bits on it. It is the OS that gives structure to that information that makes it meaningful to think of the data as a file.
For a “bare” computer, without considering booting, the idea of “storing user programs” is meaningless besides the very boring definition of “it stores the files by putting the 1’s and 0’s on a harddrive.” At this level, these 1’s and 0’s are indistinguishable from those of text, or images, or anything else because there is no “defined” structure.
People are focusing on booting because that is where your concept of “executable file” becomes meaningful for the first time. When a BIOS boots (from ROM), one of its last tasks is identifying a media to boot from (i.e. a hard drive), and “executing” something from it. This is usually implemented as “the bios will command the harddrive to produce the 1’s and 0’s from a specific numbered location on the harddrive. These 1’s and 0’s will then be stored in memory, and the Instruction Pointer of the 1st CPU will be pointed at those 1’s and 0’s.”
This is the point where we get closest to an answer to your question. This block of 1’s and 0’s is formatted in a way that is defined by the CPU as a set of instructions. I can’t quite call it a file, but is definitely a continuous block of CPU defined values loaded from a harddrive.
Now this particular set of instructions gets to take ownership of the computer. It will command everything from here on out. If I wished, I can now go ask the harddrive for a different block of 1’s and 0’s, store those in memory, and “run them.” This suggests that this block of 1’s and 0’s known as “machine code” would be an answer to your question “how are user programs stored.” However, it is an incomplete answer. I could also write my block to go read from the harddrive, then invert every bit it read, before jumping to that data as a set of instructions. In this case, now the 1’s and 0’s are not “machine code,” but rather a sort of encoded machine code. This shows that there is no one “defined” way to store user programs on a bare computer except for the first program, which is special.
Now eventually we’re going to run some programs that bring in the concept of a file system on the harddrive. Now, for the first time, we have a concept of a file, so we can talk about “executable files.” However, because we’re so far along in the process, there is no one way they get stored. As shown before, we could arbitrarily choose to invert every bit.
So the reason why your question involves terms that don’t really go together is that the concept of an “executable file” is at odds with the idea of a “bare computer.” The two words simply do not go together. However, in the initial moments of booting, there is a section of the harddrive, which is not a file but gets really close to being called a file, which is in an executable format defined by the CPU.
7
Files are a low-level abstraction provided by the operating system thru some file system layer. Another important abstraction provided by OSes is processes (running instances of programs). The OSdev site has interesting practical information. The underlying bar metal computer (e.g. your x86 laptop or desktop) does not know about files…. It is reading and writing sectors (often blocks of 512 bytes or of 4096 bytes) on disks (and the OS builds the file abstraction above that). Your usual OS (Linux or Windows) is using the file abstractions to store programs. But the bar metal computer is just executing machine code instructions (and some of them are read from the disk by the OS). At the lowest level, close to the hardware, programs do not really exist (only machine code)! Executables (hence programs) and processes are also an abstraction (& convention) provided and handled by the OS. On Linux, most executable binaries are in ELF.
But you could imagine an operating system without any files. You’ll have to write such an OS from scratch, running on the bare metal (and of course you’ll have to define some notion of program, care about how that thing boots, run programs and uses the disk). It could have some orthogonal persistence model (like Phantom, EROS, etc…)
In the 1980s & 1990s some Lisp machines did not have any files. They persisted their entire state on the disk.
In practice computers are becoming increasing complex. You can look at UEFI and at the Grub boot loader as having some limited form of files. and some firmware (like Open Firmware) also provide a limited form of files.
Another amusing way of looking at this is to imagine that aliens might have computers which do not use any files (but something else). Files are an invention (somehow related to technology and social issues of the IT sector in the 1960s)
And of course some small microcontrollers don’t have file systems. My washing machine probably has some 8 bit microcontroller, but no file system.
I guess that files are becoming less relevant than before (databases being increasingly important). Notice that a plain Unix-like filesystem might not be the best way to organize your data on some multi terabyte disk. You probably want to store more meta-data about it than a native filesystem offers (and you might use some database for that).
2
To get an OS up and running, there are various things being executed which are typically called “loaders” and “bootstrappers”.
Their collective purpose is exactly as their names imply: to get the OS up and running, one step at a time.
Some of these executable code are stored in read-only memory (ROM), or some type of reprogrammable memory (such as Flash ROM), or a certain predetermined location on the storage disk (located on a so-called “boot sector”, which is a predetermined location on a “disk partition”) from which the machine can be started up.
Your suspicion that at least some of these executable code must exist outside the concept we call “files” or “file system” is correct. Not all of them are; but at least some of them must be.
The computer hardware-firmware, and operating system itself typically are able to access these “non-file” storage areas to perform infrequent maintenance upgrades to these executable code.
The purpose of allowing these upgrades from software is an engineering choice driven by the consumer market – it is cheaper to maintain computers if is it possible for customers to perform the upgrades, than to require machines to be shipped back to a factory or maintenance center to do the same.
Are these executable code different from the code found in “executable files”? Maybe, maybe not. There are certainly some differences.
A 64-bit machine may spend 99.99% of its time executing 64-bit machine code once booted; but during the initial seconds it may have to execute some 32-bit machine code.
Likewise, a fully-loaded OS will execute in privileged mode and the rest of the code execute in user mode. But during bootstrapping most of the code may execute in privileged mode – or rather, in some “simply unprotected” mode, because the CPU mechanism for software fault handling may not have been fully initialized.
Code that needs to execute without the OS, obviously cannot make OS calls. They can still make jumps and subroutine calls to other code – as long as they are located within the same piece of code that is loaded into RAM in one swoop.
This brings up the “size limitation” of bootstrapper code. The previous stage has to know exactly how big is the code size of the next stage. That amount of executable code/data would be brought into RAM before any of it can be executed. In the absence of an OS (and also of any memory-management mechanism), the bootstrapper cannot make subroutine calls located outside what has been brought into RAM – unless if the bootstrapper knows how to load that the extra code.
The BIOS may have to provide a way to facilitate (simplify) the loading of extra data from the storage disk. Performance or security is not the concern – the only concern is simplicity for the caller (which is the bootstrapper). Otherwise, that would be a very tedious task, and would eat up the precious space the bootstrapper code has to fit in.
What formats are used for such bootstrapping code?
These code must follow some kind of conventions in order to work correctly. Whether these conventions qualify as “a format” is a word-play.
For example, the starting offset of the first machine instruction in the bootstrapping code must be specified. Otherwise, how else do you start executing it?
Some bootstrapping code are required to carry a checksum, or even a digital signature (i.e. become digitally signed), to prevent trying to execute a bootstrapper whose data is corrupted, or spoofed or tampered with by malicious intent.
These conventions must be agreed upon by the machine manufacturers, operating systems vendors and/or maintainers, and so on.
1
Back in the stone age of computing, one of the common modes of booting up was to
read an executable program into memory completely under hardware control and then
start running it.
The PDP-10 for example, could command the paper tape reader to read
a block of data, take the data presented and stuff it into memory, and
then start running it when the block was complete. This was used to
read a 16 instruction program which was enough to read more data from
the tape and place it in controlled locations of memory, and eventually
to start the bigger program which could run the console tty, read the
hard disk, and load the operating system.
1
Before an OS is installed on a bare computer system, does the computer use files?
No. At startup some code is copied from an EPROM into memory at a known location and the processor executes those instructions. All it does is load execute instruction at the ‘current’ memory address increment it and repeat forever. The CPU is unaware that a harddisk controller or anything else is even connected let alone do anything useful with any of it – it requires instructions on how to do that and those instructions are usually the lowest layer of an operating system.
does the computer system have the concept of executable files or something similar for storing programs?
With nothing to put files on there is no file system and no file format. Initially everything is loaded from an EPROM into RAM (main memory) and then executed instruction by instruction. So far as the CPU is concerned they’re just an array of bytes.
The BIOS is an example of code that the EPROM contains – it is the code for a (very simple) operating system which does what it needs to (like wake up disk controllers and other peripherals) and look for a another piece of code to run. The same mechanism that boots your system and allows it to operate enough for you to load/install your OS of choice is the one that kickstarts everything time you power up the system.
If you felt that inclined and had the right information about the exact hardware on your motherboard you can write your own EPROM and run code from that. Of course at some point you’d need to reuse functions and as that need increases you’d find yourself writing your own OS and all the headaches that go with it…
3