2019-2020-1 20199321 "Linux kernel principle and Analysis" in the fifth week of work

The first part notes

内核态:高执行级别,代码可以执行特权指令,访问任意的物理内存,CPU的执行级别对应的就是内核态。
用户态:与内核态相对应的低级别指令,代码能够掌控的范围会受到限制。

Intel x86 CPU有四种不同的执行级别,分别是0,1,2,3其中数字越小,特权越高。Linux操作系统只采用了其中的0和3两个特权级别,分别对 应内核态和用户态.用户态和内核态很显著的区别方法就是CS:EIP的指向范围,内核态CS:EIP的值是任意的,即可以访问所有的地址空间。 用户态只能访问其中的一部分内存地址(0x00000000-0xbbbbbbbf),0xc0000000以上的地址只能在内核态下访问。
CS:代码段选择寄存器  EIP:偏移量寄存器。

中断:由中断触发进入内核态。硬件中断或是由调用系统调用(Trap)引起中断,陷入内核态。从用户态切换到内核态,将用户态寄存器的上下文保存起来,同时将内核态寄存器的值放入当前CPU中。
系统调用的特点:把用户从底层的硬件编程中解放出来;极大的提高了系统的安全性;使用户程序具有可移植性。

系统调用的库函数就是我们使用的操作系统提供的API,系统调用是通过软中断向内核发出中断请求,int指令的执行中触发断请求。
libc函数库内部定义的一些API内部就使用了系统调用的封装历程。每个系统调用对应一个系统调用的封装例程。

  • User Mode indicates the user mode, Kernel Mode represents a kernel mode. xyz () API function is triggered int $ 0x80 () is interrupted corresponds to the start system_call kernel code, that is 0x80 corresponding interrupt vector interrupt service routine entry, there will be internal sys_xyz () system call handler, and then ret_from_sys_call.
  • 3-layer system call mechanism: xyz (); system_call; sys_xyz ().
  • System call number: kernel to differentiate by calling a number to each system. The API function xyz () system call and kernel function sys_xyz () associates.
  • User process must specify which requires a system call, using the EAX register transfer a named system call number of parameters.
  • Different stack system call used when switching from user mode to kernel mode, the transmission parameters can not be passed by way of pushing of the parameters. The number of parameters assigned to EBX ECX EDX ESI EDI EBP order parameter can not exceed six registers. If the parameter is too large, the register as a pointer to put the memory to deliver more parameters.

The second part of the experiment

  • Use the library function system call API
#include<stdio.h>
#include<time.h>
int main()
{
 time_t tt;
 struct tm *t;
 tt=time(NULL);
 t=localtime(&tt);
 printf("time:%d:%d:%d:%d:%d:%d:\n",t->tm_year+1900,t->tm_mon,t->tm_mda,t->tm_hour,t->tm_min,t->tm_sec);
 return 0;
}

  • C code in assembler code embedded system call
#include<stdio.h>
#include<time.h>
int main()
{
 time_t tt;
 struct tm *t;
 asm volatile
 (
    "mov $0,%%ebx\n\t"//把EBX寄存器清0
    "mov $0xd,%%eax\n\t"//eax用于传递系统调用号
    "int $0x80\n\t"//触发系统调用陷入内核执行13好系统调用的内核处理函数
    "mov %%eax,%0\n\t"//系统调用的返回值通过eax返回
    :"=m"(tt)
  );
 t=localtime(&tt);
 printf("time:%d:%d:%d:%d:%d:%d:\n",t->tm_year+1900,t->tm_mon,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
 return 0;
 }
    

  • There are two methods trigger system calls -38


  • Universal trigger system calls syscall
#include<stdio.h>
#include<sys/syscall.h>
int main()
{
 int ret;
 char oldname[]="hello.c";
 char newname[]="newhello.c";
 ret=syscall(38,oldname,newname);
 if (ret==0)
    printf("Renamed successfully\n");
else
    printf("Unable to renam the file\n");
 return 0;
 }


libc does not provide a packaging system call, syscall may be utilized to provide a direct function calls libc

Guess you like

Origin www.cnblogs.com/20199321zjy/p/11686847.html