Update memory.c

master
mp6sgfx3h 2 years ago
parent 853e2526ca
commit 75bd7f750b

@ -147,7 +147,7 @@ int free_page_tables(unsigned long from,unsigned long size)
* 1 Mb-range, so the pages can be shared with the kernel. Thus the * 1 Mb-range, so the pages can be shared with the kernel. Thus the
* special case for nr=xxxx. * special case for nr=xxxx.
*/ */
int copy_page_tables(unsigned long from,unsigned long to,long size) int copy_page_tables(unsigned long from,unsigned long to,long size )
{ {
unsigned long * from_page_table; unsigned long * from_page_table;
unsigned long * to_page_table; unsigned long * to_page_table;
@ -809,3 +809,160 @@ mytag:
/*
esp
eipret 0xec8353c3 ps:0xc3
eipeipret
int (*fn)(void *) fnexit
*/
/* int do_clone(int nr,long tmp,int (*fn)(void *), void *child_stack, int flag)
{
//设置压栈表,方便操作;
long stack[1024];
unsigned long len=0;
task[nr]->tss.esp=(unsigned long) child_stack - 8;
stack[0] = (unsigned long) fn;
task[nr]->tss.eip = (unsigned long) child_stack - 4;
stack[1]= 0xec8353c3;
//栈区赋值;
len = 8;
char *p1=stack ,*p2=(char *)((unsigned long)child_stack-len);
while(len--)
put_fs_byte(*(p1++),p2++);
return 0;
} */
/* child_stack-4 00 00 00 00 */
/* child_stack-8 00 00 00 00 */
/* child_stack-12 arg */
/* child_stack-16 fn */ //esp
/* child_stack-20 00 00 00 00 */
/* child_stack-24 00 00 00 00 */
/* child_stack-28 00 00 00 00 */
/* child_stack-32 0x000000c3 */
/*
int do_clone(int nr,long tmp,int (*fn)(void *), void *child_stack, int flag)
{
void * argv =NULL;
//共享物理页写法有缺陷可能child——stack跨页
//子进程task[nr]的页表项获取目的是更新成child——stacK的物理页
unsigned long nrfrom_page,nrfrom,from_page,from,tpage,address;
address = task[nr]->tss.esp;
nrfrom_page = ((address>>20) & 0xffc);
nrfrom_page += ((task[nr]->start_code>>20) & 0xffc);//页目录
nrfrom=*(unsigned long *)nrfrom_page; //页表项
if(!(nrfrom&1)) //无页表项分配一个
{
if(!(tpage=get_free_page()))
{
printk("out of memory.\n");
return -1;
}
else
{
*(unsigned long *)nrfrom_page= tpage | 7;
mem_map[(tpage-LOW_MEM)>>12]++;
}
}
nrfrom &= 0xfffff000;
nrfrom_page = nrfrom + ((address>>10) & 0xffc);
//获取child_stack的物理页,并将其复制给task[nr];
address=(unsigned long) child_stack;
from_page = ((address>>20) & 0xffc);
from_page += ((current->start_code>>20) & 0xffc);//页目录
if(!(*(unsigned long *)from_page&1)) //页表项不存在,申请页面
if(!(tpage=get_free_page()))
{
printk("out of memory.\n");
return -1;
}
else
{
*(unsigned long *)from_page= tpage | 7;
mem_map[(tpage-LOW_MEM)>>12]++;
}
from=*(unsigned long *)from_page; //页表项
from &= 0xfffff000;
from_page = from + ((address>>10) & 0xffc);
if(!(*(unsigned long *)from_page & 1)) //物理页不存在
if(!(tpage=get_free_page()))
{
printk("out of memory.\n");
return -1;
}
else
{
*(unsigned long *)from_page= tpage | 7;
mem_map[(tpage-LOW_MEM)>>12]++;
}
//复制给nr
*(unsigned long *)nrfrom_page = *(unsigned long *)from_page;
unsigned long stack[128];
unsigned long off=(unsigned long)child_stack & 0xfff;
if(off < 32)
{
printk("地址跨页,我也没办法.\n");
return -1;
}
//更新esp,让其指向child_stack同样偏移的地点;
//注意这里child_stack 指向的是高地址要向下面push.
task[nr]->tss.esp &=0xfffff000;
task[nr]->tss.esp |=off - 16;
//eip 只有一条ret //所以传进来的fn必须以exit结尾不能return ,
//因为我不会return这个玩意push ebp 又pop 啥的
task[nr]->tss.eip &=0xfffff000;
task[nr]->tss.eip |=off - 32;
//ret eip
stack[0]=0x000000c3;
stack[4]=(unsigned long)fn;
stack[5]=(unsigned long)argv;
char * p1=stack, *p2=(unsigned long) child_stack - 32,len=32;
while(len--)
put_fs_byte(*(p1++),p2++);
printk("nr:%d::fn:%x\n",nr,(unsigned long )fn);
return 0;
}
*/
int copy_page_tables_clone(unsigned long from,unsigned long to,long size )
{
unsigned long * from_page_table;
unsigned long * to_page_table;
unsigned long this_page;
unsigned long * from_dir, * to_dir;
unsigned long nr;
if ((from&0x3fffff) || (to&0x3fffff))
panic("copy_page_tables called with wrong alignment");
from_dir = (unsigned long *) ((from>>20) & 0xffc); /* _pg_dir = 0 */
to_dir = (unsigned long *) ((to>>20) & 0xffc);
size = ((unsigned) (size+0x3fffff)) >> 22;
for( ; size-->0 ; from_dir++,to_dir++) {
if (1 & *to_dir)
panic("copy_page_tables: already exist");
if (!(1 & *from_dir))
continue;
from_page_table = (unsigned long *) (0xfffff000 & *from_dir);
if (!(to_page_table = (unsigned long *) get_free_page()))
return -1; /* Out of memory, see freeing */
*to_dir = ((unsigned long) to_page_table) | 7;
nr = (from==0)?0xA0:1024;
for ( ; nr-- > 0 ; from_page_table++,to_page_table++) {
this_page = *from_page_table;
if (!(1 & this_page))
continue;
*to_page_table = this_page;
if (this_page > LOW_MEM) {
*from_page_table = this_page;
this_page -= LOW_MEM;
this_page >>= 12;
mem_map[this_page]++;
}
}
}
invalidate();
return 0;
}
Loading…
Cancel
Save