栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

2021-2022-1 20212808 《Linux内核原理与分析》第五周作业

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

2021-2022-1 20212808 《Linux内核原理与分析》第五周作业

遇到的问题:

关于系统调用函数号的问题,想使用getpid库函数,不知如何查找系统调用号。
可以进入目录LinuxKernel/linux-3.18.6/arch/x86/syscalls/
查看syscall_32.tbl,可以看到系统调用号
getpid()系统调用号为20,转化为十六进制即0x14。
还可以直接搜索linux 系统调用号表

实验四:使用库函数 API 和 C 代码中嵌入汇编代码两种方式使用同一个系统调用
  1. 使用库函数API获取进程识别码
    编写2808.c,只使用了getpid()库函数获取进程识别码,注意:实验楼虚拟机是64位,gcc编译时要加-m32才能输出32位机器码
#include
#include
#include
int main(void)
{
    int u_id;
    u_id=getpid();
    printf("u_id=%un",u_id);
    return 0;
}

运行结果如下:

  1. C语言代码中嵌入汇编代码

进入目录LinuxKernel/linux-3.18.6/arch/x86/syscalls/
查看syscall_32.tbl,可以看到系统调用号
getpid()系统调用号为20,十六进制即0x14

编写2808_asm.c文件:

 #include
#include
int main(void)
{
    int u_id;
    asm volatile(
           "mov $0,%%ebxnt"  
  
           "movl $0x14,%%eaxnt"        
           "int  $0x80nt"                  
           "movl %%eax, %0nt"             
           :"=m" (u_id)
           );
    printf("u_id=%un",u_id);
    return 0;
}

编译运行结果如下:

3. 含两个参数的系统调用rename
rename,它在内核中的系统调用处理函数为sys_rename(),系统调用号为38,其功能是给一个文件重命名。
库函数API进行触发:

#include
int main(){
	int ret;
	char *oldname="hello.c";
	char *newname="newhello.c";
	ret = rename(oldname,newname);
	if(ret == 0)
		printf("Renamed successfullyn");
	else
		printf("Unable to rename the file");
	
	return 0;
}


创建rename.c和hello.c:

修改成功,出现newhello.c:
嵌入式汇编代码进行触发:
编写rename_asm.c,把newhello.c改回hello.c

//rename_asm.c
#include
int main(){
	int ret;
	char *oldname="newhello.c";
	char *newname="hello.c";
	asm volatile( 
    "movl %1,%%ebxnt"                
    "movl %2,%%ecxnt"                
    "movl $0x26,%%eaxnt"           
    "int $0x80nt"                            
    :"=a"(ret) 
    :"b"(oldname),"c"(newname) 
	);
		if(ret == 0)
		printf("Renamed successfullyn");
	else
		printf("Unable to rename the file");
	
		return 0;
}

修改成功,把newhello.c改回hello.c:

系统调用的三层机制(上)
  • 用户态 内核态和中断处理过程
  1. 用户态:在低的执行级别下,代码能够掌控的范围有所限制,只能访问部分内存。
    内核态:在高的执行级别下,代码可以执行特权指令,访问任意的物理内存。
    中断处理:从用户态进入内核态的主要方式。系统调用只是一种特殊的中断。中断发生后第一件事就是保护现场,进入中断程序,保存需要拥戴的寄存器的数据。中断处理结束前的最后一件事就是恢复现场,退出中断程序,恢复保存寄存器的数据。
  2. Intel x86 CPU定义了4种不同的执行级别0、1、2、3,数字越小特权越高。Linux系统采用了其中的0、3两个特权级别,分别对应用户态和内核态。
  3. 用户态和内核态很显著的区分就是CS:EIP的指向范围。用户态只能访问0x00000000~0xbbbbbbbf的地址空间,0xc0000000以上的地址空间只能在内核态下访问。
  • 系统调用概述
    系统调用的意义是操作系统为用户态进程与硬件设备进行交互提供了一组接口。系统调用有以下功能和特性:
    1.把用户从底层的硬件编程中解放出来
    2.极大地提高系统的安全性
    3.使用户程序具有可移植性
  • API和系统调用的关系:
  1. API(应用程序编程接口):只是一个函数定义。
    系统调用通过软中断向内核发出了中断请求,int指令的执行就会触发一个中断请求。
  2. libc函数库定义的一些API内部使用了系统调用的封装例程,其主要目的是发布系统调用。
    一般每个系统调用对应的一个封装例程,函数库再用这些封装例程定义出给程序员调用的API,这样把系统调用最终封装成方便程序员使用的库函数。
  3. API可能直接提供用户态的服务。
    一个API可能只对应一个系统调用,也可能内部由多个系统调用实现;一个系统调用也可能被多个API调用。
  4. 系统调用的三层机制:xyz(),system_call和sys_xyz()
    系统调用号将xyz和sys_xyz关联起来了。
    系统调用需要输入输出参数。
    system_call是linux中所有系统调用的入口点,每个系统调用至少有一个参数。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/343823.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号