Created
March 2, 2023 13:23
-
-
Save clickCA/a56784df4bdcf7cc5aa19b29fb4965c6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <stdint.h> | |
| #define FRAME_SIZE 256 | |
| #define FRAME_ENTRIES 128 | |
| #define PAGE_SIZE 256 | |
| #define PAGE_ENTRIES 16 | |
| #define OUTER_PAGE_ENTRIES 16 | |
| typedef struct PageTableEntry { | |
| uint16_t present : 1; | |
| uint16_t frame : 15; | |
| } PageTableEntry; | |
| PageTableEntry *page_table; | |
| PageTableEntry *outer_page_table[OUTER_PAGE_ENTRIES]; | |
| uint8_t *physical_memory; | |
| uint16_t translate_address(uint16_t logical_address) { | |
| // Get outer page number and page number from logical address | |
| uint8_t outer_page_number = logical_address >> 12; | |
| uint8_t page_number = (logical_address >> 8) & 0xF; | |
| // Allocate inner page table if it's not present | |
| if (outer_page_table[outer_page_number] == NULL) { | |
| // Inner page table not present, allocate an inner page table for it | |
| outer_page_table[outer_page_number] = malloc(PAGE_ENTRIES * sizeof(PageTableEntry)); | |
| } | |
| if (outer_page_table[outer_page_number][page_number].present == 0) { | |
| // Page not present, allocate a frame for it | |
| // For simplicity, just random a frame. Must fix this later. | |
| uint16_t frame_number = rand() % FRAME_ENTRIES; | |
| // Fill in page table | |
| outer_page_table[outer_page_number][page_number].present = 1; | |
| outer_page_table[outer_page_number][page_number].frame = frame_number; | |
| } | |
| // Construct physical address from frame number and offset | |
| uint16_t physical_address = (outer_page_table[outer_page_number][page_number].frame << 8) + (logical_address & 0xFF); | |
| printf("Translate logical address 0x%X (outer page number 0x%X, page number 0x%X, offset 0x%X) to physical address 0x%X\n", | |
| logical_address, outer_page_number, page_number, logical_address & 0xFF, physical_address); | |
| return physical_address; | |
| } | |
| void read_from_memory(uint16_t logical_address, uint8_t *value) { | |
| uint16_t physical_address = translate_address(logical_address); | |
| *value = physical_memory[physical_address]; | |
| } | |
| void write_to_memory(uint16_t logical_address, uint8_t value) { | |
| uint16_t physical_address = translate_address(logical_address); | |
| physical_memory[physical_address] = value; | |
| } | |
| int main() { | |
| // Allocate physical memory | |
| physical_memory = calloc(PAGE_ENTRIES, PAGE_SIZE); | |
| // Initialize random seed for frame allocation | |
| srand(42); | |
| // Read and write to memory | |
| uint8_t value; | |
| write_to_memory(0x123, 0xA); | |
| read_from_memory(0x123, &value); | |
| printf("Value read from memory: 0x%02X\n", value); | |
| write_to_memory(0x1234, 0xAB); | |
| read_from_memory(0x1234, &value); | |
| printf("Value read from memory: 0x%02X\n", value); | |
| // Calculate total size of outer page table and inner page tables | |
| size_t page_table_size = 0; | |
| for (int i = 0; i < OUTER_PAGE_ENTRIES; i++) { | |
| if (outer_page_table[i] != NULL) { | |
| page_table_size += PAGE_ENTRIES * sizeof(PageTableEntry); | |
| } | |
| } | |
| printf("Outer page table size: %zu bytes\n", sizeof(outer_page_table)); | |
| printf("Inner page table size: %zu bytes\n", page_table_size); | |
| printf("Total page table size: %zu bytes\n", sizeof(outer_page_table)+page_table_size); | |
| // Deallocate inner page tables | |
| for (int i = 0; i < OUTER_PAGE_ENTRIES; i++) { | |
| if (outer_page_table[i] != NULL) { | |
| free(outer_page_table[i]); | |
| } | |
| } | |
| // Deallocate physical memory and page table | |
| free(physical_memory); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment