12

I'm just wondering how you create a freestanding program in C++?

Edit: By freestanding I mean a program that doesn't run in a hosted envrioment (eg. OS). I want my program to be the first program the computer loads, instead of the OS.

Bob Dylan
  • 4,293
  • 9
  • 37
  • 57
  • 2
    Define "freestanding." You mean no dependencies on external libraries? For what OS and environment? – Josh Kelley Jan 18 '10 at 22:15
  • Freestanding as in? No operating system? No dynamic libraries? – Yann Ramin Jan 18 '10 at 22:15
  • @Josh Kelley: By "freestanding" I mean a program that is basically the first program loaded on a computer (eg. the OS). I know most people write a boot-strapper in ASM but I was wondering if its possible to do it in C++. – Bob Dylan Jan 18 '10 at 22:16
  • I wouldn't use C++. The runtime is pretty huge to try and pack into a bootloader. You really only have one sector of code loaded for you, and you have to do everything else yourself. – Anon. Jan 18 '10 at 22:30
  • 3
    @Anon: "the" runtime? Not only can you have the static linker strip anything you don't use, but there is no fundamental reason that you need to use the standard library. If you could write it in c (and you can) you can write it in c++. – dmckee --- ex-moderator kitten Jan 18 '10 at 22:33
  • 4
    @JoshKelley: "Freestanding" is actually a very well-defined term, at least by the C language standard. – DevSolar Aug 22 '12 at 12:23

7 Answers7

12

Have a look at this article:

http://www.codeproject.com/KB/tips/boot-loader.aspx

You would need a little assembly start-up code to get you as far as main() but then you could write the rest in C++. You'd have to write your own heap manager (new/delete) if you wanted to create objects at runtime and your own scheduler if you wanted more than one thread.

PhilMY
  • 2,583
  • 20
  • 28
7

See this page: http://wiki.osdev.org/C++

It has everything necessary to start writing an OS using c++ as the core language using the more popular toolchains.

In addition this page should prove to be very helpful: http://wiki.osdev.org/C++_Bare_Bones. It pretty much walks you through getting to the c++ entry point of an OS.

Matt
  • 13,577
  • 6
  • 43
  • 67
Evan Teran
  • 84,149
  • 29
  • 174
  • 237
4

Legacy Systems

Even with your clarification, the answer is that it depends -- the exact boot sequence depends on the hardware -- though there's quite a bit of commonality. The boot loader is typically loaded at an absolute address, and the file it's contained in is frequently read into memory exactly as-is. This means instead of a normal linker, you typically use a "linking locator". Where a typical linker produces an executable file ready for relocation and loading, a locator produces an executable that's already set up to run at one exact address, with all relocations already applied. For those old enough to remember them, it's typically pretty much like an MS-DOS .COM file.

Along with that, it has to (of course) statically link the whole run-time that the program depends upon -- it can't depend on something like a DLL or shared object library, because the code to load either of those hasn't itself been loaded yet.

EFI/UEFI

Current PCs (and Macs) use EFI/UEFI. I'm going to just refer to UEFI throughout the remainder of this article, but most of it applies about equally to EFI as well (but UEFI is much more common).

These provide quite a bit more support for boot code. This includes drivers for most devices (it supports installing device drivers), so your boot code can use networking and such, which is much more difficult to support in legacy mode.

Bootable code under EFI uses the same PE format as Windows executables. Libraries are also available so quite a bit of boot code can be written much more like normal code that runs inside an OS. I won't try to get into a lot of detail, but here are links to some information.

https://www.intel.com/content/www/us/en/developer/articles/tool/unified-extensible-firmware-interface.html

https://www.intel.com/content/dam/doc/guide/uefi-driver-network-boot-devices-guide.pdf

https://www.intel.com/content/dam/www/public/us/en/documents/guides/bldk-v2-uefi-standard-based-guide.pdf

And perhaps the most important one--the development kit:

https://github.com/tianocore/edk2

Jerry Coffin
  • 455,417
  • 76
  • 598
  • 1,067
2

google 'embedded c++' for a start

Another idea is to start with the embedded systems emulators, for example the atmel AVR site has a nice IDE the emulates atmel AVR systems, and allows you to build raw code in C and load it into an emulated CPU, they use gcc as toolchain (I think)

pm100
  • 42,706
  • 22
  • 76
  • 135
2

C++ is used in embedded systems programming, even to write OS kernels.

Usually you have at least a few assembler instructions early in the boot sequence. A few things are just easier to express that way, or there may be reference code from the CPU vendor you need to use.

For the initial boot process, you won't be able to use the standard library. No exceptions, RTII, new/delete. It's back to "C with classes". Most people just use C here.

Once you have enough supporting infrastructure loaded though, you can use whatever parts of the standard library you can port.

Marsh Ray
  • 2,787
  • 20
  • 20
2

You will need an environment that provides:

  • A working C library, or enough of it to do what you want
  • The parts of the C++ runtime that you intend to use. This is compiler-specific

In addition to any other libraries. If you have no dynamic linker on your platform (if you have no OS, you probably have no linker) then you will have to static-link it all.

In practice this means linking some small C++ runtime, and a C library appropriate for your platform. Then you can simply write a standalone C++ program.

MarkR
  • 61,128
  • 14
  • 112
  • 147
1

If you were using BSD Unix, you would link with the standalone library. That included a basic IO system for disk and tty. Your source code looked the same as if it were to be run under Unix, but the binary could be loaded into a naked machine.

gary
  • 564
  • 3
  • 12