记录一些学习哈工大操作系统实验的学习笔记和心得
int iam(const char * name); // 将字符串内容保存到内核中
int whoami(char* name, unsigned int size); // 在内核中将iam()保存的信息拷贝到指定的用户地址空间中
./iam zhaojiazhen
./whoami
zhaojiazhen
补充:调用系统调用和调用一个普通的自定义函数在代码上并没有什么区别,但是不同的是,系统调用可能会涉及到内核交互
sys_whoami
和sys_iam
,然后进行调用相当于直接执行了系统调用代码printf
则是通过头文件中的syscall
来访问system_call.s
进而调用80中断来,然后调用sys_xxx
函数实现的首先我们需要知道实现一个系统调用需要修改哪些部分(这部分需要重点理解):
sys_call
sys_call1
sys_call2
sys_call3
sys_call
则是通过传入参数到int 0x80
实现的int 0x80
进行系统调用的原理是通过system_call.s
实现的system_call.s
通过system_call_table
实现,进而根据中断号调用系统调用函数unistd.h
添加有关__NR_IAM
和__NR_whoami
的系统调用号system_call.s
中更新系统调用数量linux/sys.h
中添加
extern int sys_iam
extern int sys_whoami
call_table
数组中添加相关调用完成上述修改后,还需要根据教程修改Makefile
OBJS
Dependices
通过教程我们可以发现,用户态和核心态数据交互所需要的函数为:
include/asm/segment.h/get_fs_byte
include/asm/segment.h/put_fs_byte
接下来就可以开始实现iam()
和 whoami()
函数了
kernel/
下创建who.c
int sys_iam(const char *name)
{
printk("hello, i'm sys_iam\n");
char tmp[maxSize];
int i;
for (i = 0; i < maxSize; i++)
{
tmp[i] = get_fs_byte(name + i);
if (tmp[i] == '\0')
break;
}
if (i == maxSize)
return -EINVAL;
else
{
strcpy(msg, tmp);
return i;
}
}
int sys_whoami(char *name, unsigned int size)
{
printk("hello, i'm sys_whoami\n");
int msg_size = 0;
while (msg[msg_size] != '\0')
msg_size++;
if (size < msg_size)
return -EINVAL;
else
{
int i;
for (i = 0; i < size; i++)
{
put_fs_byte(msg[i], name + i);
if (msg[i] == '\0')
break;
}
return i;
}
}
之后编译img镜像,进入linux0.11之后,编译iam
和whoami
运行如下命令即可
tips:为了防止出现编译或者其余问题,可以考虑先不实现
iam
以及whoami
函数的具体逻辑,先使用printk
来进行输出,测试函数是否真正起到了作用。
./iam zhaojiazhen
./whoami
zhaojiazhen
出现上述,证明完成了实验
实验报告