研究内核也两三个月了,今天读了个copy_strings(),晚上没啥事,写写心得:
这个函数是用来复制指定个数的参数字符串到参数和环境变量中的,它的一大特点是用到了许多get_ds()和
get_fs_long()等函数,它们的定义在segment.h文件中。首先设置new_fs,old_fs,是为from_kmem服务的,如果
from_kmem == 1或者2,则设置fs指向内核空间,否则指向用户空间。如果指向内核空间,不要忘记在函数返回时将fs还原回去。在copy_strings()函数之前fs曾被设置为指向用户空间(sys_call.s中的_system_call:z)。
下面我们来看看这个函数的重点(我认为的),tmp = (char *)get_fs_long(((unsiged long *)argv)+argc),argv 参数指针数组,argc参数个数,若如图,则argv+argc指向0x223c,get_fs_long()这个函数是用来读取fs段中指定地址处的4字节长度,于是我们便得到了0xabcd,tmp也就变成了指向地址0xabcd的地址变量(指针),之后我们设len = 0;,然后进入循环,再一次执行get_fs_byte(tmp++)函数,该函数取地址0xabcd处的字节,于是得到一个字符,依次循环,因为串是以NULL为结尾的,所以可以退出循环。退出循环后,我们便得到了该参数的长度,以此长度为基础,我们又进入了一个while(len)循环,上来一个if(--offset < 0)因为offset = 0;在前面已经设置过了,所以if判断语句为真,进入offset = p % PAGE_SIZE;,这条语句设置在一个页面中(PAGE_SIZE)的当前那指针
偏移量,它和后面的p / PAGE_SIZE,相辅相成,p / PAGE_SIZE计算出来的是走过了多少个页, p % PAGE_SIZE计算出来的是,下一个页内p的位置,也就是页内偏移offset.后面的就没什么了。时间不早了,睡了。