Creating a very simple bootloader

Hi Guys,

I'm following along with - https://www.cs.bham.ac.uk/~exr/lectures/opsys/10_11/lectures/os-dev.pdf

this tutorial/pdf outlines how to make a very simple and basic operating system, I'm trying to make a disc image file but to no avail

so when a computer starts the bios searches it's persistent memory devices for a boot sector which will usually be the first sector on a drive, like the tutorial specifies I created an iso file with a hexeditor , made it 512 bytes in length and ended it with the magic number to identify it as a boot loader.

all this simple file will do is constantly loop and show a black screen

I've run into a problem though, I'm trying to set it up on virtual box but when I select the iso file it tells me failed to open disk image file,

how would I go about setting the virtual machine to read my boot loader, the tutorial says it can be done with virtual box but can't seem a way to set it


Use virtual machine software, such as VMWare or VirtualBox, and set the boot
block code as a disk image of a virtual machine, then start-up the virtual machine.


I'm not sure where in virtualbox I can do this, I know where to do this

this is the contents of the file - https://ibb.co/nRxZC1R

and settings of my vm - https://ibb.co/Sd54XSq
- https://ibb.co/6t5LczN

thanks
Last edited on
like the tutorial specifies I created an iso file with a hexeditor , made it 512 bytes in length and ended it with the magic number to identify it as a boot loader.
That's not what the document says and that's not an ISO. What you did there is write to a file a simplistic boot sector. You need to copy it to a disk image in a format that the hypervisor can understand. VirtualBox has a utility that can convert flat images to VDIs (VirtualBox's own virtual disk format).
so would when saving the simple boot sector I wouldn't save it as .ISO, I'm guessing I would save it as .bin?

and as mentioned then I would convert that flat image ( maybe a .bin file?) to a VDI
It's a formatless file. You can give it whatever name you want.
I used the VBoxManage utility with convertfromraw as an argument along with the input and output file , input obviously being the bootsector.bin, but when I try to convert I get an error

VBoxManage.exe: error: Cannot create the disk image "output.vdi": VERR_VD_INVALID_SIZE

the bootsector.bin (bt.bin) is 512 bytes in size.


properties of the bin file - https://ibb.co/qRx0Rn6
You'll need to pad it to a larger size. Try 32 MiB.
Last edited on
I'll give that a try,

is there an option to pad it with VBoxManage? or do I have to just add 32 bytes to the bin file with a hex editor?

Just write a short program to pad the file. It should take like five minutes. Hell, here you go:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <fstream>
#include <vector>
#include <cstdint>

int main(int argc, char **argv){
    if (argc < 2)
        return -1;
    std::vector<std::uint8_t> data;
    {
        std::ifstream file(argv[1], std::ios::binary);
        if (!file)
            return -1;
        file.seekg(0, std::ios::end);
        data.resize(file.tellg());
        if (data.size()){
            file.seekg(0);
            file.read((char *)&data[0], data.size());
        }
    }
    data.resize(32 << 20);
    {
        std::ofstream file(argv[1], std::ios::binary);
        file.write((const char *)&data[0], data.size());
    }
    return 0;
}
Last edited on
Sorry about the 101 questions, thanks for sticking with me :)

I've got a couple of questions

so first off, the program worked as intended it padded my bin file :) and also good news the VBoxManage utility accepted and converted it but... I must be still doing something wrong, maybe I have the wrong settings, I set the hardisk to the output.vdi file from my bin file,

and I get the following error - https://ibb.co/Sd54XSq

and the more detailed error which is probably more important ( says wrong permissions ? )- https://ibb.co/DzKGLS3

here are my settings - https://ibb.co/6t5LczN

I was expecting a constant black screen to be displayed, but instead get an error as the image shows, failed to open a virtual machine session for boot



********* edit I ran VirtualBox as admin and it seems to work !! :) ( I think ), I'm guessing that the vdi file is read only when not running as admin?

anyway so what happens is indeed a black screen is just constantly showing, with a cursor,

does this look right to you? - https://www.youtube.com/watch?v=332I_fELo3o

sorry about getting so nuanced but what is with the blinking cursor? I thought a black screen would just appear

__________________________________________________________________________________________

the final questions relate to the actual program itself,

first off why does the bin file need to be padded before it can be converted? why isn't 512 bytes sufficient?

now onto the program I understand most of it but a few things I'm not concrete on

so file will take the arguments of the file was passed in, file will be in binary mode, we then resize the vector to the size of file,

I'm guessing file.read((char *)&data[0], data.size()); will read in and place the data from inside the file into the data vector?

the next line kind of confuses me, we again resize the vector with data.resize(32 << 20); why do we left bit shift 32 by 20??

and how does this pad the file with zeros? we didn't explicitly say we want to fill the rest of data with zeros, so all values from data.at(file.tellg()) and upwards to data.resize(32 << 20) will be 0?

1
2
3

std::ofstream file(argv[1], std::ios::binary);
 file.write((const char *)&data[0], data.size());


this will just write the data from the vector to the file right?

* also that's a pretty neat little program :)
Last edited on
and I get the following error - https://ibb.co/Sd54XSq

and the more detailed error which is probably more important ( says wrong permissions ? )- https://ibb.co/DzKGLS3
Those are two very different errors. On one you're trying to attach an "ISO" file and on the other you're trying to attach a VDI that's located on Program Files, which obviously by default non-administrators will not be able to write to.

sorry about getting so nuanced but what is with the blinking cursor? I thought a black screen would just appear
x86 machines start in text mode. In text mode there's no such thing as a pure black screen. The current position of the cursor is always displayed.

first off why does the bin file need to be padded before it can be converted? why isn't 512 bytes sufficient?
There's presumably no real reason, but have you ever seen a 512-byte disk?

why do we left bit shift 32 by 20?
It's a quick and easy way to write "32 megabytes". Likewise, 32ULL << 30ULL is 32 gigabytes, and 32 << 10 is 32 kilobytes.

so all values from data.at(file.tellg()) and upwards to data.resize(32 << 20) will be 0?
Yes. This is a specified behavior of std::vector.
so all values from data.at(file.tellg()) and upwards to data.resize(32 << 20) will be 0?
Yes. This is a specified behavior of std::vector.


so let's say we wanted to pad it so each byte would be 0xFF, would we have to loop through the whole array and manually set each of our padded bytes to 0xFF?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

#include <fstream>
#include <vector>
#include <cstdint>

int main(int argc, char **argv){
    if (argc < 2)
        return -1;
    std::vector<std::uint8_t> data;
    int sz;
    {
        std::ifstream file(argv[1], std::ios::binary);
        if (!file)
            return -1;
        file.seekg(0, std::ios::end);
        data.resize(file.tellg());
        sz = file.tellg();
        if (data.size()){
            file.seekg(0);
            file.read((char *)&data[0], data.size());
        }
    }
    data.resize(32 << 20);
    for(int i = sz; i < (32 << 20); ++i)
        data.at(i) = 0xFF;
    {
        std::ofstream file(argv[1], std::ios::binary);
        file.write((const char *)&data[0], data.size());
    }

}


that works but it's quite expensive


first off why does the bin file need to be padded before it can be converted? why isn't 512 bytes sufficient?
There's presumably no real reason, but have you ever seen a 512-byte disk?


Very true, so it was just intuition that you chose 32? what if say we chose 16 or let's say a number that has to have multiple 1 bits set like 26 would it still work?

Last edited on
so let's say we wanted to pad it so each byte would be oxFF, would we have to loop through the whole array and manually set each of our padded bytes to oxFF?
std::vector<T>::resize() accepts an optional second parameter, which is the value to fill the new elements with. If the parameter is not provided, it defaults to T().
I recommend that you get comfortable with reading the reference.
http://www.cplusplus.com/reference/vector/vector/resize/

Very true, so it was just intuition that you chose 32? what if say we chose 16 or let's say a number that has to have multiple 1 bits set like 26 would it still work?
I guessed. Feel free to try and find the smallest size that VBoxManage will accept.
Thanks Helios :)

I actually tried adding the optional "0XFF" didn't seem to work but worked this time, very strange I don't know what I did wrong,

I think I vaguely remember reading about the optional argument to resize() in Bjarne's practices and principles.

Last edited on
Topic archived. No new replies allowed.