1 00:00:00,510 --> 00:00:06,689 Hello, in this section, we will build memory manager and set up paging. The memory map is what we have seen before 2 00:00:06,689 --> 00:00:07,620 . 3 00:00:08,039 --> 00:00:14,910 The free memory is normally above 1mb. Our kernel is running at 2mb. 4 00:00:14,910 --> 00:00:19,800 But not all the memory above 1mb is available to use. We need to find out the memory map. 5 00:00:21,740 --> 00:00:23,120 So in the loader file, 6 00:00:27,860 --> 00:00:35,020 we have retrieved the information about memory map and stored it in the address 9000, 7 00:00:35,160 --> 00:00:40,970 We didn’t print the information on the screen since we hadn’t implemented print function back then. 8 00:00:40,970 --> 00:00:42,890 And now we can collect the data and print them on the screen. 9 00:00:44,020 --> 00:00:50,850 Here we make changes. The data we retrieved is stored in the structures. So we stores the count of structures 10 00:00:50,860 --> 00:00:53,620 in address 9000, 11 00:00:54,980 --> 00:01:00,440 We initialize 9000 with value 0 and this value is 4-byte data 12 00:01:02,050 --> 00:01:05,890 And the structures are stored from address 0x9008. 13 00:01:07,900 --> 00:01:10,570 So we move edi 0x9008 14 00:01:12,280 --> 00:01:16,030 each time we get the memory block, we update the count value. 15 00:01:18,510 --> 00:01:24,570 So we increment the value in memory address 0x9000 16 00:01:26,970 --> 00:01:33,770 Then we test ebx, if ebx is 0, it means that we reach the end and we jump to get memory done. 17 00:01:34,740 --> 00:01:40,170 So we use jz instruction, if zero flag is set, we jump to get memory done. 18 00:01:43,070 --> 00:01:49,880 If carry flag is not set after executing int instruction, we will jump to get mem info 19 00:01:49,910 --> 00:01:54,710 to continue retrieving the memory info, otherwise we reach the end and exit out the loop. 20 00:01:55,460 --> 00:01:56,630 So here we use jnc instruction 21 00:01:57,830 --> 00:02:03,320 if carry flag is not set, we jump to get memory info 22 00:02:06,780 --> 00:02:11,640 In the memory.c file, we can get the memory map in the memory location 9000. 23 00:02:14,460 --> 00:02:17,310 Ok we create a header file memory.h 24 00:02:20,910 --> 00:02:26,510 The first structure we define is the structure that we have seen in the loader file. 25 00:02:26,970 --> 00:02:29,900 When we retrieve the memory info using the BIOS service, 26 00:02:30,180 --> 00:02:32,640 the data is actually arranged in the structures. 27 00:02:34,150 --> 00:02:39,850 The first field in the structure is the base address of the memory region. The second field is the length of the memory region. 28 00:02:39,850 --> 00:02:42,970 And the last one is the memory type. 29 00:02:43,720 --> 00:02:46,060 Here we name the structure E820. 30 00:02:46,570 --> 00:02:49,170 Notice that we add attribute packed, 31 00:02:49,630 --> 00:02:51,970 so the structure is stored without padding in it. 32 00:02:52,420 --> 00:02:58,200 Otherwise the structure will be larger than 20 bytes and we will not interpret the data in memory correctly. 33 00:03:00,090 --> 00:03:05,880 OK, the next structure is called free memory region. Because some of memory regions are not available to use 34 00:03:05,880 --> 00:03:06,370 . 35 00:03:06,540 --> 00:03:10,280 So this structure is used to store the information about the free memory. 36 00:03:11,100 --> 00:03:12,730 We have only two fields in it. 37 00:03:13,030 --> 00:03:15,750 The base address and the length of the memory region. 38 00:03:17,430 --> 00:03:21,480 The function initialize memory is referenced in main.c file. 39 00:03:23,390 --> 00:03:26,300 Let’s see the function in the file memory.c. 40 00:03:27,860 --> 00:03:34,730 The free memory region is used to store the information for later use. In this example, we assume that 41 00:03:34,730 --> 00:03:41,450 we get no more than 50 blocks of memory regions. In the function, variable memory map holds the address of the data 42 00:03:41,450 --> 00:03:45,560 retrieved by the BIOS services. The base address is at 0x9008 43 00:03:45,920 --> 00:03:47,300 . 44 00:03:47,910 --> 00:03:52,640 The number of the memory regions is stored at 0x9000. 45 00:03:53,950 --> 00:04:01,550 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. 46 00:04:01,570 --> 00:04:05,830 The variable count is 4 bytes, 47 00:04:05,830 --> 00:04:09,910 here we used fixed width data type. Variable free memory region count 48 00:04:09,950 --> 00:04:16,540 is used to store the actual number of free memory regions. Total memory stores the size of 49 00:04:16,540 --> 00:04:18,459 free memory we can use in the system. 50 00:04:20,250 --> 00:04:26,010 Also, for simplicity, we use assert to make the assumption that the number of memory regions is less than 50 51 00:04:26,010 --> 00:04:27,020 . 52 00:04:28,710 --> 00:04:31,650 Then we can parse the e820 structures. 53 00:04:33,910 --> 00:04:39,160 First off, we loop through each of the memory structures and print the base address of memory region, 54 00:04:39,550 --> 00:04:41,740 the size and type of the memory region. 55 00:04:42,970 --> 00:04:46,660 The free memory region we can use is the memory region with type 1. 56 00:04:48,870 --> 00:04:52,200 If the type is 1, we copy the data to the free region structure. 57 00:04:53,780 --> 00:05:00,420 So the variable free region is actually an array of free memory region structure 58 00:05:00,450 --> 00:05:03,200 and variable total memory stores the memory size the operating system can use. 59 00:05:04,580 --> 00:05:09,050 So we added the length to the total memory to update the free memory size. 60 00:05:09,980 --> 00:05:12,170 Then we increment the free region count. 61 00:05:13,100 --> 00:05:16,550 After we exit out for loop, we simply print memory size, 62 00:05:17,680 --> 00:05:20,260 here we covert it to the value in megabytes. 63 00:05:21,190 --> 00:05:23,770 Alright, that's it for the main.c file, 64 00:05:24,930 --> 00:05:29,160 in the main.c file, we include memory.h 65 00:05:30,050 --> 00:05:33,350 and call initialize memory function to initialize the memory. 66 00:05:35,050 --> 00:05:35,510 OK. 67 00:05:35,710 --> 00:05:38,260 we add memory.c file in the build script. 68 00:05:39,890 --> 00:05:41,690 build the project and test it out. 69 00:05:44,120 --> 00:05:45,050 open bochs. 70 00:05:50,030 --> 00:05:56,060 As you see, the first entry and fourth entry are the free memory we can use in the system. 71 00:05:56,060 --> 00:06:01,580 The fourth entry shows that free memory starts 1mb and the size of this region is more than 1000mb 72 00:06:01,580 --> 00:06:02,720 . 73 00:06:03,660 --> 00:06:09,180 The other entries shows the reserved memory and the operating system doesn’t use these memory regions. 74 00:06:10,140 --> 00:06:16,050 The total memory is 1023 mb that is the size of free memory 75 00:06:16,060 --> 00:06:17,010 in this example.