Hello, in this section, we will build memory manager and set up paging. The memory map is what we have seen before
.
The free memory is normally above 1mb. Our kernel is running at 2mb.
But not all the memory above 1mb is available to use. We need to find out the memory map.
So in the loader file,
we have retrieved the information about memory map and stored it in the address 9000,
We didn’t print the information on the screen since we hadn’t implemented print function back then.
And now we can collect the data and print them on the screen.
Here we make changes. The data we retrieved is stored in the structures. So we stores the count of structures
in address 9000,
We initialize 9000 with value 0 and this value is 4-byte data
And the structures are stored from address 0x9008.
So we move edi 0x9008
each time we get the memory block, we update the count value.
So we increment the value in memory address 0x9000
Then we test ebx, if ebx is 0, it means that we reach the end and we jump to get memory done.
So we use jz instruction, if zero flag is set, we jump to get memory done.
If carry flag is not set after executing int instruction, we will jump to get mem info
to continue retrieving the memory info, otherwise we reach the end and exit out the loop.
So here we use jnc instruction
if carry flag is not set, we jump to get memory info
In the memory.c file, we can get the memory map in the memory location 9000.
Ok we create a header file memory.h
The first structure we define is the structure that we have seen in the loader file.
When we retrieve the memory info using the BIOS service,
the data is actually arranged in the structures.
The first field in the structure is the base address of the memory region. The second field is the length of the memory region.
And the last one is the memory type.
Here we name the structure E820.
Notice that we add attribute packed,
so the structure is stored without padding in it.
Otherwise the structure will be larger than 20 bytes and we will not interpret the data in memory correctly.
OK, the next structure is called free memory region. Because some of memory regions are not available to use
.
So this structure is used to store the information about the free memory.
We have only two fields in it.
The base address and the length of the memory region.
The function initialize memory is referenced in main.c file.
Let’s see the function in the file memory.c.
The free memory region is used to store the information for later use. In this example, we assume that
we get no more than 50 blocks of memory regions. In the function, variable memory map holds the address of the data
retrieved by the BIOS services. The base address is at 0x9008
.
The number of the memory regions is stored at 0x9000.
Each memory region is stored in a e820 structure we just defined. So the variable count indicates how many memory regions we have in the system.
The variable count is 4 bytes,
here we used fixed width data type. Variable free memory region count
is used to store the actual number of free memory regions. Total memory stores the size of
free memory we can use in the system.
Also, for simplicity, we use assert to make the assumption that the number of memory regions is less than 50
.
Then we can parse the e820 structures.
First off, we loop through each of the memory structures and print the base address of memory region,
the size and type of the memory region.
The free memory region we can use is the memory region with type 1.
If the type is 1, we copy the data to the free region structure.
So the variable free region is actually an array of free memory region structure
and variable total memory stores the memory size the operating system can use.
So we added the length to the total memory to update the free memory size.
Then we increment the free region count.
After we exit out for loop, we simply print memory size,
here we covert it to the value in megabytes.
Alright, that's it for the main.c file,
in the main.c file, we include memory.h
and call initialize memory function to initialize the memory.
OK.
we add memory.c file in the build script.
build the project and test it out.
open bochs.
As you see, the first entry and fourth entry are the free memory we can use in the system.
The fourth entry shows that free memory starts 1mb and the size of this region is more than 1000mb
.
The other entries shows the reserved memory and the operating system doesn’t use these memory regions.
The total memory is 1023 mb that is the size of free memory
in this example.