70

As I understand, the BIOS code/bitstream that is held in the ROM should be generic (work alongside with multiple CPU types or ISAs). In addition, I saw mentioned on the web that it is possible to dump its code (and to "disassemble" it).

So, in which language, instruction set or machine code is it written? Doesn't it need any kind of processor to perform its operations? If so, I guess that it will use the external CPU, then how does it know the specific instruction set of the employed one?

Maybe it has an internal processor?

7
  • 9
    possible duplicate of How Do Computers Work?
    – gnat
    Commented Sep 30, 2015 at 13:25
  • 39
    Cross posting is bad enough, but when it ends up on the Hot Network Questions in both versions, that's just beyond the pale... Commented Sep 30, 2015 at 15:45
  • 9
    "BIOS code/bitstream that held in the ROM should be generic (work alongside with multiple CPU types or ISAs)." -- I never heard of a BIOS that works with multiple ISAs. Do you have an example?
    – chx
    Commented Sep 30, 2015 at 16:02
  • 6
    As I understand, the BIOS code/bitstream that is held in the ROM should be generic (work alongside with multiple CPU types or ISAs). I'd say "No, just the contrary"
    – edc65
    Commented Sep 30, 2015 at 17:59
  • 11
    This is not even remotely a duplicate of a question as general as "How Do Computers Work?". Please do not close as dupe.
    – Andres F.
    Commented Sep 30, 2015 at 19:56

3 Answers 3

107

BIOSes used to be written exclusively in assembly language, but the transition was made a long time ago to write the majority of the code in some higher level language, and leave written in assembly as few portions of it as possible, preferably only the bootstrapper, (the very first few hundreds of instructions that the CPU jumps to after a start / reset,) and whatever routines deal with specific quirks of the underlying architecture.

BIOSes were already being written primarily in C as early as the early nineties. (I wrote a BIOS in 90% C, 10% assembly in the early nineties.)

What has also helped greatly in this direction is:

  • C libraries that target a specific architecture and include functions for dealing with peculiarities of that architecture, for example, functions for reading/writing bytes to/from I/O ports of the x86 architecture. Microsoft C has always offered library functions for that kind of stuff.

  • C compilers that not only target a specific CPU architecture but even offer extensions to the C language that you can use in order to write code which makes use of special CPU features. For example, the x86 architecture supports things known as interrupts, which invoke routines known as interrupt handlers, and it requires them to have special entry/exit instruction sequences. From the very early days, Microsoft C supported special keywords that you could use to mark a function as an interrupt handler, so it could be invoked directly by a CPU interrupt, so you did not have to write any assembly for it.

Nowadays I would assume that most of the BIOS is written in C++, if not in any higher level language.

The vast majority of the code that makes up a BIOS is specific to the underlying hardware, so it does not really need to be portable: it is guaranteed that it will always run on the same type of CPU. The CPU may evolve, but as long as it maintains backwards compatibility with previous versions, it can still run the BIOS unmodified. Plus, you can always recompile the parts of the BIOS written in C to run natively on any new CPU that comes up, if the need arises.

The reason why we write BIOSes in languages of a higher level than assembly is because it is easier to write them this way, not because they really need to be portable.

39
  • 7
    Yes. Sometimes you may even have a motherboard bound not only to a specific CPU architecture, but even to a specific CPU vendor. Nowadays you can buy an x86 motherboard which is only compatible with Intel x86 CPUs, or an x86 motherboard which is only compatible with AMD x86 CPUs. The BIOS in these motherboards will be identical to a large degree, because in both cases the CPU understands the x86 instruction set, and most of the peripherals are identical, but some peripherals have differences, that the BIOS must account for.
    – Mike Nakis
    Commented Sep 30, 2015 at 12:52
  • 4
    @Reflection take a close look at what a motherboard physically looks like. The CPU socket will have a certain pin arrangement, which is specific to the family of CPUs it accepts. You physically cannot connect say an Intel P4 to an AMD Opteron motherboard
    – Caleth
    Commented Sep 30, 2015 at 13:45
  • 14
    The term "BIOS" refers to the "Basic Input/Output System" of a PC, so, having a BIOS implies an x86 CPU. IA64 systems have an EFI instead of a BIOS, PowerPC systems may have an Open Firmware system or a proprietary one, Sparc systems also have OFW (or rather OpenBoot), the OLPC X0 is an x86-based system that uses OFW. Even PCs don't use BIOS anymore, they have switched to (U)EFI. OB/OFW is interesting, because it is designed to not only be portable but cross-platform. OFW drivers will work on any OFW system, they are "Write Once Run Anywhere", regardless of CPU ISA. Commented Sep 30, 2015 at 14:05
  • 14
    "Nowadays I would assume that most of the BIOS is written in C++" I wouldn't necessarily assume that, It might be true but I work in that industry and certainly many boot loaders are written in plain C. The people who write that kind of stuff are often the "Old Guard" and tend not to fully trust C++ still.
    – Sam
    Commented Sep 30, 2015 at 15:52
  • 6
    @TomDworzanski: While technically not BIOS (which refers exclusively to the old 1981 PC-stuff), many implementations of IEEE-1275 Open Firmware (which is used for a similar role as the BIOS on Sparc, the PowerPC Common Hardware Reference Platform (e.g. PowerMac, PowerBook), the 100$ laptop OLPC X0-1) are written partly in languages other than assembly/C. OpenBoot, Open Firmware, OpenBIOS all contain … Commented Sep 30, 2015 at 20:22
12

While in theory one can write BIOS in any language, the modern reality is most BIOS is written using Assembly, C, or a combination of the two.

BIOS must be written in a language that can compile to machine code, that is understood by the physical hardware-machine. This eliminates the directly or intermediate-ly interpreted languages (Perl, Python, PHP, Ruby, Java, C#, JavaScript, etc) as being appropriate for writing BIOS. (Though, in theory, one could implement one of these languages to either compile directly to static machine code or one could somehow embed the interpreter in BIOS. There is, for-example, the abandonware GCJ project for Java.)

Most OEMs implement a BIOS by extending proprietary, generic BIOS implementations by companies like American Megatrends and Phoenix Techologies. (You've probably seen one of those companies displayed on the first boot screen of a computer before.) The source code for these implementations is not publicly available, but some of it has been leaked. I do not want to link to this directly to the C and assembly source code, but there are places on the Internet where this source code is discussed for those who care to peek.

Some hardware manufacturers, like those targeting the high-performance and gaming markets, saturate their BIOS implementations with customization features, statistics, and attractive user interfaces designed for their exact implementations. Many of these features go beyond what is offered in the generic products produced by American Megatrends and others. Unfortunately, these companies often see the release of their source code as a security risk, so little is known about these high-end implementations because little is shared about them. One could of course find ways to access and de-compile such BIOS implementations but doing so may be difficult and possibly illegal.

Going back to the original question, because of the need to produce native machine code, a BIOS would have to be implemented in a programming language supported by a native machine code compiler. While there are many such languages and while I'm sure over the last few decades, several languages have been used in experimentation, every open BIOS implementation I have been able to find specifically relies on a combination of C and/or assembly. The open-sourced BIOS implementations I looked at to form this conclusion include OpenBIOS, tinyBIOS, coreboot, Intel BIOS, and Libreboot. I also looked at some very old BIOS implementations that are not relevant today but also followed the C and/or assembly rule.

I think it's also relevant to look at other software built to interact directly with hardware. We know, for example, that the Linux Kernel, the OS X kernel, and the Windows kernel are largely C with some assembly and some higher level languages for specific tasks. We also know that hardware drivers on Linux and hardware drivers on Windows are written largely in C.

Getting back to BIOS, I think it's also important to consider the economics of the programming language chosen. BIOS is generally written as a necessity to complement hardware sales. Modern BIOS systems are known to be largely written in C and/or assembly. A move to some other tool would add significant costs to what are generally considered to be commodity products which could very adversely affect sales. Without getting into Economics 101, I can assure you that it's probably not worth it to an OEM to deviate from tried-and-true tools that have been proven over decades.

Of course there are and will be hobbyist projects to write BIOS as well. These too, thus far, seem to be choosing C and/or assembly. Perhaps one day other technologies will be used. But today, the choice of is well-defined.

5
  • 4
    It is a little bit of nit-picking but C# and Java are not interpreted. They compile to byte-code. It is the byte-code that is then handled by an interpreter. Doesn't change the logic of the first paragraph.
    – Tonny
    Commented Oct 1, 2015 at 9:33
  • 1
    @Tonny That's correct. I added "directly or intermediate-ly interpreted" to be a little more clear.
    – user91878
    Commented Oct 1, 2015 at 9:35
  • @Tonny normally a jitter rather than an interpreter, which is an important distinction because it's possible to pre-jit it all to native as long as certain dynamic techniques aren't used. As such it would be just about theoretically possible to write a BIOS in .NET languages or Java, if one did both that and made sure all runtime-support needed was available. I imagine the efforts of doing that would more than dwarf any convenience found though.
    – Jon Hanna
    Commented Oct 1, 2015 at 12:19
  • 1
    @Tonny Actually C# compiles to native code msdn.microsoft.com/en-us/vstudio/dotnetnative.aspx so it's weird to see it in the list of weak/dynamic languages.
    – Den
    Commented Oct 6, 2015 at 14:23
  • @Den C# is not typically compiled to native code. This .Net Native product to which you link has not yet been officially released. From what I've read, it will compile the application code and the required framework code into an executable. According to the FAQ, this will be targeted at Windows Store apps initially, so it may take some time for this to be supported more widely. All that being said, it does seem like Microsoft may move away from the virtual machine model some time in the future if all goes well.
    – user91878
    Commented Oct 6, 2015 at 20:15
4

The actual BIOS for a computer would be written in some language (probably C or assembly) that is compiled to architecture dependent binary code; this code can't run on any other architecture (and arguably doesn't really need to, as it is already very specific to the machine with which it is shipped).

But are you possibly thinking about Option ROMs (which are sometimes called BIOSes, as in "Video BIOS" for a GPU option ROM)?

For actual, legacy BIOS compatible option ROMs, they would probably be ISA dependent executable code (again generated by any language that can be compiled to target the desired architecture); PCI also allows including code for multiple ISAs and allows the host to select the appropriate binary image during the boot process.

For UEFI compatible option ROMs, there is also an architecture-independent byte code format that can be run on different architectures, but ISA-dependent code can also still be used.

Not the answer you're looking for? Browse other questions tagged or ask your own question.