1 00:00:00,330 --> 00:00:08,160 Hello, in this lecture we will wrap up this section by writing setup uvm function. The setup uvm function, 2 00:00:08,160 --> 00:00:10,560 as opposed to setup kvm function, 3 00:00:10,950 --> 00:00:15,980 will create a virtual space for user applications. In the system, 4 00:00:16,000 --> 00:00:20,730 the base of the virtual memory for user space is 400000. 5 00:00:21,770 --> 00:00:28,430 And we map only one page for the user programs which means the code, data and stack of the programs 6 00:00:28,430 --> 00:00:30,710 are located in the same 2m page. 7 00:00:32,210 --> 00:00:33,440 OK, let's get started. 8 00:00:35,060 --> 00:00:36,830 We opened the memory.c file. 9 00:00:42,980 --> 00:00:44,750 The setup uvm function 10 00:00:46,700 --> 00:00:50,120 returns Boolean value to tell us the status of the operation. 11 00:00:53,910 --> 00:00:58,650 It takes three parameters, the address of page map level 4 table, 12 00:01:02,220 --> 00:01:03,720 the location of the program. 13 00:01:06,430 --> 00:01:11,380 After we allocate a page and map virtual address 400000 to this page, 14 00:01:11,380 --> 00:01:17,890 we will copy the program instructions and data to it. The last parameter specifies the size of the data we need to copy 15 00:01:17,890 --> 00:01:18,570 . 16 00:01:21,490 --> 00:01:26,140 In the function, the first thing we will do in the function is define a variable status 17 00:01:27,760 --> 00:01:29,950 and initialize it with false. 18 00:01:32,710 --> 00:01:38,470 Then we allocate a page which is used to store the code and data of the program. So we call function kalloc 19 00:01:38,470 --> 00:01:38,980 . 20 00:01:43,550 --> 00:01:45,710 If we allocate a page successfully, 21 00:01:49,760 --> 00:01:56,140 we will zero the page using function memset because it could include random values. 22 00:02:00,120 --> 00:02:04,980 The next thing we are going to do is we are going to map the page using map pages. 23 00:02:06,500 --> 00:02:07,770 We have seen it before. 24 00:02:07,830 --> 00:02:13,810 The first argument we pass to it is the address of pml4 table. We pass map to it 25 00:02:13,820 --> 00:02:18,840 in this case, the next two arguments are the start and end address of the virtual space we want map, 26 00:02:18,860 --> 00:02:22,220 400000 in this case. 27 00:02:25,140 --> 00:02:30,180 Because we implement only one page for user application, we add page size 28 00:02:32,720 --> 00:02:33,830 to the base address. 29 00:02:38,800 --> 00:02:41,090 Next one is the base of the physical page we want to map into 30 00:02:41,110 --> 00:02:49,170 which is the page we allocate. We use macro v2p to convert the virtual address 31 00:02:49,210 --> 00:02:50,320 to physical address. 32 00:02:53,040 --> 00:03:01,200 The last one stores the attributes of the page. So we pass attribute present, writable 33 00:03:02,890 --> 00:03:04,540 the last one is user 34 00:03:05,670 --> 00:03:11,910 In this example, the page is used for the user program. So we add pte user in the attributes. 35 00:03:13,380 --> 00:03:16,800 After the function returns, we check the status, 36 00:03:18,200 --> 00:03:19,280 if it succeeds, 37 00:03:23,040 --> 00:03:28,560 we just copy the data to the page. The function we use is memcpy. 38 00:03:30,270 --> 00:03:33,820 The first argument is the page to which we copy the data, 39 00:03:34,590 --> 00:03:36,510 next one is the address of the data. 40 00:03:39,670 --> 00:03:40,990 So we pass start. 41 00:03:42,200 --> 00:03:44,790 The last one is the size of the data we want to copy. 42 00:03:48,830 --> 00:03:56,150 If the status is false, we will free the page as well as translation tables. So here we use 43 00:03:56,150 --> 00:03:57,110 free vm. 44 00:04:00,050 --> 00:04:03,740 And we pass the address of pml4 table to this function. 45 00:04:05,230 --> 00:04:08,680 In the last lecture, we commented out the free pages function. 46 00:04:12,040 --> 00:04:14,140 Now we can use it to free the VM. 47 00:04:16,750 --> 00:04:22,600 The base of the virtual space for user program is 400000 in the system 48 00:04:25,710 --> 00:04:29,250 and the end of the space is 400000 49 00:04:32,650 --> 00:04:36,910 plus page size. So what it does is just free one page. 50 00:04:38,260 --> 00:04:44,380 The next three functions will free the page translation tables. Note that we only free the translation tables and user pages. 51 00:04:44,380 --> 00:04:50,980 The kernel pages where our kernel resides are not freed, because in our system, 52 00:04:50,980 --> 00:04:56,730 we can have multiple vms and each vm is mapped to the same kernel pages, 53 00:04:57,250 --> 00:05:00,600 the kernel is residing in the memory until we shut down the system. 54 00:05:01,060 --> 00:05:03,150 Therefore, when we free a vm, 55 00:05:03,400 --> 00:05:07,930 we will not free the kernel page because the kernel page is shared among all the vms. 56 00:05:09,090 --> 00:05:12,090 Ok, at the end of setup uvm function, 57 00:05:14,960 --> 00:05:16,190 we return the status. 58 00:05:18,580 --> 00:05:23,290 This function is used in other modules, so we add the declaration in the header file. 59 00:05:31,090 --> 00:05:35,410 Alright, we have setup uvm and free vm functions ready to use. 60 00:05:36,390 --> 00:05:43,220 Before we wrap up this section, let’s focus on setup kvm function. In the next section, we will implement processes. 61 00:05:43,230 --> 00:05:50,220 Each process has its own address space, any changes in one address space will not affect other address spaces 62 00:05:50,290 --> 00:05:51,360 . 63 00:05:51,730 --> 00:05:56,730 So in the system, we setup kernel space and user space for each process. 64 00:05:57,790 --> 00:06:02,980 The setup kvm function will be called in the process module. So we add the declaration in the header file. 65 00:06:02,980 --> 00:06:09,200 It returns the address of pml4 table which is used when we switch vm. 66 00:06:16,460 --> 00:06:20,090 In the function, we define a variable to save the address of the new page 67 00:06:21,680 --> 00:06:23,300 we still use the name page map 68 00:06:24,960 --> 00:06:27,660 and we allow the allocation fails in this case. 69 00:06:28,620 --> 00:06:32,580 So we use if statement to check the return value instead of assert. 70 00:06:40,380 --> 00:06:44,100 If the page is valid, we zero the page just as we did before. 71 00:06:45,880 --> 00:06:51,520 In this example, we don’t assume the status of the map pages either. Instead, we check the return value 72 00:06:51,520 --> 00:06:52,210 , 73 00:06:56,750 --> 00:06:59,390 if the operation fails, we just free the vm 74 00:07:04,720 --> 00:07:07,540 and save the value 0 to variable map. 75 00:07:08,940 --> 00:07:12,390 The last thing we will do is return the address of pml4 table. 76 00:07:14,900 --> 00:07:21,290 Another thing we need to do after we use free vm in the if statement is that in function 77 00:07:24,850 --> 00:07:25,810 free pages, 78 00:07:26,950 --> 00:07:31,210 we used assert to check the present bit of the page directory entry. 79 00:07:32,380 --> 00:07:39,200 At this point, we allow the page not present which means if the present bit is cleared, 80 00:07:39,200 --> 00:07:41,320 we just skip this part and continue the loop. 81 00:07:43,430 --> 00:07:46,040 In the initialize kvm function, 82 00:07:47,900 --> 00:07:52,720 we will save the return value of function setup kvm to the variable page map. 83 00:07:54,420 --> 00:07:56,970 And in this case, we don’t need global variable. 84 00:08:09,390 --> 00:08:10,350 Then we assert 85 00:08:12,970 --> 00:08:13,720 page map 86 00:08:15,770 --> 00:08:22,340 is allocated successfully, because we are now at the kernel initialization stage. If the operation fails 87 00:08:22,340 --> 00:08:22,740 , 88 00:08:22,760 --> 00:08:23,750 we stop the system. 89 00:08:25,230 --> 00:08:32,080 It’s worth mentioning that in the setup uvm function, we just map one page. 90 00:08:32,220 --> 00:08:38,909 So if the operation fails, it means that the mapping is not done. When we call free vm function, 91 00:08:38,970 --> 00:08:40,590 this page will not be freed. 92 00:08:41,370 --> 00:08:43,770 Therefore, we have to free the page manually, 93 00:08:44,220 --> 00:08:46,140 otherwise we will have memory leak. 94 00:08:48,330 --> 00:08:54,800 Ok. When I test it on the real machine with more than 1g of ram, the assertion fails 95 00:08:54,930 --> 00:08:56,460 at kfree function. 96 00:08:58,880 --> 00:09:05,530 It turns out we have a typo in the free region function. The v here should be start. 97 00:09:05,930 --> 00:09:06,680 So we change v 98 00:09:06,680 --> 00:09:08,120 to start. 99 00:09:10,520 --> 00:09:16,640 Ok, that’s it. In the next section, we will use these functions to build the process module. 100 00:09:16,640 --> 00:09:17,630 See you in the next section.