SlideShare a Scribd company logo
Assignment of SOS operating system
The file lmemman.c has one incomplete function with TODO blocks. Finish these blocks to
complete the assignment.
bool init_logical_memory(PCB *p, uint32_t code_size);
This function initializes a process’ logical address space. This involves allocating frames for the
process code, stacks, page directory and page tables, and then setting them up. The PCB is
passed in the argument p, and the number of bytes in the process’ code and data is in the
argument code_size. The function should return TRUE if all goes well; otherwise FALSE. Any
frames allocated in the function must be freed if FALSE is returned.
This should be able to work under SOS operating system.
Here is the lmenman.c file:
////////////////////////////////////////////////////////
// The NAIVE Logical Memory Manager
//
// Divides memory into 4KB pages and allocates from them
#include "kernel_only.h"
// kernel page directory will be placed at frame 257
PDE *k_page_directory = (PDE *)(0xC0101000);
// page table entries for the 768th page directory entry will be placed
// at frame 258; 768th entry corresponds to virtual address range
// 3GB to 3GB+4MB-1 (0xC0000000 to 0xC03FFFFF)
PTE *pages_768 = (PTE *)(0xC0102000);
/*** Initialize logical memory for a process ***/
// Allocates physical memory and sets up page tables;
// we need to allocate memory to hold the program code and
// data, the stack, the page directory, and the required
// page tables
// called by runprogram.c; this function does not load the
// program from disk to memory (done in scheduler.c)
bool init_logical_memory(PCB *p, uint32_t code_size) {
// TODO: see background material on what this function should
// do. High-level objectives are:
// 1) calculate the number of frames necessary for program code,
// user-mode stack and kernel-mode stack
// 2) allocate frames for above
// 3) determine beginning physical address of program code,
// user-mode stack and kernel-mode stack
// 4) calculate the number of frames necessary for page directory
// and page tables
// 5) allocate frames for above
// 6) set up page directory and page tables
// 7) set mem struct in PCB: start_code, end_code, start_stack,
// start_brk, brk, and page_directory
// Return value: TRUE if everything goes well; FALSE if allocation
// of frames failed (you should dealloc any frames that may
// have already been allocated before returning)
// TODO: uncomment following line when you start working in
// this function
return FALSE;
}
/*** Initialize kernel's page directory and table ***/
void init_kernel_pages(void) {
uint32_t i;
// set up kernel page directory (users cannot touch this)
for (i=0; i<1024; i++) k_page_directory[i] = 0;
k_page_directory[768] = ((uint32_t)pages_768-KERNEL_BASE) | PDE_PRESENT |
PDE_READ_WRITE;
// map virtual (0xC0000000--0xC03FFFFF) to physical (0--0x3FFFFF)
for (i=0; i<1024; i++)
pages_768[i] = (i*4096) | PTE_PRESENT | PTE_READ_WRITE | PTE_GLOBAL;
// load page directory
load_CR3((uint32_t)k_page_directory-KERNEL_BASE);
}
/*** Load CR3 with page directory ***/
void load_CR3(uint32_t pd) {
asm volatile ("movl %0, %%eax ": :"m"(pd));
asm volatile ("movl %eax, %cr3 ");
}
/*** Allocate logical memory for kernel***/
// Allocates pages for kernel and returns logical address of allocated memory
// Note: Kernel uses 0xC0000000 to 0xC0400000 for now
void *alloc_kernel_pages(uint32_t n_pages) {
uint32_t p_alloc_base; // physical address of allocated memory
uint32_t l_alloc_base; // logical address of allocated memory
int i;
p_alloc_base = (uint32_t)alloc_frames(n_pages, KERNEL_ALLOC);
if (p_alloc_base==NULL) return NULL;
// Note: page table update is not necessary since first 4MB is already
// mapped and kernel allocation is always from first 4MB
// adding KERNEL_BASE converts address to logical when allocation
// of kernel is from the first 4MB (see alloc_frames)
l_alloc_base = p_alloc_base + KERNEL_BASE;
// fill-zero the memory area
zero_out_pages((void *)l_alloc_base, n_pages);
return (void *)l_alloc_base;
}
/*** Deallocate one page ***/
// Deallocates the page corresponding to virtual address
// ; p is the virtual address of page directory
void dealloc_page(void *loc, PDE *p) {
uint32_t pd_entry = (uint32_t)loc >> 22; // top 10 bits
uint32_t pt_entry = ((uint32_t)loc >> 12) & 0x000003FF; // next top 10 bits
int i;
// obtain page table corresponding to page directory entry
PTE *pt = (PTE *)(p[pd_entry] & 0xFFFFF000);
pt = (PTE *)((uint32_t)pt + KERNEL_BASE); // converting to virtual address
// deallocate the frame
dealloc_frames((void *)(pt[pt_entry] & 0xFFFFF000), 1);
// if user space address, then mark page table entry as not present
if ((uint32_t)loc < KERNEL_BASE)
pt[pt_entry] = 0;
}
/*** Deallocate all pages ***/
// Traverses the page directory and deallocs all allocated
// pages; p is the virtual address of page directory
void dealloc_all_pages(PDE *p) {
uint32_t pd_entry;
uint32_t pt_entry;
uint32_t i;
uint32_t loc = 0;
PTE *pt;
while (loc < 0xC0000000) { // only freeing user area of virtual memory
pd_entry = loc >> 22; // top 10 bits
if (p[pd_entry] != 0) { // page directory entry exists
pt = (PTE *)((p[pd_entry] & 0xFFFFF000) + KERNEL_BASE);
for (i=0; i<1024; i++) { // walk through page table
if (pt[i] == 0) continue;
dealloc_page((void *)(loc + i*4096), p);
}
// dealloc page table space and mark page directory entry not present
dealloc_frames((void *)(p[pd_entry] & 0xFFFFF000), 1);
p[pd_entry] = 0;
}
loc += 0x400000; // move ahead 4MB; the next page table
}
}
/*** Zero out pages ***/
// Ensure that page mappings exist before calling this function
void zero_out_pages(void *base, uint32_t n_pages) {
int i=0;
for (i=0; i<1024*n_pages; i++)
*((uint32_t *)((uint32_t)base + i)) = 0;
}
Solution
////////////////////////////////////////////////////////
// The NAIVE Logical Memory Manager
//
// Divides memory into 4KB pages and allocates from them
#include "kernel_only.h"
// kernel page directory will be placed at frame 257
PDE *k_page_directory = (PDE *)(0xC0101000);
// page table entries for the 768th page directory entry will be placed
// at frame 258; 768th entry corresponds to virtual address range
// 3GB to 3GB+4MB-1 (0xC0000000 to 0xC03FFFFF)
PTE *pages_768 = (PTE *)(0xC0102000);
/*** Initialize logical memory for a process ***/
// Allocates physical memory and sets up page tables;
// we need to allocate memory to hold the program code and
// data, the stack, the page directory, and the required
// page tables
// called by runprogram.c; this function does not load the
// program from disk to memory (done in scheduler.c)
bool init_logical_memory(PCB *p, uint32_t code_size) {
// TODO: see background material on what this function should
// do. High-level objectives are:
// 1) calculate the number of frames necessary for program code,
// user-mode stack and kernel-mode stack
// 2) allocate frames for above
// 3) determine beginning physical address of program code,
// user-mode stack and kernel-mode stack
// 4) calculate the number of frames necessary for page directory
// and page tables
// 5) allocate frames for above
// 6) set up page directory and page tables
// 7) set mem struct in PCB: start_code, end_code, start_stack,
// start_brk, brk, and page_directory
// Return value: TRUE if everything goes well; FALSE if allocation
// of frames failed (you should dealloc any frames that may
// have already been allocated before returning)
// TODO: comment following line when you start working in
// this function
uint32_t codePages;
if(code_size % 4096 == 0) {
codePages= code_size / 4096;
}
else {
codePages = (uint32_t)(code_size / 4096 + 1);
}
sys_printf("We are allocating a kernel page ");
//cleared sets to zero, unused good
PDE *myPDE = (PDE*)alloc_kernel_pages(1);
//uint32_t n_pages, uint32_t base, PDE *page_directory, uint32_t mode
sys_printf("The location of the PDE is : %x ", myPDE);
//sys_printf("The location of the tempPDE is : %x ", tempPDE);
myPDE[768] = ((uint32_t)pages_768-KERNEL_BASE) | PDE_PRESENT |
PDE_READ_WRITE;
sys_printf("The location of pde[768] is : %x ", &myPDE[768]);
//allocate pages tables
//mode -> bits get or'ed into page table entires
uint32_t codeRet = (uint32_t)alloc_user_pages(codePages, 0x0, myPDE,
PTE_READ_WRITE);
sys_printf("codeRet is: %d ", codeRet);
if(codeRet == NULL){
sys_printf("We are failing when making a page for the code ");
dealloc_all_pages(myPDE);
return FALSE;
}
//BFBFFFF-16K+1 (16K=0x4000)
//can't we just do if(alloc_user_pages())
//base of user stack ((0xBFBFEFFF+1)%4096)
uint32_t stackRet = (uint32_t)alloc_user_pages(4, 0xBFBFC000, myPDE,
PTE_READ_WRITE);
sys_printf("stackRet is: %d ", stackRet);
if(stackRet == NULL){
sys_printf("We are failing when making a page for the stack ");
dealloc_all_pages(myPDE);
return FALSE;
}
uint32_t testPDE = (uint32_t)myPDE - KERNEL_BASE;
sys_printf("The location of the real PDE is : %x ", testPDE);
//assigned correctly ?
//assigned correctly ?
p->mem.start_code = 0x0;
p->mem.end_code = code_size;
p->mem.start_brk = codePages * 4096;
p->mem.brk = p->mem.start_brk;
p->mem.start_stack = 0xBFBFFFFF - 0x1000; //0xBFBFEFFF kernal stack
p->mem.page_directory = (PDE*)((uint32_t)myPDE - KERNEL_BASE);
sys_printf("The real PDE is : %x ", p->mem.page_directory);
sys_printf("Looks like we are getting past the code ");
//deallocate frames if fails
return TRUE;
//return FALSE;
}
/*** Initialize kernel's page directory and table ***/
void init_kernel_pages(void) {
uint32_t i;
// set up kernel page directory (users cannot touch this)
for (i=0; i<1024; i++) k_page_directory[i] = 0;
k_page_directory[768] = ((uint32_t)pages_768-KERNEL_BASE) | PDE_PRESENT |
PDE_READ_WRITE;
// map virtual (0xC0000000--0xC03FFFFF) to physical (0--0x3FFFFF)
for (i=0; i<1024; i++)
pages_768[i] = (i*4096) | PTE_PRESENT | PTE_READ_WRITE | PTE_GLOBAL;
// load page directory
load_CR3((uint32_t)k_page_directory-KERNEL_BASE);
}
/*** Load CR3 with page directory ***/
void load_CR3(uint32_t pd) {
asm volatile ("movl %0, %%eax ": :"m"(pd));
asm volatile ("movl %eax, %cr3 ");
}
/*** Allocate logical memory for kernel***/
// Allocates pages for kernel and returns logical address of allocated memory
// Note: Kernel uses 0xC0000000 to 0xC0400000 for now
void *alloc_kernel_pages(uint32_t n_pages) {
uint32_t p_alloc_base; // physical address of allocated memory
uint32_t l_alloc_base; // logical address of allocated memory
int i;
p_alloc_base = (uint32_t)alloc_frames(n_pages, KERNEL_ALLOC);
if (p_alloc_base==NULL) return NULL;
// Note: page table update is not necessary since first 4MB is already
// mapped and kernel allocation is always from first 4MB
// adding KERNEL_BASE converts address to logical when allocation
// of kernel is from the first 4MB (see alloc_frames)
l_alloc_base = p_alloc_base + KERNEL_BASE;
// fill-zero the memory area
zero_out_pages((void *)l_alloc_base, n_pages);
return (void *)l_alloc_base;
}
/*** Allocate logical memory for user ***/
// n_pages: the number of contiguous pages requested
// base: requested base address of first page; must be 4KB aligned;
// all pages must fit before hitting KERNEL_BASE
// page_directory: logical base address of process page directory
// mode: page modes (READ ONLY or READ+WRITE)
// Returns FALSE on failure, TRUE on success
//
// We also allocate frames for page tables if necessary
//
// 2016-02-24: Fixed some bugs:
// 1. Return type changed to bool, void* return type failed if called with base = 0
// 2. Fixed calculation of n_pde
// 3. Removed init of user pages to 0 (this failed because they aren't mapped in the kernel
space)
// Requires corresponding update of declaration in kernel_only.h
bool alloc_user_pages(uint32_t n_pages, uint32_t base, PDE *page_directory, uint32_t mode) {
// some sanity check
if (base & 0x00000FFF != 0 || // base not 4KB aligned
base >= KERNEL_BASE || // base encroaching on kernel address space
(KERNEL_BASE - base)/4096 < n_pages || // some pages on kernel address space
n_pages == 0) return FALSE;
int i;
// allocate frames for the requested pages
uint32_t user_frames = (uint32_t)alloc_frames(n_pages, USER_ALLOC);
if (user_frames==NULL) return FALSE;
// how many new page tables we may need; some may be returned
uint32_t n_pde = (n_pages+1023) / 1024 + 1; // one page table maps 1024 pages
// allocate frames for the new page tables
uint32_t pt_frames = (uint32_t)alloc_frames(n_pde, KERNEL_ALLOC);
uint32_t pt_frames_used = 0; // we will track how many are used
if (pt_frames == NULL) {
dealloc_frames((void *)user_frames,n_pages);
return FALSE;
}
// set up page directory and page tables
PTE *l_pages; 
uint32_t pd_entry = base >> 22; // start from this page directory entry
uint32_t pt_entry = (base >> 12) & 0x000003FF; // and this page table entry
for (i=0; i; p is the virtual address of page directory
void dealloc_page(void *loc, PDE *p) {
uint32_t pd_entry = (uint32_t)loc >> 22; // top 10 bits
uint32_t pt_entry = ((uint32_t)loc >> 12) & 0x000003FF; // next top 10 bits
int i;
// obtain page table corresponding to page directory entry
PTE *pt = (PTE *)(p[pd_entry] & 0xFFFFF000);
pt = (PTE *)((uint32_t)pt + KERNEL_BASE); // converting to virtual address
// deallocate the frame
dealloc_frames((void *)(pt[pt_entry] & 0xFFFFF000), 1);
// if user space address, then mark page table entry as not present
if ((uint32_t)loc < KERNEL_BASE)
pt[pt_entry] = 0;
}
/*** Deallocate all pages ***/
// Traverses the page directory and deallocs all allocated
// pages; p is the virtual address of page directory
void dealloc_all_pages(PDE *p) {
uint32_t pd_entry;
uint32_t pt_entry;
uint32_t i;
uint32_t loc = 0;
PTE *pt;
while (loc < 0xC0000000) { // only freeing user area of virtual memory
pd_entry = loc >> 22; // top 10 bits
if (p[pd_entry] != 0) { // page directory entry exists
pt = (PTE *)((p[pd_entry] & 0xFFFFF000) + KERNEL_BASE);
for (i=0; i<1024; i++) { // walk through page table
if (pt[i] == 0) continue;
dealloc_page((void *)(loc + i*4096), p);
}
// dealloc page table space and mark page directory entry not present
dealloc_frames((void *)(p[pd_entry] & 0xFFFFF000), 1);
p[pd_entry] = 0;
}
loc += 0x400000; // move ahead 4MB; the next page table
}
}
/*** Zero out pages ***/
// Ensure that page mappings exist before calling this function
void zero_out_pages(void *base, uint32_t n_pages) {
int i=0;
for (i=0; i<1024*n_pages; i++)
*((uint32_t *)((uint32_t)base + i)) = 0;
}

More Related Content

PPTX
C Assignment Help
DOCX
finalprojtemplatev5finalprojtemplate.gitignore# Ignore the b
PPT
Bootstrap process of u boot (NDS32 RISC CPU)
PDF
Tema3_Introduction_to_CUDA_C.pdf
PPT
Linux memory
PPTX
The TCP/IP Stack in the Linux Kernel
PPTX
Lec05 buffers basic_examples
C Assignment Help
finalprojtemplatev5finalprojtemplate.gitignore# Ignore the b
Bootstrap process of u boot (NDS32 RISC CPU)
Tema3_Introduction_to_CUDA_C.pdf
Linux memory
The TCP/IP Stack in the Linux Kernel
Lec05 buffers basic_examples

Similar to Assignment of SOS operating systemThe file lmemman.c has one incom.pdf (20)

PDF
various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)
PDF
Farewell to Disks: Efficient Processing of Obstinate Data
PDF
Kernel Recipes 2014 - What I’m forgetting when designing a new userspace inte...
PPTX
2011.02.18 marco parenzan - modelli di programmazione per le gpu
PDF
CUDA lab's slides of "parallel programming" course
PDF
Yevhen Tatarynov "My .NET Application Allocates too Much Memory. What Can I Do?"
PDF
Process Address Space: The way to create virtual address (page table) of user...
PPT
Microkernel Development
KEY
Post Exploitation Bliss: Loading Meterpreter on a Factory iPhone, Black Hat U...
PDF
Drizzles Approach To Improving Performance Of The Server
PPTX
Linux Initialization Process (1)
PPTX
Programming Assignment Help
DOCX
Program Assignment Process ManagementObjective This program a.docx
PPTX
Operating System Assignment Help
PPTX
Operating System Assignment Help
ODP
Introduction to Kernel Programming
PDF
main.pdf java programming practice for programs
PDF
Db2 For I Parallel Data Load
PDF
The ProblemUsing C programming language write a program that simul.pdf
PDF
GPU Programming on CPU - Using C++AMP
various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)
Farewell to Disks: Efficient Processing of Obstinate Data
Kernel Recipes 2014 - What I’m forgetting when designing a new userspace inte...
2011.02.18 marco parenzan - modelli di programmazione per le gpu
CUDA lab's slides of "parallel programming" course
Yevhen Tatarynov "My .NET Application Allocates too Much Memory. What Can I Do?"
Process Address Space: The way to create virtual address (page table) of user...
Microkernel Development
Post Exploitation Bliss: Loading Meterpreter on a Factory iPhone, Black Hat U...
Drizzles Approach To Improving Performance Of The Server
Linux Initialization Process (1)
Programming Assignment Help
Program Assignment Process ManagementObjective This program a.docx
Operating System Assignment Help
Operating System Assignment Help
Introduction to Kernel Programming
main.pdf java programming practice for programs
Db2 For I Parallel Data Load
The ProblemUsing C programming language write a program that simul.pdf
GPU Programming on CPU - Using C++AMP
Ad

More from sktambifortune (20)

PDF
Your company is preparing to migrate from IPv4 to IPv6, and you are .pdf
PDF
You are burning the latest song you bought on ITunes to a disk. The .pdf
PDF
CASE 3-12 Information System Project Steering Committee The Informat.pdf
PDF
Can you date the latest financial crisis in the United States or in .pdf
PDF
B1. State the components of organization. Give good examples to justi.pdf
PDF
Any kind of help would gladly be appreciated. (C-programming)Probl.pdf
PDF
Which of the following solutions will turn red litmus blue pOH 1.pdf
PDF
What serves as the most reliable source of information about the .pdf
PDF
What is the difference between the terms “earnings and profits” and .pdf
PDF
what are three effects of transistor scaling on computer architectur.pdf
PDF
What are some of the motives for employee theft What are some .pdf
PDF
Twitter is a popular social media. It allows its users to exchange tw.pdf
PDF
A. State the domai and ranga. 1. y find the inverse and state the dom.pdf
PDF
The Puritan faith community shaped the New England colonies in virtu.pdf
PDF
savings account d. the value of the shares is based on the amount of .pdf
PDF
QuestionIt was reported on June 11, 1997, by NBC Nightly News that.pdf
PDF
946 LTE Labs Le.chateliers-lab.pdf Before beginning this experiment.pdf
PDF
Prove that the T_i-property is a topological property for i = 0So.pdf
PDF
4. Refer to the table of Gini coefficients in the Added Dimension box.pdf
PDF
number of lines should be included in the last page of the paper aft.pdf
Your company is preparing to migrate from IPv4 to IPv6, and you are .pdf
You are burning the latest song you bought on ITunes to a disk. The .pdf
CASE 3-12 Information System Project Steering Committee The Informat.pdf
Can you date the latest financial crisis in the United States or in .pdf
B1. State the components of organization. Give good examples to justi.pdf
Any kind of help would gladly be appreciated. (C-programming)Probl.pdf
Which of the following solutions will turn red litmus blue pOH 1.pdf
What serves as the most reliable source of information about the .pdf
What is the difference between the terms “earnings and profits” and .pdf
what are three effects of transistor scaling on computer architectur.pdf
What are some of the motives for employee theft What are some .pdf
Twitter is a popular social media. It allows its users to exchange tw.pdf
A. State the domai and ranga. 1. y find the inverse and state the dom.pdf
The Puritan faith community shaped the New England colonies in virtu.pdf
savings account d. the value of the shares is based on the amount of .pdf
QuestionIt was reported on June 11, 1997, by NBC Nightly News that.pdf
946 LTE Labs Le.chateliers-lab.pdf Before beginning this experiment.pdf
Prove that the T_i-property is a topological property for i = 0So.pdf
4. Refer to the table of Gini coefficients in the Added Dimension box.pdf
number of lines should be included in the last page of the paper aft.pdf
Ad

Recently uploaded (20)

PPTX
202450812 BayCHI UCSC-SV 20250812 v17.pptx
PDF
Supply Chain Operations Speaking Notes -ICLT Program
PPTX
PPT- ENG7_QUARTER1_LESSON1_WEEK1. IMAGERY -DESCRIPTIONS pptx.pptx
PPTX
Presentation on HIE in infants and its manifestations
PPTX
human mycosis Human fungal infections are called human mycosis..pptx
PDF
VCE English Exam - Section C Student Revision Booklet
PPTX
Final Presentation General Medicine 03-08-2024.pptx
PDF
3rd Neelam Sanjeevareddy Memorial Lecture.pdf
PDF
A systematic review of self-coping strategies used by university students to ...
PDF
Complications of Minimal Access Surgery at WLH
PDF
Saundersa Comprehensive Review for the NCLEX-RN Examination.pdf
PDF
Classroom Observation Tools for Teachers
PDF
102 student loan defaulters named and shamed – Is someone you know on the list?
PPTX
Pharmacology of Heart Failure /Pharmacotherapy of CHF
PDF
grade 11-chemistry_fetena_net_5883.pdf teacher guide for all student
PDF
RMMM.pdf make it easy to upload and study
PDF
FourierSeries-QuestionsWithAnswers(Part-A).pdf
PDF
ANTIBIOTICS.pptx.pdf………………… xxxxxxxxxxxxx
PDF
OBE - B.A.(HON'S) IN INTERIOR ARCHITECTURE -Ar.MOHIUDDIN.pdf
PPTX
Pharma ospi slides which help in ospi learning
202450812 BayCHI UCSC-SV 20250812 v17.pptx
Supply Chain Operations Speaking Notes -ICLT Program
PPT- ENG7_QUARTER1_LESSON1_WEEK1. IMAGERY -DESCRIPTIONS pptx.pptx
Presentation on HIE in infants and its manifestations
human mycosis Human fungal infections are called human mycosis..pptx
VCE English Exam - Section C Student Revision Booklet
Final Presentation General Medicine 03-08-2024.pptx
3rd Neelam Sanjeevareddy Memorial Lecture.pdf
A systematic review of self-coping strategies used by university students to ...
Complications of Minimal Access Surgery at WLH
Saundersa Comprehensive Review for the NCLEX-RN Examination.pdf
Classroom Observation Tools for Teachers
102 student loan defaulters named and shamed – Is someone you know on the list?
Pharmacology of Heart Failure /Pharmacotherapy of CHF
grade 11-chemistry_fetena_net_5883.pdf teacher guide for all student
RMMM.pdf make it easy to upload and study
FourierSeries-QuestionsWithAnswers(Part-A).pdf
ANTIBIOTICS.pptx.pdf………………… xxxxxxxxxxxxx
OBE - B.A.(HON'S) IN INTERIOR ARCHITECTURE -Ar.MOHIUDDIN.pdf
Pharma ospi slides which help in ospi learning

Assignment of SOS operating systemThe file lmemman.c has one incom.pdf

  • 1. Assignment of SOS operating system The file lmemman.c has one incomplete function with TODO blocks. Finish these blocks to complete the assignment. bool init_logical_memory(PCB *p, uint32_t code_size); This function initializes a process’ logical address space. This involves allocating frames for the process code, stacks, page directory and page tables, and then setting them up. The PCB is passed in the argument p, and the number of bytes in the process’ code and data is in the argument code_size. The function should return TRUE if all goes well; otherwise FALSE. Any frames allocated in the function must be freed if FALSE is returned. This should be able to work under SOS operating system. Here is the lmenman.c file: //////////////////////////////////////////////////////// // The NAIVE Logical Memory Manager // // Divides memory into 4KB pages and allocates from them #include "kernel_only.h" // kernel page directory will be placed at frame 257 PDE *k_page_directory = (PDE *)(0xC0101000); // page table entries for the 768th page directory entry will be placed // at frame 258; 768th entry corresponds to virtual address range // 3GB to 3GB+4MB-1 (0xC0000000 to 0xC03FFFFF) PTE *pages_768 = (PTE *)(0xC0102000); /*** Initialize logical memory for a process ***/ // Allocates physical memory and sets up page tables; // we need to allocate memory to hold the program code and // data, the stack, the page directory, and the required // page tables // called by runprogram.c; this function does not load the // program from disk to memory (done in scheduler.c) bool init_logical_memory(PCB *p, uint32_t code_size) { // TODO: see background material on what this function should // do. High-level objectives are: // 1) calculate the number of frames necessary for program code, // user-mode stack and kernel-mode stack // 2) allocate frames for above
  • 2. // 3) determine beginning physical address of program code, // user-mode stack and kernel-mode stack // 4) calculate the number of frames necessary for page directory // and page tables // 5) allocate frames for above // 6) set up page directory and page tables // 7) set mem struct in PCB: start_code, end_code, start_stack, // start_brk, brk, and page_directory // Return value: TRUE if everything goes well; FALSE if allocation // of frames failed (you should dealloc any frames that may // have already been allocated before returning) // TODO: uncomment following line when you start working in // this function return FALSE; } /*** Initialize kernel's page directory and table ***/ void init_kernel_pages(void) { uint32_t i; // set up kernel page directory (users cannot touch this) for (i=0; i<1024; i++) k_page_directory[i] = 0; k_page_directory[768] = ((uint32_t)pages_768-KERNEL_BASE) | PDE_PRESENT | PDE_READ_WRITE; // map virtual (0xC0000000--0xC03FFFFF) to physical (0--0x3FFFFF) for (i=0; i<1024; i++) pages_768[i] = (i*4096) | PTE_PRESENT | PTE_READ_WRITE | PTE_GLOBAL; // load page directory load_CR3((uint32_t)k_page_directory-KERNEL_BASE); } /*** Load CR3 with page directory ***/ void load_CR3(uint32_t pd) { asm volatile ("movl %0, %%eax ": :"m"(pd)); asm volatile ("movl %eax, %cr3 "); } /*** Allocate logical memory for kernel***/ // Allocates pages for kernel and returns logical address of allocated memory // Note: Kernel uses 0xC0000000 to 0xC0400000 for now
  • 3. void *alloc_kernel_pages(uint32_t n_pages) { uint32_t p_alloc_base; // physical address of allocated memory uint32_t l_alloc_base; // logical address of allocated memory int i; p_alloc_base = (uint32_t)alloc_frames(n_pages, KERNEL_ALLOC); if (p_alloc_base==NULL) return NULL; // Note: page table update is not necessary since first 4MB is already // mapped and kernel allocation is always from first 4MB // adding KERNEL_BASE converts address to logical when allocation // of kernel is from the first 4MB (see alloc_frames) l_alloc_base = p_alloc_base + KERNEL_BASE; // fill-zero the memory area zero_out_pages((void *)l_alloc_base, n_pages); return (void *)l_alloc_base; } /*** Deallocate one page ***/ // Deallocates the page corresponding to virtual address // ; p is the virtual address of page directory void dealloc_page(void *loc, PDE *p) { uint32_t pd_entry = (uint32_t)loc >> 22; // top 10 bits uint32_t pt_entry = ((uint32_t)loc >> 12) & 0x000003FF; // next top 10 bits int i; // obtain page table corresponding to page directory entry PTE *pt = (PTE *)(p[pd_entry] & 0xFFFFF000); pt = (PTE *)((uint32_t)pt + KERNEL_BASE); // converting to virtual address // deallocate the frame dealloc_frames((void *)(pt[pt_entry] & 0xFFFFF000), 1); // if user space address, then mark page table entry as not present if ((uint32_t)loc < KERNEL_BASE) pt[pt_entry] = 0; } /*** Deallocate all pages ***/ // Traverses the page directory and deallocs all allocated // pages; p is the virtual address of page directory void dealloc_all_pages(PDE *p) { uint32_t pd_entry;
  • 4. uint32_t pt_entry; uint32_t i; uint32_t loc = 0; PTE *pt; while (loc < 0xC0000000) { // only freeing user area of virtual memory pd_entry = loc >> 22; // top 10 bits if (p[pd_entry] != 0) { // page directory entry exists pt = (PTE *)((p[pd_entry] & 0xFFFFF000) + KERNEL_BASE); for (i=0; i<1024; i++) { // walk through page table if (pt[i] == 0) continue; dealloc_page((void *)(loc + i*4096), p); } // dealloc page table space and mark page directory entry not present dealloc_frames((void *)(p[pd_entry] & 0xFFFFF000), 1); p[pd_entry] = 0; } loc += 0x400000; // move ahead 4MB; the next page table } } /*** Zero out pages ***/ // Ensure that page mappings exist before calling this function void zero_out_pages(void *base, uint32_t n_pages) { int i=0; for (i=0; i<1024*n_pages; i++) *((uint32_t *)((uint32_t)base + i)) = 0; } Solution //////////////////////////////////////////////////////// // The NAIVE Logical Memory Manager // // Divides memory into 4KB pages and allocates from them #include "kernel_only.h" // kernel page directory will be placed at frame 257
  • 5. PDE *k_page_directory = (PDE *)(0xC0101000); // page table entries for the 768th page directory entry will be placed // at frame 258; 768th entry corresponds to virtual address range // 3GB to 3GB+4MB-1 (0xC0000000 to 0xC03FFFFF) PTE *pages_768 = (PTE *)(0xC0102000); /*** Initialize logical memory for a process ***/ // Allocates physical memory and sets up page tables; // we need to allocate memory to hold the program code and // data, the stack, the page directory, and the required // page tables // called by runprogram.c; this function does not load the // program from disk to memory (done in scheduler.c) bool init_logical_memory(PCB *p, uint32_t code_size) { // TODO: see background material on what this function should // do. High-level objectives are: // 1) calculate the number of frames necessary for program code, // user-mode stack and kernel-mode stack // 2) allocate frames for above // 3) determine beginning physical address of program code, // user-mode stack and kernel-mode stack // 4) calculate the number of frames necessary for page directory // and page tables // 5) allocate frames for above // 6) set up page directory and page tables // 7) set mem struct in PCB: start_code, end_code, start_stack, // start_brk, brk, and page_directory // Return value: TRUE if everything goes well; FALSE if allocation // of frames failed (you should dealloc any frames that may // have already been allocated before returning) // TODO: comment following line when you start working in // this function uint32_t codePages; if(code_size % 4096 == 0) { codePages= code_size / 4096; }
  • 6. else { codePages = (uint32_t)(code_size / 4096 + 1); } sys_printf("We are allocating a kernel page "); //cleared sets to zero, unused good PDE *myPDE = (PDE*)alloc_kernel_pages(1); //uint32_t n_pages, uint32_t base, PDE *page_directory, uint32_t mode sys_printf("The location of the PDE is : %x ", myPDE); //sys_printf("The location of the tempPDE is : %x ", tempPDE); myPDE[768] = ((uint32_t)pages_768-KERNEL_BASE) | PDE_PRESENT | PDE_READ_WRITE; sys_printf("The location of pde[768] is : %x ", &myPDE[768]); //allocate pages tables //mode -> bits get or'ed into page table entires uint32_t codeRet = (uint32_t)alloc_user_pages(codePages, 0x0, myPDE, PTE_READ_WRITE); sys_printf("codeRet is: %d ", codeRet); if(codeRet == NULL){ sys_printf("We are failing when making a page for the code "); dealloc_all_pages(myPDE); return FALSE; } //BFBFFFF-16K+1 (16K=0x4000) //can't we just do if(alloc_user_pages()) //base of user stack ((0xBFBFEFFF+1)%4096) uint32_t stackRet = (uint32_t)alloc_user_pages(4, 0xBFBFC000, myPDE, PTE_READ_WRITE); sys_printf("stackRet is: %d ", stackRet); if(stackRet == NULL){ sys_printf("We are failing when making a page for the stack "); dealloc_all_pages(myPDE); return FALSE; } uint32_t testPDE = (uint32_t)myPDE - KERNEL_BASE;
  • 7. sys_printf("The location of the real PDE is : %x ", testPDE); //assigned correctly ? //assigned correctly ? p->mem.start_code = 0x0; p->mem.end_code = code_size; p->mem.start_brk = codePages * 4096; p->mem.brk = p->mem.start_brk; p->mem.start_stack = 0xBFBFFFFF - 0x1000; //0xBFBFEFFF kernal stack p->mem.page_directory = (PDE*)((uint32_t)myPDE - KERNEL_BASE); sys_printf("The real PDE is : %x ", p->mem.page_directory); sys_printf("Looks like we are getting past the code "); //deallocate frames if fails return TRUE; //return FALSE; } /*** Initialize kernel's page directory and table ***/ void init_kernel_pages(void) { uint32_t i; // set up kernel page directory (users cannot touch this) for (i=0; i<1024; i++) k_page_directory[i] = 0; k_page_directory[768] = ((uint32_t)pages_768-KERNEL_BASE) | PDE_PRESENT | PDE_READ_WRITE; // map virtual (0xC0000000--0xC03FFFFF) to physical (0--0x3FFFFF) for (i=0; i<1024; i++) pages_768[i] = (i*4096) | PTE_PRESENT | PTE_READ_WRITE | PTE_GLOBAL; // load page directory load_CR3((uint32_t)k_page_directory-KERNEL_BASE); } /*** Load CR3 with page directory ***/ void load_CR3(uint32_t pd) { asm volatile ("movl %0, %%eax ": :"m"(pd)); asm volatile ("movl %eax, %cr3 "); } /*** Allocate logical memory for kernel***/ // Allocates pages for kernel and returns logical address of allocated memory // Note: Kernel uses 0xC0000000 to 0xC0400000 for now
  • 8. void *alloc_kernel_pages(uint32_t n_pages) { uint32_t p_alloc_base; // physical address of allocated memory uint32_t l_alloc_base; // logical address of allocated memory int i; p_alloc_base = (uint32_t)alloc_frames(n_pages, KERNEL_ALLOC); if (p_alloc_base==NULL) return NULL; // Note: page table update is not necessary since first 4MB is already // mapped and kernel allocation is always from first 4MB // adding KERNEL_BASE converts address to logical when allocation // of kernel is from the first 4MB (see alloc_frames) l_alloc_base = p_alloc_base + KERNEL_BASE; // fill-zero the memory area zero_out_pages((void *)l_alloc_base, n_pages); return (void *)l_alloc_base; } /*** Allocate logical memory for user ***/ // n_pages: the number of contiguous pages requested // base: requested base address of first page; must be 4KB aligned; // all pages must fit before hitting KERNEL_BASE // page_directory: logical base address of process page directory // mode: page modes (READ ONLY or READ+WRITE) // Returns FALSE on failure, TRUE on success // // We also allocate frames for page tables if necessary // // 2016-02-24: Fixed some bugs: // 1. Return type changed to bool, void* return type failed if called with base = 0 // 2. Fixed calculation of n_pde // 3. Removed init of user pages to 0 (this failed because they aren't mapped in the kernel space) // Requires corresponding update of declaration in kernel_only.h bool alloc_user_pages(uint32_t n_pages, uint32_t base, PDE *page_directory, uint32_t mode) { // some sanity check if (base & 0x00000FFF != 0 || // base not 4KB aligned base >= KERNEL_BASE || // base encroaching on kernel address space (KERNEL_BASE - base)/4096 < n_pages || // some pages on kernel address space
  • 9. n_pages == 0) return FALSE; int i; // allocate frames for the requested pages uint32_t user_frames = (uint32_t)alloc_frames(n_pages, USER_ALLOC); if (user_frames==NULL) return FALSE; // how many new page tables we may need; some may be returned uint32_t n_pde = (n_pages+1023) / 1024 + 1; // one page table maps 1024 pages // allocate frames for the new page tables uint32_t pt_frames = (uint32_t)alloc_frames(n_pde, KERNEL_ALLOC); uint32_t pt_frames_used = 0; // we will track how many are used if (pt_frames == NULL) { dealloc_frames((void *)user_frames,n_pages); return FALSE; } // set up page directory and page tables PTE *l_pages; uint32_t pd_entry = base >> 22; // start from this page directory entry uint32_t pt_entry = (base >> 12) & 0x000003FF; // and this page table entry for (i=0; i; p is the virtual address of page directory void dealloc_page(void *loc, PDE *p) { uint32_t pd_entry = (uint32_t)loc >> 22; // top 10 bits uint32_t pt_entry = ((uint32_t)loc >> 12) & 0x000003FF; // next top 10 bits int i; // obtain page table corresponding to page directory entry PTE *pt = (PTE *)(p[pd_entry] & 0xFFFFF000); pt = (PTE *)((uint32_t)pt + KERNEL_BASE); // converting to virtual address // deallocate the frame dealloc_frames((void *)(pt[pt_entry] & 0xFFFFF000), 1); // if user space address, then mark page table entry as not present if ((uint32_t)loc < KERNEL_BASE) pt[pt_entry] = 0; } /*** Deallocate all pages ***/ // Traverses the page directory and deallocs all allocated
  • 10. // pages; p is the virtual address of page directory void dealloc_all_pages(PDE *p) { uint32_t pd_entry; uint32_t pt_entry; uint32_t i; uint32_t loc = 0; PTE *pt; while (loc < 0xC0000000) { // only freeing user area of virtual memory pd_entry = loc >> 22; // top 10 bits if (p[pd_entry] != 0) { // page directory entry exists pt = (PTE *)((p[pd_entry] & 0xFFFFF000) + KERNEL_BASE); for (i=0; i<1024; i++) { // walk through page table if (pt[i] == 0) continue; dealloc_page((void *)(loc + i*4096), p); } // dealloc page table space and mark page directory entry not present dealloc_frames((void *)(p[pd_entry] & 0xFFFFF000), 1); p[pd_entry] = 0; } loc += 0x400000; // move ahead 4MB; the next page table } } /*** Zero out pages ***/ // Ensure that page mappings exist before calling this function void zero_out_pages(void *base, uint32_t n_pages) { int i=0; for (i=0; i<1024*n_pages; i++) *((uint32_t *)((uint32_t)base + i)) = 0; }