UbixOS  2.0
createvirtualspace.c
Go to the documentation of this file.
1 /*-
2  * Copyright (c) 2002-2018 The UbixOS Project.
3  * All rights reserved.
4  *
5  * This was developed by Christopher W. Olsen for the UbixOS Project.
6  *
7  * Redistribution and use in source and binary forms, with or without modification, are permitted
8  * provided that the following conditions are met:
9  *
10  * 1) Redistributions of source code must retain the above copyright notice, this list of
11  * conditions, the following disclaimer and the list of authors.
12  * 2) Redistributions in binary form must reproduce the above copyright notice, this list of
13  * conditions, the following disclaimer and the list of authors in the documentation and/or
14  * other materials provided with the distribution.
15  * 3) Neither the name of the UbixOS Project nor the names of its contributors may be used to
16  * endorse or promote products derived from this software without specific prior written
17  * permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
20  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
22  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <vmm/vmm.h>
30 
31 /************************************************************************
32 
33  Function: void *vmm_createVirtualSpace(pid_t);
34  Description: Creates A Virtual Space For A New Task
35  Notes:
36 
37  07/30/02 - This Is Going To Create A New VM Space However Its Going To
38  Share The Same Top 1GB Space With The Kernels VM And Lower
39  1MB Of VM Space With The Kernel
40 
41  07/30/02 - Note This Is Going To Get The Top 1Gig And Lower 1MB Region
42  From The Currently Loaded Page Directory This Is Safe Because
43  All VM Spaces Will Share These Regions
44 
45  07/30/02 - Note I Realized A Mistake The First Page Table Will Need To Be
46  A Copy But The Page Tables For The Top 1GB Will Not Reason For
47  This Is That We Just Share The First 1MB In The First Page Table
48  So We Will Just Share Physical Pages.
49 
50  08/02/02 - Added Passing Of pid_t pid For Better Tracking Of Who Has Which
51  Set Of Pages
52 
53  ************************************************************************/
54 void *vmm_createVirtualSpace(pid_t pid) {
55 
56  void *newPageDirectoryAddress = 0x0;
57  uint32_t *parentPageDirectory = 0x0, *newPageDirectory = 0x0;
58  uint32_t *parentPageTable = 0x0, *newPageTable = 0x0;
59 
60  int x = 0;
61 
62  /* Set Address Of Parent Page Directory */
63  parentPageDirectory = (uint32_t *) PD_BASE_ADDR; /* PD_BASE_ADDR is the addressable Page Directory */
64 
65  /* Allocate A New Page For The New Page Directory */
66  newPageDirectory = (uint32_t *) vmm_getFreePage(pid);
67 
68  /* Set newPageDirectoryAddress To The Newly Created Page Directories Page */
69  newPageDirectoryAddress = (void *) vmm_getPhysicalAddr((uint32_t) newPageDirectory);
70 
71  /* First Set Up A Flushed Page Directory */
72  bzero(newPageDirectory, PAGE_SIZE);
73 
74  /* Map The Lower 8MB Kernel Code Space */
75  /* Map First 4MB 1:1 */
76  newPageDirectory[0] = parentPageDirectory[0];
77  //XXX: We Dont Need This - newPageDirectory[1] = parentPageDirectory[1];
78 
79  /* Map Second 4MB */
80  newPageTable = (uint32_t *) vmm_getFreePage(pid);
81  bzero(newPageTable, PAGE_SIZE);
82 
83  parentPageTable = (uint32_t *) (PT_BASE_ADDR + (PAGE_SIZE * 1));
84 
85  for (x = 0; x < PT_ENTRIES; x++) {
86  if (((parentPageTable[x]) & PAGE_PRESENT) == PAGE_PRESENT) {
87 
88  /* Set Page To COW In Parent And Child Space */
89  newPageTable[x] = (((uint32_t) parentPageTable[x] & 0xFFFFF000) | (KERNEL_PAGE_DEFAULT | PAGE_COW));
90 
91  /* Increment The COW Counter For This Page */
92  if (((uint32_t) parentPageTable[x] & PAGE_COW) == PAGE_COW) {
93  adjustCowCounter(((uint32_t) parentPageTable[x] & 0xFFFFF000), 1);
94  }
95  else {
96  /* Add Two If This Is The First Time Setting To COW */
97  adjustCowCounter(((uint32_t) parentPageTable[x] & 0xFFFFF000), 2);
98  parentPageTable[x] |= PAGE_COW; // newPageTable[i];
99  }
100 
101  }
102  else
103  newPageTable[x] = parentPageTable[x];
104 
105  }
106 
107  newPageDirectory[1] = (vmm_getPhysicalAddr((uint32_t) newPageTable) | KERNEL_PAGE_DEFAULT);
108 
109  vmm_unmapPage((uint32_t) newPageTable, 1);
110  /* Done Mapping Second 4MB */
111 
112  /* Map The Top Kernel (APPROX 1GB) Region Of The VM Space */
113  for (x = PD_INDEX(VMM_KERN_START); x < PD_ENTRIES; x++) {
114  newPageDirectory[x] = parentPageDirectory[x];
115  }
116 
117  /* Allocate Stack Pages */
118  newPageTable = (uint32_t *) vmm_getFreePage(pid);
119  bzero(newPageTable, PAGE_SIZE);
120 
121  newPageDirectory[1023] = (vmm_getPhysicalAddr((uint32_t) newPageTable) | KERNEL_PAGE_DEFAULT);
122 
123  parentPageTable = (uint32_t *) (PT_BASE_ADDR + (PAGE_SIZE * 1023));
124  newPageTable[1023] = parentPageTable[1023] | PAGE_COW;
125  adjustCowCounter(((uint32_t) parentPageTable[1023] & 0xFFFFF000), 2);
126  newPageTable[1022] = parentPageTable[1022] | PAGE_COW;
127  adjustCowCounter(((uint32_t) parentPageTable[1022] & 0xFFFFF000), 2);
128 
129  vmm_unmapPage((uint32_t) newPageTable, 1);
130 
131  /*
132  * Allocate A New Page For The The First Page Table Where We Will Map The
133  * Lower Region
134  */
135 
136  //newPageTable = (uint32_t *) vmm_getFreePage(pid);
137  /* Flush The Page From Garbage In Memory */
138  //bzero(newPageTable, PAGE_SIZE);
139  /* Map This Into The Page Directory */
140  //newPageDirectory[0] = (vmm_getPhysicalAddr((uint32_t) newPageTable) | KERNEL_PAGE_DEFAULT); //MrOlsen 2018-01-14 PAGE_DEFAULT
141  /* Set Address Of Parents Page Table */
142  //parentPageTable = (uint32_t *) PT_BASE_ADDR;
143  /* Map The First 1MB Worth Of Pages */
144  /*
145  for (x = 0; x < (PD_ENTRIES / 4); x++) {
146  newPageTable[x] = parentPageTable[x];
147  }
148  */
149 
150  /* Unmap Page From Virtual Space */
151  //vmm_unmapPage((uint32_t) newPageTable, 1);
152  /*
153  *
154  * Map Page Directory Into VM Space
155  * First Page After Page Tables
156  * This must be mapped into the page directory before we map all 1024 page directories into the memory space
157  */
158  newPageTable = (uint32_t *) vmm_getFreePage(pid);
159 
160  newPageDirectory[PD_INDEX(PD_BASE_ADDR)] = (uint32_t) (vmm_getPhysicalAddr((uint32_t) newPageTable) | KERNEL_PAGE_DEFAULT); //MrOlsen 2018-01-14 PAGE_DEFAULT
161 
162  newPageTable[0] = (uint32_t) ((uint32_t) (newPageDirectoryAddress) | KERNEL_PAGE_DEFAULT); //MrOlsen 2018-01-14 PAGE_DEFAULT
163 
164  vmm_unmapPage((uint32_t) newPageTable, 1);
165 
166  /*
167  *
168  * Map Page Tables Into VM Space
169  * The First Page Table (4MB) Maps To All Page Directories
170  *
171  */
172 
173  newPageTable = (uint32_t *) vmm_getFreePage(pid);
174 
175  newPageDirectory[PD_INDEX(PT_BASE_ADDR)] = (uint32_t) (vmm_getPhysicalAddr((uint32_t) newPageTable) | KERNEL_PAGE_DEFAULT); //MrOlsen 2018-01-14 PAGE_DEFAULT
176 
177  /* Flush The Page From Garbage In Memory */
178  bzero(newPageTable, PAGE_SIZE);
179 
180  for (x = 0; x < PD_ENTRIES; x++) {
181  newPageTable[x] = newPageDirectory[x];
182  }
183 
184  /* Unmap Page From Virtual Space */
185  vmm_unmapPage((uint32_t) newPageTable, 1);
186 
187  /* Now We Are Done With The Page Directory So Lets Unmap That Too */
188  vmm_unmapPage((uint32_t) newPageDirectory, 1);
189 
190  /* Return Physical Address Of Page Directory */
191  return (newPageDirectoryAddress);
192 }
PAGE_COW
#define PAGE_COW
Definition: paging.h:64
vmm.h
pid_t
int pid_t
Definition: types.h:77
vmm_getPhysicalAddr
uint32_t vmm_getPhysicalAddr(uint32_t)
Definition: getphysicaladdr.c:38
adjustCowCounter
int adjustCowCounter(uint32_t baseAddr, int adjustment)
bzero
#define bzero(buf, size)
Definition: gpt.h:37
VMM_KERN_START
#define VMM_KERN_START
Definition: vmm.h:64
vmm_unmapPage
void vmm_unmapPage(uint32_t, unmapFlags_t)
Definition: unmappage.c:47
PT_ENTRIES
#define PT_ENTRIES
Definition: paging.h:49
PD_INDEX
#define PD_INDEX(v_addr)
Definition: paging.h:40
PD_BASE_ADDR
#define PD_BASE_ADDR
Definition: paging.h:45
uint32_t
__uint32_t uint32_t
Definition: types.h:46
vmm_getFreePage
void * vmm_getFreePage(pidType)
Definition: getfreepage.c:45
PD_ENTRIES
#define PD_ENTRIES
Definition: paging.h:48
PAGE_SIZE
#define PAGE_SIZE
Definition: paging.h:37
KERNEL_PAGE_DEFAULT
#define KERNEL_PAGE_DEFAULT
Definition: paging.h:69
vmm_createVirtualSpace
void * vmm_createVirtualSpace(pid_t pid)
Definition: createvirtualspace.c:53
PT_BASE_ADDR
#define PT_BASE_ADDR
Definition: paging.h:46
PAGE_PRESENT
#define PAGE_PRESENT
Definition: paging.h:55