pcmattman wrote:If baseaddr is something like 0x1234567, when you do the mapping it'll end up pointing to 0x1234000, which means that your offsets will be wrong. You can fix this by mapping it to the first entry, and then keeping track of a page offset (0x1234567 % 0xFFF = 0x567) which you add to all memory access.
When I allocate the page that will hold the user's code, I ensure it is page aligned; this won't happen. But, as you can see:
Code: Select all
#define PAGEMASK 0xFFF00000 /* Page alignment - is this right? */
#define KPFLAGS 0x83 /* Supervisor level, read/write, present */
U32 *duppdir(void)
{
U32 *tmp;
tmp = (U32 *) kmalloca(1024 * sizeof (U32));
memcpy(tmp, kdir, 1024 * sizeof (U32));
return tmp;
}
U32 addrtopage(void *addr)
{
return ((U32) addr & PAGEMASK) | KPFLAGS;
}
U32 loadexec(U32 inumber)
{
char *sector;
sector = (char *) kmalloca(1024 * sizeof (char));
readinto(0, inumber, 1, sector);
return doregistertask((void (*)(void)) sector, 1);
}
static U32 doregistertask(void (*f)(void), int map)
{
U32 *st, *ebp, i;
cli();
if (nTasks >= 256)
panic("no more tasks");
tasks[nTasks].stack = kmalloca(STACKSIZE * sizeof (U32));
st = &tasks[nTasks].stack[STACKSIZE];
if (map)
*--st = 0;
else
*--st = (U32) f;
for (i = 0; i < 8; i++) /* the eight registers of pusha */
*--st = 0;
tasks[nTasks].esp = st;
tasks[nTasks].e.inuse = 0;
if (map) {
tasks[nTasks].pdir = duppdir();
tasks[nTasks].pdir[0] = addrtopage(f);
} else
tasks[nTasks].pdir = samepdir();
tasks[nTasks].baseaddr = (U32) f;
nTasks++;
sti();
return nTasks - 1;
}
the page directory is set to ensure that the address is made to 0. What I don't understand, however, is why I have to add the baseaddr when the page directory is set. It's like the processor is ignoring the page directory's first item.
Another bit of awkwardness: when I look at the directory entry in the syscall handler, the bit that is supposed to be 0 is set to 1. I don't know what it means...
PGOS. It's my hand-written OS. Deal with it.