Linux中0号进程的创建

2020年2月20日15:09:49
评论

Linux中1号进程是由0号进程来创建的,因此必须要知道的是如何创建0号进程,由于在创建进程时,程序一直运行在内核态,而进程运行在用户态,因此创建0号进程涉及到特权级的变化,即从特权级0变到特权级3,Linux是通过模拟中断返回来实现特权级的变化以及创建0号进程,通过将0号进程的代码段选择子以及程序计数器EIP直接压入内核态堆栈,然后利用iret汇编指令中断返回跳转到0号进程运行。

相关阅读:Linux中1号进程的创建剖析 http://www.linuxidc.com/Linux/2013-07/87010.htm

代码如下:

 move_to_user_mode();//创建0号进程,开始进入0号进程,切换到特权级3运行
 if (!fork()) {init();}//创建1号进程

跟踪代码:

#define move_to_user_mode() \
__asm__ ("movl %%esp,%%eax\n\t" \//将esp寄存器的内容存入eax中
 "pushl $0x17\n\t" \//压入0号任务的数据段选择符
 "pushl %%eax\n\t" \//压入堆栈指针
 "pushfl\n\t" \//压入标志寄存器
 "pushl $0x0f\n\t" \//压入0号任务的代码段选择符
 "pushl $1f\n\t" \//压入EIP,即切换到0号任务后CPU运行的位置
 "iret\n" \//中断返回指令
 "1:\tmovl $0x17,%%eax\n\t" \//由于发生了切换,需要更改各段寄存器
 "movw %%ax,%%ds\n\t" \//更改段寄存器ds
 "movw %%ax,%%es\n\t" \//更改段寄存器es
 "movw %%ax,%%fs\n\t" \//更改段寄存器fs
 "movw %%ax,%%gs" \//更改段寄存器gs
 :::"ax")

分析如下,注释已经很清楚:

代码为嵌入汇编语句的C程序,::”ax”表示的是输出为空,输入为空,在这个宏定义的执行过程中可以发生改变的是ax寄存器,这属于GNU的gas语法,不作解释

0x17与0x0f的真实意义,跟踪查看前先写成二进制形式

0x17=0000 0000 0001 0111

0x0f=0000 0000 0000 1111

企鹅博客
  • 本文由 发表于 2020年2月20日15:09:49
  • 转载请务必保留本文链接:https://www.qieseo.com/178370.html

发表评论