move_to_user_mode()函数分析

来源:互联网 发布:js splice函数 编辑:程序博客网 时间:2024/06/06 03:34

在linux0.1.1内核中,系统从main函数执行开始到达到“怠速”状态,主要的工作分为三个部分:

1、创建进程0,并让进程0具备在32位保护模式下在主机中运算的能力;

2、以进程0为母本创建进程1,使进程1不仅具有进程0的能力,还有以文件方式与外设进行数据交互的能力;

3、以进程1为母本创建进程2,使进程2在拥有进程1全面能力和环境的情况下,进一步具备支持人机交互的能力,最终实现“怠速”。

(ps:道生一,一生二,二生三,三生万物   是不是就是这种感觉?)


        按照规则,除了进程0,其他所有的进程都应该是由父进程在用户态下完成创建的,所以为了遵守这个规则,进程0要先变成用户态才能创建进程1,方法就是调用move_to_user_mode()函数。

#define move_to_user_mode() /  __asm__ ( "movl %%esp,%%eax/n/t" /     "pushl $0x17/n/t" /         "pushl %%eax/n/t" /         "pushfl/n/t" /          "pushl $0x0f/n/t" /          "pushl $1f/n/t" /       "iret/n" /              "1:/tmovl $0x17,%%eax/n/t" /    "movw %%ax,%%ds/n/t" /   "movw %%ax,%%es/n/t" "movw %%ax,%%fs/n/t" "movw %%ax,%%gs":::"ax")  

   

       在iret之前,之前5个push压入的数据会出栈,分别赋给ss,esp,eflags,cs,eip,与通常中断引起的压栈顺序是一样的。“ pushl $0x17/n/t ”代表的是SS段选择符。0x17中的17用二进制表示是00010111。最后两位表示特权级是用户态还是内核态。linux0.1.1中特权级分为0,1,2,3共4个特权级,用户态是3,内核态是0。因此它表示的是用户态。倒数第三位是1,表示从LDT中获取描述符,因此第4~5位的10表示从LDT的第2项(从第0项开始)中得到有关用户栈段的描述符。

        同理,“ pushl $0x0f/n/t ” 代表的是CS段选择符,0x0f中的0f为00001111,也是用户特权级,从LDT中的第1项(从第0项开始)中取得用户态代码段描述符。当iret返回时,程序将数据出栈给ss,esp,eflags,cs,eip,之后就可以使进程进入用户态。

0 0
原创粉丝点击