|
|
|
@ -463,7 +463,42 @@ int sys_umask(int mask)
|
|
|
|
|
return (old);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int my_share(unsigned long address, struct task_struct * p)
|
|
|
|
|
{
|
|
|
|
|
unsigned long from;
|
|
|
|
|
unsigned long to;
|
|
|
|
|
unsigned long from_page;
|
|
|
|
|
unsigned long to_page;
|
|
|
|
|
unsigned long phys_addr;
|
|
|
|
|
|
|
|
|
|
from_page = to_page = ((address>>20) & 0xffc);
|
|
|
|
|
from_page += ((current->start_code>>20) & 0xffc);
|
|
|
|
|
to_page += ((p->start_code>>20) & 0xffc);
|
|
|
|
|
|
|
|
|
|
from = *(unsigned long *) from_page;
|
|
|
|
|
from &= 0xfffff000;
|
|
|
|
|
from_page = from + ((address>>10) & 0xffc);
|
|
|
|
|
phys_addr = *(unsigned long *) from_page;
|
|
|
|
|
to = *(unsigned long *) to_page;
|
|
|
|
|
if (!(to & 1))
|
|
|
|
|
if (to = get_free_page())
|
|
|
|
|
*(unsigned long *) to_page = to | 7;
|
|
|
|
|
else
|
|
|
|
|
return 0;
|
|
|
|
|
to &= 0xfffff000;
|
|
|
|
|
to_page = to + ((address>>10) & 0xffc);
|
|
|
|
|
if (1 & *(unsigned long *) to_page)
|
|
|
|
|
return 0;
|
|
|
|
|
/* share them: write-protect */
|
|
|
|
|
*(unsigned long *) to_page = *(unsigned long *) from_page;
|
|
|
|
|
phys_addr -= LOW_MEM;
|
|
|
|
|
phys_addr >>= 12;
|
|
|
|
|
mem_map[phys_addr]++;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// rememeber to sync when munmap exit manual
|
|
|
|
|
|
|
|
|
|
long sys_mmap(void * start,size_t len,...)// int prot,int flags,int fd,off_t off
|
|
|
|
|
{
|
|
|
|
|
printk("start mmaping\n");
|
|
|
|
@ -475,27 +510,37 @@ long sys_mmap(void * start,size_t len,...)// int prot,int flags,int fd,off_t off
|
|
|
|
|
int *ll=&len;printk("%d,%d,%d,%d,%d\n",*ll,*(ll+1),*(ll+2),*(ll+3),*(ll+4));
|
|
|
|
|
va_end(args);
|
|
|
|
|
printk("%d,%d,%d,%ld\n",prot,flags,fd,off); */
|
|
|
|
|
|
|
|
|
|
int block;
|
|
|
|
|
size_t l=len;
|
|
|
|
|
struct buffer_head * bh;
|
|
|
|
|
char *temp,*p1,*p2;
|
|
|
|
|
void * buf=start;
|
|
|
|
|
int tempprot=0;
|
|
|
|
|
|
|
|
|
|
//因为new.h和namei.c定义不一样,要修改
|
|
|
|
|
if(prot &PROT_READ) tempprot |=4;
|
|
|
|
|
if(prot &PROT_EXEC) tempprot |=1;
|
|
|
|
|
if(prot &PROT_WRITE) tempprot |=2;
|
|
|
|
|
//特殊量
|
|
|
|
|
if(!len || off<0 || (off%PAGE_SIZE)) return MAP_FAILED;
|
|
|
|
|
|
|
|
|
|
//特殊量len>0 off%4096==0 prot至少有read权限
|
|
|
|
|
if(len<=0 || off<0 || (off%PAGE_SIZE))
|
|
|
|
|
{
|
|
|
|
|
if(len<=0)
|
|
|
|
|
printk("the len of the wanting bytes must be positive");
|
|
|
|
|
else
|
|
|
|
|
printk("offset must be the mul of 4096");
|
|
|
|
|
return MAP_FAILED;
|
|
|
|
|
}
|
|
|
|
|
if(!(prot& PROT_READ)) return MAP_FAILED;
|
|
|
|
|
//permissions of the file
|
|
|
|
|
printk("end of permissions0\n");
|
|
|
|
|
|
|
|
|
|
//permissions of the file ,搬运函数namei.c::permissions
|
|
|
|
|
printk("fd: %d\n",fd);
|
|
|
|
|
struct m_inode *inode=current->filp[fd]->f_inode;
|
|
|
|
|
printk("end of permissions\n");
|
|
|
|
|
int mode = inode->i_mode;
|
|
|
|
|
if (inode->i_dev && !inode->i_nlinks)
|
|
|
|
|
{printk("end of permissions1\n");;return MAP_FAILED;}
|
|
|
|
|
{printk("end of permissions1\n");return MAP_FAILED;}
|
|
|
|
|
else if (current->euid==inode->i_uid)
|
|
|
|
|
mode >>= 6;
|
|
|
|
|
else if (current->egid==inode->i_gid)
|
|
|
|
@ -507,6 +552,9 @@ long sys_mmap(void * start,size_t len,...)// int prot,int flags,int fd,off_t off
|
|
|
|
|
}
|
|
|
|
|
//end of permission check
|
|
|
|
|
printk("end of permissions\n");
|
|
|
|
|
|
|
|
|
|
//设置用户空间的虚拟地址,初始为32MB处,这样写在brk增长至32MB时会有bug,我们忽略
|
|
|
|
|
//同时,当栈向下增长到一定程度时,也会和当前地址冲突,我们忽略
|
|
|
|
|
if(start<=current->brk || start>=current->start_stack-0x8000 || start==NULL)
|
|
|
|
|
{
|
|
|
|
|
if(!current->mmap_tail)
|
|
|
|
@ -514,24 +562,76 @@ long sys_mmap(void * start,size_t len,...)// int prot,int flags,int fd,off_t off
|
|
|
|
|
else
|
|
|
|
|
buf=current->mmap_tail->endaddr;
|
|
|
|
|
}
|
|
|
|
|
//申请mmap
|
|
|
|
|
struct mmap_struct *mmap=(struct mmap_struct *)malloc(sizeof(struct mmap_struct));
|
|
|
|
|
mmap->address=buf;mmap->size=len;
|
|
|
|
|
mmap->endaddr=buf+(len + 0xfff)&0xfffff000;
|
|
|
|
|
mmap->rw=prot;mmap->ps=flags;
|
|
|
|
|
mmap->address=buf;
|
|
|
|
|
mmap->size=len;
|
|
|
|
|
mmap->endaddr=(unsigned long)buf+(len + 0xfff)&0xfffff000;
|
|
|
|
|
mmap->rw=prot;
|
|
|
|
|
mmap->ps=flags;
|
|
|
|
|
mmap->next=NULL;
|
|
|
|
|
//加入current->mmap
|
|
|
|
|
if(!current->mmap)
|
|
|
|
|
{current->mmap=current->mapp_tail=mapp;}
|
|
|
|
|
{current->mmap=current->mmap_tail=mmap;}
|
|
|
|
|
else
|
|
|
|
|
current->mmap_tail->next=mapp;
|
|
|
|
|
current->mmap_tail->next=mmap;
|
|
|
|
|
printk("buf: %x\n",(unsigned long )buf);
|
|
|
|
|
|
|
|
|
|
//分配物理页
|
|
|
|
|
|
|
|
|
|
unsigned long from;
|
|
|
|
|
unsigned long to;
|
|
|
|
|
unsigned long from_page;
|
|
|
|
|
unsigned long to_page;
|
|
|
|
|
unsigned long phys_addr;
|
|
|
|
|
unsigned long tpage;
|
|
|
|
|
unsigned long address=mmap->address;
|
|
|
|
|
while(address<mmap->endaddr)
|
|
|
|
|
{
|
|
|
|
|
from_page = ((mmap->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 MAP_FAILED;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
*(unsigned long *)from_page= tpage | 7;
|
|
|
|
|
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 MAP_FAILED;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
*(unsigned long *)from_page= tpage | 7;
|
|
|
|
|
*(unsigned long *)from_page &= (prot&PROT_WRITE); //分配读写权限
|
|
|
|
|
if(flags & MAP_SHARED)
|
|
|
|
|
{
|
|
|
|
|
struct task_struct ** p;
|
|
|
|
|
|
|
|
|
|
for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
|
|
|
|
|
if (!*p)
|
|
|
|
|
continue;
|
|
|
|
|
if (current == *p)
|
|
|
|
|
continue;
|
|
|
|
|
if(!my_share(address,*p))
|
|
|
|
|
printk("share failed at task:pid=%d",(*p)->pid);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
address+=PAGE_SIZE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//read and put in
|
|
|
|
|
if (!(block = inode->i_zone[0]))
|
|
|
|
|
return NULL;
|
|
|
|
|
if (!(bh = bread(inode->i_dev,block)))
|
|
|
|
|
return NULL;
|
|
|
|
|
temp = (char *) bh->b_data;
|
|
|
|
|
printk("end of mmap\n");
|
|
|
|
|
p1=temp;p2=buf;
|
|
|
|
|
while(l--)
|
|
|
|
|
put_fs_byte(*(p1++),p2++);
|
|
|
|
|