обновить таблицу страниц - операционная система - PullRequest
0 голосов
/ 28 апреля 2020

У меня есть домашнее задание по операционным системам. Цель этого задания - реализовать смоделированный код ОС, который обрабатывает многоуровневую (основанную на tr ie) таблицу страниц. Вы будете реализовывать две функции. Первая функция создает / уничтожает сопоставления виртуальной памяти в таблице страниц. Вторая функция проверяет, отображается ли адрес в таблице страниц. (Вторая функция необходима, если ОС хочет выяснить, к какому физическому адресу относится виртуальный адрес процесса.) Ваш код будет симуляцией, потому что он будет работать в нормальном процессе. Мы предоставляем два файла os. c и os.h, которые содержат вспомогательные функции, имитирующие некоторые функции ОС, которые ваш код должен будет вызывать. Для вашего удобства также есть функция main (), демонстрирующая использование кода. Тем не менее, предоставляемый main () только обрабатывает ваш код тривиальными способами. Мы рекомендуем вам изменить его, чтобы тщательно протестировать реализованные вами функции. 1.1 Целевое оборудование Наша моделируемая ОС предназначена для воображаемого 64-битного x86-подобного процессора Говоря об адресах (виртуальных или физических), мы обращаемся к младшему значащему биту как к биту 0, а к старшему значимому биту - как к биту 63. Виртуальные адреса Размер виртуального адреса нашего оборудования составляет 64 бита, из которых только младшие 57 бит используются для перевода. Старшие 7 бит гарантированно идентичны биту 56, т. Е. Они являются либо всеми единицами, либо всеми нулями. Ниже показано расположение виртуальных адресов:

описание

Физические адреса

Размер физического адреса нашего оборудования также составляет 64 бита.

Структура таблицы страниц Размер страницы / фрейма составляет 4 КБ (4096 байт). Узлы таблицы страниц занимают физический фрейм страницы, то есть имеют размер 4 КБ. Размер записи таблицы страниц составляет 64 бита. Бит 0 является действительным битом. Биты 1–11 не используются и должны быть установлены на ноль. (Это означает, что наш целевой ЦП не реализует права доступа к странице.) Первые 52 бита содержат номер кадра страницы, на который указывает эта запись. Ниже представлен формат PTE:

описание

Количество уровней таблицы страниц Чтобы успешно выполнить задание, вы должны ответить себе: сколько уровней в нашем многоуровневая таблица страниц целевой машины? Как уже упоминалось, предположим, что только 57 младших битов виртуального адреса используются для перевода. 1.2 Диспетчер физической памяти ОС Для написания кода, который манипулирует таблицами страниц, вам необходимо выполнить следующее: (1) получить номер страницы неиспользуемой физической страницы, которая помечает ее как использованную; и (2) получить виртуальный адрес ядра данного физического адреса. Предоставленный os. c содержит функции, имитирующие эту функциональность: 1. Используйте следующую функцию для выделения физической страницы (также называемой рамкой страницы):

uint64 t allo c рамка страницы (void);

Эта функция возвращает номер физической страницы выделенной страницы. В этом задании вам не нужно освобождать физические страницы. Если allo c page frame () не может выделить физическую страницу, он выйдет из программы. Содержимое выделенного фрейма страницы - все нули. 2. Используйте следующую функцию для получения указателя (т. Е. Виртуального адреса) на физический адрес:

void * phys to virt (uint64 t phys addr);

Допустимые входные данные для Phys к virt () относятся адреса, которые находятся на физических страницах, которые ранее были возвращены allo c page frame (). Если он вызывается с неверным вводом, он возвращает NULL. 2 Описание назначения Внедрите следующие две функции в файл с именем pt. c. Этот файл должен #include "os.h", чтобы получить прототипы функций. 1. Функция для создания / уничтожения отображений виртуальной памяти в таблице страниц:

void обновление таблицы страниц (uint64 t pt, uint64 t vpn, uint64 t ppn); Эта функция принимает следующие аргументы: (a) pt: номер физической страницы таблицы страниц root (это физическая страница, на которую будет указывать регистр таблицы страниц в состоянии ЦП). (b) vpn: номер виртуальной страницы, который абонент хочет отобразить / удалить. (c) ppn: Может быть одним из двух случаев. Если ppn равно специальному значению NO MAPPING (определенному в os.h), то отображение vpn должно быть уничтожено. В противном случае ppn указывает номер физической страницы, на который должен быть сопоставлен vpn. 2. Функция для запроса сопоставления номера виртуальной страницы в таблице страниц: uint64 t запрос таблицы страниц (uint64 t pt, uint64 t vpn);

Эта функция возвращает номер физической страницы, с которой сопоставлен vpn. to или NO MAPPING, если сопоставление не существует. Значение аргумента pt такое же, как и для update таблицы таблицы (). Вы можете реализовать вспомогательные функции для своего кода, но обязательно используйте их в своем файле pt. c. Вы не можете отправлять дополнительные файлы (даже файлы заголовков). ВАЖНО: Узел таблицы страниц следует рассматривать как массив uint64 ts.

Теперь это мой файл os. c:

#define _GNU_SOURCE

#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <err.h>
#include <sys/mman.h>

#include "os.h"

/* 2^20 pages ought to be enough for anybody */
#define NPAGES  (1024*1024)

static void* pages[NPAGES];

uint64_t alloc_page_frame(void)
{
static uint64_t nalloc;
uint64_t ppn;
void* va;

if (nalloc == NPAGES)
    errx(1, "out of physical memory");

/* OS memory management isn't really this simple */
ppn = nalloc;
nalloc++;

va = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
if (va == MAP_FAILED)
    err(1, "mmap failed");

pages[ppn] = va;    
return ppn;
}

void* phys_to_virt(uint64_t phys_addr)
{
uint64_t ppn = phys_addr >> 12;
uint64_t off = phys_addr & 0xfff;
void* va = NULL;

if (ppn < NPAGES)
    va = pages[ppn] + off;

return va;
}

int main(int argc, char **argv)
{
uint64_t pt = alloc_page_frame();

assert(page_table_query(pt, 0xcafe) == NO_MAPPING);
page_table_update(pt, 0xcafe, 0xf00d);
assert(page_table_query(pt, 0xcafe) == 0xf00d);
page_table_update(pt, 0xcafe, NO_MAPPING);
assert(page_table_query(pt, 0xcafe) == NO_MAPPING);

return 0;
}

И это мой os.h file

#include <stdint.h>

#define NO_MAPPING  (~0ULL)

uint64_t alloc_page_frame(void);
void* phys_to_virt(uint64_t phys_addr);

void page_table_update(uint64_t pt, uint64_t vpn, uint64_t ppn);
uint64_t page_table_query(uint64_t pt, uint64_t vpn);

И это файл pt. c, который у меня сейчас есть ...

 #include "os.h"
 void page_table_update(uint64_t pt, uint64_t vpn, uint64_t ppn)
{
if (ppn==NO_MAPPING)
{
void *va=phys_to_virt(pt);
}
else
{


}
}
uint64_t page_table_query(uint64_t pt, uint64_t vpn)
{
return 0;
}

Может кто-нибудь помочь мне объяснить, как действовать? Я не понимаю, как перейти от основной таблицы к следующим таблицам (их должно быть четыре) и какую строку мне следует обновить. Спасибо !!

...