Import backup from 2003-12-23
This commit is contained in:
parent
9070a76b18
commit
71aaa7a598
@ -29,7 +29,7 @@
|
||||
#define YELLOW_TXT 0x0E
|
||||
#define BRWHITE_TXT 0x0F
|
||||
|
||||
#define FREERAM_START 0x268000
|
||||
#define FREERAM_START 0x368000 // 0x368000 is first available byte (this is right after the initrd @ 2mb, 1440kb.
|
||||
#define MAX_RAM 0x40000000 //1gb maximum RAM supported
|
||||
|
||||
#define PID_KERNEL 0x02 //kernel's PID
|
||||
|
@ -86,7 +86,7 @@ newgdtcontinue:
|
||||
mov gs, ax
|
||||
mov fs, ax
|
||||
mov ss, ax
|
||||
mov esp, 0xc01ffffc ;stack just under 2mb, moves downward
|
||||
mov esp, 0xc01ffffc ;stack just under 3gb+2mb, moves downward
|
||||
lidt [idtr] ;load idt
|
||||
|
||||
call _k_init
|
||||
|
18
kernel.c
18
kernel.c
@ -6,7 +6,6 @@
|
||||
|
||||
#include "k_defines.h" //#DEFINE's for kernel
|
||||
|
||||
#include "lib/string.h" //library string functions
|
||||
#include "lib/io.h" //library input/output functions
|
||||
|
||||
#include "functions.h" //general functions
|
||||
@ -34,30 +33,27 @@ extern dword read_cr3();
|
||||
#include "video.c"
|
||||
|
||||
dword timer = 0;
|
||||
dword *videoMode;
|
||||
|
||||
//Main kernel initialization method
|
||||
void k_init()
|
||||
{
|
||||
// ===== Initialization
|
||||
fdc_sendDOR(0x0C); //turn off floppy motor!!
|
||||
console_cls();
|
||||
video_init();
|
||||
mm_init();
|
||||
vmm_init();
|
||||
console_cls();
|
||||
remap_pics(0x20, 0x28);
|
||||
init_timer();
|
||||
videoMode = (dword *)0x90002;
|
||||
if (*videoMode)
|
||||
video_init((ModeInfoBlock *) 0x90306);
|
||||
mouse_init();
|
||||
pic1_mask(0); //unmask IRQ's 0-7
|
||||
pic2_mask(0); //unmask IRQ's 8-15
|
||||
enable_ints();
|
||||
kbd_resetLEDs(); //after enabling interrupts!!
|
||||
|
||||
printf("HOS 0.12 - Kernel Size: %d kb\n", kernel_size()/1024);
|
||||
printf("Memory available to OS: %d MB (Bytes: %d)\n", mm_totalmem/0x100000, mm_totalmem);
|
||||
printf("Free memory: %d bytes\n", mm_freemem());
|
||||
|
||||
printf("HOS 0.12 - Kernel Size: %u kb\n", kernel_size()/1024);
|
||||
printf("Memory available to OS: %u MB (Bytes: %u)\n", mm_megabytes, mm_totalmem);
|
||||
printf("Free memory: %u bytes\n", mm_freemem());
|
||||
|
||||
dword key = 0;
|
||||
for (;;)
|
||||
@ -75,7 +71,7 @@ void isr(dword num)
|
||||
{
|
||||
case 0x20: // IRQ0 - timer interrupt
|
||||
timer++;
|
||||
(*(byte *)(0xb8000))++;
|
||||
(*(byte *)(0xc00b8000))++;
|
||||
eoi();
|
||||
break;
|
||||
case 0x21: // IRQ1 - keyboard interrupt
|
||||
|
@ -107,7 +107,7 @@ _putc:
|
||||
jz putc_tab
|
||||
|
||||
shl ebx, 1
|
||||
add ebx, 0xb8000
|
||||
add ebx, 0xc00b8000
|
||||
mov ah, 0x07
|
||||
mov [ebx], ax
|
||||
mov eax, ecx
|
||||
@ -274,8 +274,8 @@ printf_done:
|
||||
;
|
||||
_console_scroll:
|
||||
pusha
|
||||
mov esi, 0xb8000+160
|
||||
mov edi, 0xb8000
|
||||
mov esi, 0xc00b8000+160
|
||||
mov edi, 0xc00b8000
|
||||
mov ecx, 960 ;(2000-80)/2
|
||||
console_scroll_loop:
|
||||
lodsd
|
||||
@ -294,7 +294,7 @@ console_scroll_loop2:
|
||||
;
|
||||
_console_cls:
|
||||
pusha
|
||||
mov edi, 0xb8000
|
||||
mov edi, 0xc00b8000
|
||||
mov ax, 0x0720
|
||||
mov ecx, 2000
|
||||
console_cls_loop:
|
||||
|
@ -11,7 +11,7 @@ _memcpy:
|
||||
push ecx
|
||||
mov esi, [ebp+8]
|
||||
mov edi, [ebp+12]
|
||||
mov ecx, [ebp+14]
|
||||
mov ecx, [ebp+16]
|
||||
|
||||
rep movsb
|
||||
|
||||
|
13
lib/string.c
13
lib/string.c
@ -1,13 +0,0 @@
|
||||
|
||||
#include "string.h"
|
||||
|
||||
int strlen(char *str)
|
||||
{
|
||||
int retn = 0;
|
||||
while (*str++ != 0)
|
||||
retn++;
|
||||
return retn;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,8 +0,0 @@
|
||||
|
||||
#ifndef __HSTRING_H__
|
||||
#define __HSTRING_H__ __HSTRING_H__
|
||||
|
||||
int strlen(char *str);
|
||||
|
||||
#endif
|
||||
|
306
mm.c
306
mm.c
@ -1,273 +1,105 @@
|
||||
// mm.c
|
||||
// 09/01/03 Josh Holtrop
|
||||
|
||||
// 0x368000 is first available byte (this is right after the kernel @ 1mb and the initrd @ 2mb, 1440kb.
|
||||
|
||||
|
||||
//Pointer to the first pageblock in the linked list
|
||||
pageblock *first_pageblock = (pageblock *) 0;
|
||||
//The total amount of physical memory available (bytes)
|
||||
dword mm_totalmem = 0x100000; //start counting from 1mb
|
||||
//The highest physical address
|
||||
dword mm_highestAddress = 0;
|
||||
#define BITMAP_SIZE 0x20000
|
||||
dword mm_totalmem = 0;
|
||||
dword mm_megabytes;
|
||||
byte page_bitmap[BITMAP_SIZE]; //used to store a bit for each page that is used, 0 if available
|
||||
//0x20000*(8 bits/byte)=0x100000 pages in 4gb total
|
||||
|
||||
//This function initializes the memory manager's linked list, filling it with the
|
||||
// memory areas returned by bios interrupt 0x8E20
|
||||
void mm_init()
|
||||
{
|
||||
dword *memmap_entries = (dword *) 0x9040A;
|
||||
memmap_entry *maps = (memmap_entry *) 0x92000;
|
||||
dword memmap_entries = *(dword *)0xC009040A;
|
||||
memmap_entry *maps = (memmap_entry *) 0xC0092000;
|
||||
dword a;
|
||||
for (a=0;a<(*memmap_entries);a++)
|
||||
for (a = 0; a < BITMAP_SIZE; a++)
|
||||
{
|
||||
page_bitmap[a] = 0xFF; //all pages used
|
||||
}
|
||||
for (a = 0; a < memmap_entries; a++)
|
||||
{
|
||||
if (maps[a].attributes == 1) // (1) mem free to OS
|
||||
{
|
||||
mm_totalmem += maps[a].limit.lowdword;
|
||||
if (mm_highestAddress < (maps[a].base.lowdword + maps[a].limit.lowdword))
|
||||
mm_highestAddress = maps[a].base.lowdword + maps[a].limit.lowdword;
|
||||
if ((maps[a].base.lowdword + maps[a].limit.lowdword) > (FREERAM_START+8192)) //goes past where we start freeram
|
||||
if ((maps[a].base.lowdword + maps[a].limit.lowdword) >= (FREERAM_START+4096)) //goes past where we start freeram
|
||||
{
|
||||
if (maps[a].base.lowdword < FREERAM_START)
|
||||
{
|
||||
maps[a].limit.lowdword = maps[a].limit.lowdword - (FREERAM_START - maps[a].base.lowdword);
|
||||
maps[a].base.lowdword = FREERAM_START; //block at least 4kb, starts >= FREERAM_START
|
||||
mm_pfreen(FREERAM_START, (maps[a].limit.lowdword - (FREERAM_START - maps[a].base.lowdword)) >> 12);
|
||||
}
|
||||
if (first_pageblock == 0) //no pageblock page set up yet, so set it up here
|
||||
else
|
||||
{
|
||||
first_pageblock = (pageblock *) maps[a].base.lowdword;
|
||||
maps[a].base.lowdword += 4096;
|
||||
maps[a].limit.lowdword -= 4096;
|
||||
mm_init_pageblockpage(first_pageblock);
|
||||
first_pageblock->base = maps[a].base.lowdword;
|
||||
first_pageblock->length = maps[a].limit.lowdword / 4096;
|
||||
first_pageblock->pid = MM_PB_AVAIL;
|
||||
mm_pfreen(maps[a].base.lowdword, maps[a].limit.lowdword >> 12); //set the appropriate bits as "free" in the page bitmap
|
||||
}
|
||||
else //first_pageblock already set up, add on segment
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mm_totalmem % 0x100000)
|
||||
mm_megabytes = (mm_totalmem >> 20) + 1;
|
||||
else
|
||||
mm_megabytes = mm_totalmem >> 20;
|
||||
}
|
||||
|
||||
|
||||
void mm_pfreen(dword base, dword pages)
|
||||
{
|
||||
dword a;
|
||||
dword max = base + (pages << 12);
|
||||
for (a = base; a < max; a += 4096)
|
||||
{
|
||||
mm_pfree(a);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void mm_pfree(dword base)
|
||||
{
|
||||
// dword pageNumber = base >> 12; // >>12 == /4096
|
||||
dword byteNumber = base >> 15; //pageNumber >> 3; //pageNumber/8
|
||||
dword bitNumber = (base >> 12) % 8; //pageNumber % 8;
|
||||
page_bitmap[byteNumber] = page_bitmap[byteNumber] & ((0x01 << bitNumber) ^ 0xFF);
|
||||
}
|
||||
|
||||
|
||||
void *mm_palloc()
|
||||
{
|
||||
dword bite;
|
||||
for (bite = 0; bite < BITMAP_SIZE; bite++)
|
||||
{
|
||||
if (page_bitmap[bite] != 0xFF) //there is an available page within this 8-page region
|
||||
{
|
||||
int bit;
|
||||
for (bit = 0; bit < 8; bit++)
|
||||
{
|
||||
if (!(page_bitmap[bite] & (1 << bit))) //this bite/bit combination is available
|
||||
{
|
||||
pageblock *pb = first_pageblock;
|
||||
for (;;)
|
||||
{
|
||||
if (pb->pid == MM_PB_NP)
|
||||
break;
|
||||
else
|
||||
pb++;
|
||||
}
|
||||
pb->base = maps[a].base.lowdword;
|
||||
pb->length = maps[a].limit.lowdword / 4096;
|
||||
pb->pid = MM_PB_AVAIL;
|
||||
return (void *)((bite << 15) + (bit << 12));
|
||||
}
|
||||
}
|
||||
}
|
||||
bite++;
|
||||
}
|
||||
if (first_pageblock == 0)
|
||||
{
|
||||
printf("ERROR! NO INITIAL PAGE BLOCK CREATED.");
|
||||
asm("cli");
|
||||
asm("hlt");
|
||||
for (;;)
|
||||
;
|
||||
}
|
||||
return 0; //no free page
|
||||
}
|
||||
|
||||
|
||||
|
||||
//This function initializes a pageblock to be full of empty pointers
|
||||
void mm_init_pageblockpage(pageblock *pbp)
|
||||
dword mm_freemem()
|
||||
{
|
||||
int a;
|
||||
for (a=0; a<256; a++) // 256 pageblock entries * 16 bytes per page block entry = 4096 bytes (1 page of pageblock entries)
|
||||
dword a;
|
||||
dword pages = 0;
|
||||
for (a = 0; a < BITMAP_SIZE; a++)
|
||||
{
|
||||
pbp[a].base = 0;
|
||||
pbp[a].length = 0;
|
||||
pbp[a].pid = MM_PB_NP;
|
||||
if (a<255)
|
||||
pbp[a].link = (dword)(&pbp[a+1]);
|
||||
else
|
||||
pbp[a].link = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//This function allocates a certain number of physical pages for a particular process
|
||||
//Returns:
|
||||
// 0 - no free mem, invalied PID
|
||||
// void* - physical address of allocated pages
|
||||
void *mm_palloc(dword numpages, dword proc_pid)
|
||||
{
|
||||
if (proc_pid < PID_KERNEL)
|
||||
return 0;
|
||||
pageblock *pb = first_pageblock;
|
||||
if (mm_freeentries() < 2)
|
||||
{
|
||||
if(mm_new_pageblock_page() == 0)
|
||||
return 0;
|
||||
}
|
||||
pageblock *newentry = mm_nextpageblockentry();
|
||||
for (;;)
|
||||
{
|
||||
if ((pb->pid == MM_PB_AVAIL) && (pb->length >= numpages))
|
||||
break;
|
||||
if (pb->link == 0)
|
||||
return 0;
|
||||
pb = (pageblock *)pb->link;
|
||||
}
|
||||
if (pb->length == numpages) //dont need a new entry, just mark this one as used :)
|
||||
{
|
||||
pb->pid = proc_pid;
|
||||
return (void *)pb->base;
|
||||
}
|
||||
else //subtract out allocated number of pages from length
|
||||
{
|
||||
newentry->base = pb->base;
|
||||
newentry->length = numpages;
|
||||
newentry->pid = proc_pid;
|
||||
pb->base += (numpages * 4096);
|
||||
pb->length -= numpages;
|
||||
return (void *)newentry->base;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//This method returns the number of free pageblock entries at the end of the linked list
|
||||
dword mm_freeentries()
|
||||
{
|
||||
pageblock *pb = first_pageblock;
|
||||
dword counter = 0;
|
||||
for (;;)
|
||||
{
|
||||
if (pb->pid == MM_PB_NP)
|
||||
counter++;
|
||||
if (pb->link == 0)
|
||||
return counter;
|
||||
pb = (pageblock *) pb->link;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//This method creates a new page used to hold more pageblock entries at the end of the linked list
|
||||
//Returns:
|
||||
// 0 - no free pages
|
||||
// pageblock* - address of pageblock page
|
||||
pageblock *mm_new_pageblock_page() //as of 09/26/03 this method leaks 4kb main memory per call, unrecoverable
|
||||
{
|
||||
pageblock *pb = first_pageblock;
|
||||
for (;;)
|
||||
{
|
||||
if ((pb->pid == MM_PB_AVAIL) && (pb->length > 1))
|
||||
int bit;
|
||||
for (bit = 0; bit < 8; bit++)
|
||||
{
|
||||
pageblock *retval = (pageblock *)pb->base;
|
||||
pb->base += 4096;
|
||||
pb->length--;
|
||||
mm_init_pageblockpage(retval); //zeros out, links new pageblock page
|
||||
mm_lastpageblockentry()->link = (dword)retval; //set up link to new pageblock page
|
||||
return retval;
|
||||
if (!(page_bitmap[a] & (1 << bit)))
|
||||
pages++;
|
||||
}
|
||||
pb = (pageblock *) pb->link;
|
||||
if (pb == 0)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//This method frees a physical page
|
||||
//Returns:
|
||||
// 2 - pointer to free was a null pointer
|
||||
// 1 - address not found
|
||||
// 0 - all went well
|
||||
int mm_pfree(void *ptr)
|
||||
{
|
||||
if (ptr == 0)
|
||||
return 2;
|
||||
pageblock *pb = first_pageblock;
|
||||
dword tofree = (dword) ptr;
|
||||
for (;;)
|
||||
{
|
||||
if (pb->base == tofree) // && (pb->pid == MM_PB_USED))
|
||||
{
|
||||
pb->pid = MM_PB_AVAIL; //found block, mark available / coalesce it
|
||||
mm_coalesce(pb);
|
||||
return 0;
|
||||
}
|
||||
if (pb->link == 0)
|
||||
return 1;
|
||||
pb = (pageblock *) pb->link;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//This method returns a pointer to the last pageblock in the linked list
|
||||
pageblock *mm_lastpageblockentry()
|
||||
{
|
||||
pageblock *pb = first_pageblock;
|
||||
for (;;)
|
||||
{
|
||||
if (pb->link == 0)
|
||||
return pb;
|
||||
pb = (pageblock *)pb->link;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//This method returns the next available-for-use pageblock entry
|
||||
// or 0, if they are all used
|
||||
pageblock *mm_nextpageblockentry()
|
||||
{
|
||||
pageblock *pb = first_pageblock;
|
||||
for (;;)
|
||||
{
|
||||
if (pb->pid == MM_PB_NP)
|
||||
return pb;
|
||||
if (pb->link == 0)
|
||||
return 0;
|
||||
pb = (pageblock *)pb->link;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//This method returns the amount of free physical RAM
|
||||
dword mm_freemem()
|
||||
{
|
||||
dword amount = 0;
|
||||
pageblock *pb = first_pageblock;
|
||||
for (;;)
|
||||
{
|
||||
if (pb->pid == MM_PB_AVAIL)
|
||||
amount += (pb->length)*4096;
|
||||
if (pb->link == 0)
|
||||
return amount;
|
||||
pb = (pageblock *) pb->link;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//This method "walks" through the linked list of pageblock entries and
|
||||
// combines any two entries that are adjacent and of the same type
|
||||
void mm_coalesce(pageblock *pb)
|
||||
{
|
||||
pageblock *pbc = first_pageblock;
|
||||
for (;;)
|
||||
{
|
||||
if (pbc->pid == pb->pid) //pid fields must match, both same process, both avail, or both not present
|
||||
{
|
||||
if ((pbc->base + (pbc->length * 4096)) == pb->base) //pbc ends where pb starts
|
||||
{
|
||||
pbc->length += pb->length;
|
||||
pb->pid = MM_PB_NP;
|
||||
mm_coalesce(pbc); //recursion: checks for any more page blocks to coalesce if one found
|
||||
return; //exit this recursion...
|
||||
}
|
||||
if ((pb->base + (pb->length * 4096)) == pbc->base) //pb ends where pbc starts
|
||||
{
|
||||
pb->length += pbc->length;
|
||||
pbc->pid = MM_PB_NP;
|
||||
mm_coalesce(pb);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (pbc->link == 0)
|
||||
return;
|
||||
pbc = (pageblock *)pbc->link;
|
||||
}
|
||||
return pages << 12;
|
||||
}
|
||||
|
||||
|
||||
|
24
mm.h
24
mm.h
@ -7,28 +7,14 @@ typedef struct {
|
||||
} __attribute__((packed)) memmap_entry;
|
||||
|
||||
|
||||
typedef struct {
|
||||
dword base;
|
||||
dword length; //in pages
|
||||
dword pid; //normally PID of process, use NP, AVAIL for special flags
|
||||
dword link; //leave dword instead of pointer so i dont have to worry about pointer arithmetic
|
||||
} __attribute__ ((packed)) pageblock; //16 byte pageblock entry - 256 entries = 1 page
|
||||
|
||||
|
||||
void mm_init();
|
||||
void mm_init_pageblockpage(pageblock *pbp);
|
||||
void *mm_palloc(dword numpages, dword proc_pid);
|
||||
void mm_coalesce(pageblock *pb);
|
||||
int mm_pfree(void *ptr);
|
||||
dword mm_freeentries();
|
||||
void mm_pfreen(dword base, dword pages);
|
||||
void mm_pfree(dword base);
|
||||
void *mm_palloc();
|
||||
dword mm_freemem();
|
||||
pageblock *mm_new_pageblock_page();
|
||||
pageblock *mm_lastpageblockentry();
|
||||
pageblock *mm_nextpageblockentry();
|
||||
|
||||
|
||||
#define MM_PB_NP 0x00 //00000000
|
||||
#define MM_PB_AVAIL 0x01 //00000001
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
17
video.c
17
video.c
@ -4,9 +4,17 @@
|
||||
|
||||
|
||||
//Initialized the video mode information block video_mode and allocated double-buffer memory for graphics display
|
||||
void video_init(ModeInfoBlock *mib)
|
||||
void video_init()
|
||||
{
|
||||
video_mode = *mib;
|
||||
videoMode = *(dword *)0xC0090002;
|
||||
|
||||
if (!videoMode) //we are in console mode
|
||||
{
|
||||
video_psetp = &video_psetpnull;
|
||||
return;
|
||||
}
|
||||
|
||||
video_mode = *(ModeInfoBlock *) 0xC0090306;
|
||||
|
||||
switch(video_mode.BitsPerPixel)
|
||||
{
|
||||
@ -139,5 +147,8 @@ void video_psetp32(int pixel, dword color)
|
||||
vid_ptr32[pixel] = color;
|
||||
}
|
||||
|
||||
|
||||
//Dummy function to not draw anything if there is no graphical mode enabled
|
||||
void video_psetpnull(int pixel, dword color)
|
||||
{
|
||||
}
|
||||
|
||||
|
2
video.h
2
video.h
@ -11,6 +11,7 @@ inline void video_pset(int x, int y, dword color);
|
||||
void video_psetp16(int pixel, dword color);
|
||||
void video_psetp24(int pixel, dword color);
|
||||
void video_psetp32(int pixel, dword color);
|
||||
void video_psetpnull(int pixel, dword color);
|
||||
void video_renderChar(int x, int y, int character, dword color);
|
||||
|
||||
typedef struct{
|
||||
@ -53,6 +54,7 @@ typedef struct{
|
||||
} ModeInfoBlock;
|
||||
|
||||
ModeInfoBlock video_mode;
|
||||
dword videoMode; //what video mode # we are in, 0 for console mode
|
||||
byte *vid_ptr24;
|
||||
word *vid_ptr16;
|
||||
dword *vid_ptr32;
|
||||
|
130
vmm.c
130
vmm.c
@ -2,140 +2,20 @@
|
||||
// vmm.c
|
||||
// Author: Josh Holtrop
|
||||
// Date: 09/30/03
|
||||
|
||||
PageDirectory *vmm_PDBR = (PageDirectory *)0x104000;
|
||||
dword vmm_first_virtual_address = 0;
|
||||
// Rewritten from scratch: 12/23/03
|
||||
|
||||
|
||||
void vmm_init()
|
||||
{
|
||||
if (mm_totalmem % 4096)
|
||||
vmm_first_virtual_address = mm_totalmem + (4096 - (mm_totalmem % 4096));
|
||||
else
|
||||
vmm_first_virtual_address = mm_totalmem;
|
||||
dword *pagetables = (dword *)0xC0104000; //this is the location of the page directory
|
||||
pagetables[0x3FF] = 0x104000|0x03; //the last page directory entry points to the page directory itself
|
||||
if (videoMode) //we are in a graphical mode
|
||||
{
|
||||
|
||||
if (vmm_mapn(0, 0, 0x03, mm_totalmem/4096+1))
|
||||
{
|
||||
printf("Could not page in all physical RAM!\n");
|
||||
//halt();
|
||||
}
|
||||
//we also need to map in the video framebuffer memory:
|
||||
if (video_mode.PhysBasePtr > 0 && video_mode.BitsPerPixel > 0)
|
||||
{
|
||||
if (vmm_mapn(video_mode.PhysBasePtr, video_mode.PhysBasePtr, 0x03, ((video_mode.BitsPerPixel>>3) * video_mode.XResolution * video_mode.YResolution)/4096+1))
|
||||
{
|
||||
printf("Could not page in video memory at 0x%x!\n", video_mode.PhysBasePtr);
|
||||
halt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int vmm_map1(dword virtual, dword physical, dword flags)
|
||||
{
|
||||
if (virtual & 0x00000FFF)
|
||||
return 1; // ERROR 1: address not page-aligned
|
||||
if (physical & 0x00000FFF)
|
||||
return 1; // ERROR 1: address not page-aligned
|
||||
int pde = (virtual & 0xFFC00000) >> 22;
|
||||
int pte = (virtual & 0x003FF000) >> 12;
|
||||
if (!(vmm_PDBR->pageTables[pde] & 0x01))
|
||||
{
|
||||
vmm_PDBR->pageTables[pde] = (dword)mm_palloc(1, PID_KERNEL) | 0x7; //user, r/w, present
|
||||
vmm_init_pagetable(vmm_PDBR->pageTables[pde] & 0xFFFFF000);
|
||||
if (vmm_PDBR->pageTables[pde] == 0x07)
|
||||
return 2; // ERROR 2: page table could not be created
|
||||
}
|
||||
PageTable *ptp = (PageTable *)(vmm_PDBR->pageTables[pde] & 0xFFFFF000);
|
||||
if (ptp->page[pte] & 0x01)
|
||||
return 3; // ERROR 3: page table entry already exists
|
||||
ptp->page[pte] = physical | flags;
|
||||
//invlpg();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int vmm_mapn(dword virtual, dword physical, dword flags, dword n)
|
||||
{
|
||||
int mapped;
|
||||
dword va = virtual;
|
||||
dword pa = physical;
|
||||
for (mapped = 0; mapped < n; mapped++)
|
||||
{
|
||||
vmm_map1(va, pa, flags);
|
||||
va += 4096;
|
||||
pa += 4096;
|
||||
}
|
||||
//invlpg();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vmm_unmap1(dword virtual)
|
||||
{
|
||||
if (virtual & 0x00000FFF)
|
||||
return 1; // ERROR 1: address not page-aligned
|
||||
int pde = (virtual & 0xFFC00000) >> 22;
|
||||
int pte = (virtual & 0x003FF000) >> 12;
|
||||
if (!(vmm_PDBR->pageTables[pde] & 0x01))
|
||||
return 2; // ERROR 2: page table not present
|
||||
PageTable *ptp = (PageTable *)(vmm_PDBR->pageTables[pde] & 0xFFFFF000);
|
||||
ptp->page[pte] = 0;
|
||||
//invlpg();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int vmm_unmapn(dword virtual, dword n)
|
||||
{
|
||||
int reslt;
|
||||
int i;
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
if (reslt = vmm_unmap1(virtual))
|
||||
return reslt;
|
||||
virtual += 4096;
|
||||
}
|
||||
vmm_walkPageTables();
|
||||
//invlpg();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void vmm_init_pagetable(dword address)
|
||||
{
|
||||
PageTable *ptp = (PageTable *)address;
|
||||
int n;
|
||||
for (n = 0; n < 1024; n++)
|
||||
ptp->page[n] = 0;
|
||||
}
|
||||
|
||||
|
||||
int vmm_walkPageTables()
|
||||
{
|
||||
int pde;
|
||||
int pte;
|
||||
int used_ptes;
|
||||
PageTable *ptp;
|
||||
for (pde = 0; pde < 1024; pde++)
|
||||
{
|
||||
if (vmm_PDBR->pageTables[pde] & 0x01)
|
||||
{
|
||||
used_ptes = 0;
|
||||
ptp = (PageTable *)(vmm_PDBR->pageTables[pde] & 0xFFFFF000);
|
||||
for (pte = 0; pte < 1024; pte++)
|
||||
{
|
||||
if (ptp->page[pte] & 0x01) //page table entry present
|
||||
used_ptes++;
|
||||
}
|
||||
if (!(used_ptes)) //no used pte's -- remove page table & page directory entry
|
||||
{
|
||||
mm_pfree(ptp);
|
||||
vmm_PDBR->pageTables[pde] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void *malloc(dword bytes)
|
||||
|
15
vmm.h
15
vmm.h
@ -2,26 +2,13 @@
|
||||
// vmm.h
|
||||
// Author: Josh Holtrop
|
||||
// Date: 09/30/03
|
||||
// Rewritten from scratch: 12/23/03
|
||||
|
||||
|
||||
typedef struct {
|
||||
dword page[1024];
|
||||
} PageTable;
|
||||
|
||||
typedef struct {
|
||||
dword pageTables[1024];
|
||||
} PageDirectory;
|
||||
|
||||
|
||||
void vmm_init();
|
||||
void *malloc(dword bytes);
|
||||
int free(void *ptr);
|
||||
int vmm_map1(dword virtual, dword physical, dword flags);
|
||||
int vmm_mapn(dword virtual, dword physical, dword flags, dword n);
|
||||
int vmm_unmap1(dword virtual);
|
||||
int vmm_unmapn(dword virtual, dword n);
|
||||
void vmm_init_pagetable(dword address);
|
||||
int vmm_walkPageTables();
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user