|
为什么内核空间读应用空间的数据要用get_user(),而传到应用空间要用put_user()这二个宏呢。查了很多书都没说明,书上只是说内核空间和应用空间不能直接读写,要通过这二个宏来实现(char,int,long类型的数),但没说明为什么,我看了这二个宏的ASM,实现也是通过间接地址实现的,内核空间在0XC0000000地址上面,应用空间在0XC0000000下面,为什么不能直接用直接用C语言的 *dst=*src 来实现呢,这点一直没弄明白。有那位兄弟指点一下我这个菜鸟。
如下面这个装载a.out文件执行格式建立程序运行之前的堆栈的函数,在内核空间读用户空间的数据,又把它cp到用户空间去,为什么不能用 *dst = *src实现呢。
static unsigned long * create_aout_tables(char * p, struct linux_binprm * bprm)
{
char **argv, **envp;
unsigned long * sp;
int argc = bprm->argc;
int envc = bprm->envc;
sp = (unsigned long *) ((-(unsigned long)sizeof(char *)) & (unsigned long) p);
#ifdef __sparc__
/* This imposes the proper stack alignment for a new process. */
sp = (unsigned long *) (((unsigned long) sp) & ~7);
if ((envc+argc+3)&1) --sp;
#endif
#ifdef __alpha__
/* whee.. test-programs are so much fun. */
put_user(0, --sp);
put_user(0, --sp);
if (bprm->loader) {
put_user(0, --sp);
put_user(0x3eb, --sp);
put_user(bprm->loader, --sp);
put_user(0x3ea, --sp);
}
put_user(bprm->exec, --sp);
put_user(0x3e9, --sp);
#endif
sp -= envc+1;
envp = (char **) sp;
sp -= argc+1;
argv = (char **) sp;
#if defined(__i386__) || defined(__mc68000__) || defined(__arm__) || defined(__arch_um__)
put_user((unsigned long) envp,--sp);
put_user((unsigned long) argv,--sp);
#endif
put_user(argc,--sp);
current->mm->arg_start = (unsigned long) p;
while (argc-->0) {
char c;
put_user(p,argv++);
do {
get_user(c,p++);
} while (c);
}
put_user(NULL,argv);
current->mm->arg_end = current->mm->env_start = (unsigned long) p;
while (envc-->0) {
char c;
put_user(p,envp++);
do {
get_user(c,p++);
} while (c);
}
put_user(NULL,envp);
current->mm->env_end = (unsigned long) p;
return sp;
} |
|