文章 35
评论 44
浏览 88230
[6]完善内核(内联汇编、c混编)

[6]完善内核(内联汇编、c混编)

完善内核 1:函数调用约定 参数传递方式---------存放在栈中 在函数未执行前发生进程切换,参数还是需要转移阵地,寄存器又太少,干脆直接放在内存中 为了避免多进程的参数覆盖问题,将参数放在进程自己的栈中。 参数压栈顺序---------从右向左,栈空间的清理员----------调用者(仅限在当前cdecl调用约定下) 由于编写函数的程序员或者调用函数的人都知道需要调用的参数,所以这些工作其实有谁做都可以,只需要双方做好约定即可。调用约定例如有cdecl,syscall,optlink,thiscall cdecl ( C declaration,即 C 声明〉,起源于 C语言的一种调用约定,在c语言中,函数参数是 从右到左的顺序入梭的。 GNU/Linux GCC,把这一约定作为 准, x86 架构上的许多 C 编译器也都使用这个约定。在 cdecl 中,参数是在栈中传递的。 EAX、 ECX 和 EDX 寄存 器是由调用者保存的,其余的寄存器由被调用者保存.函数的返回值存储在 EAX 寄存器。 由 调用者清理栈空间 2:汇编、c混编 为何要混编: 汇编可以直接操作寄....

[7]了解中断的实现——逐步深入底层

[7]了解中断的实现——逐步深入底层

中断 1:中断概述 并发和并行的区别: 单核cpu-并发:单位时间内的积累工作量,如在一秒内cpu处理了100个请求量 多核cpu-并行:真正同时进行的工作量,如在任意瞬间cpu正在同时处理100个请求量 系统有了中断,才能够并发运行,能够不断的切换进程。 操作系统是中断驱动的,本身是一个死循环while(1){ 操作系统代码 },所以系统是在循环中等待事件的发生,被动的调用资源去处理,而事件是由中断去通知系统的的。 2:中断类型 外部中断:由外部硬件发出的中断信号,再细分有可屏蔽中断和不可屏蔽中断 内部中断:内部发出,再细分有软中断和异常 补充:软中断int3断点调试指令,常用在GDB和Bochs调试器,具体的原理是 父进程(调试器)fork了一个子进程,来运行被调试的程序,当用户在调试器(Bochs举例)上输入b 0xXXXXXXXX指令时,父进程会将该地址的指令的第一个字节备份,再用0xcc(int3的机器指令)替换 这样再输入c运行,子进程运行到断点处就会触发3号中断,进行中断处理程序,但在此之前,还需保存当前的寄存器和栈的状态,所以用户查看寄存器和栈都是在栈中的值。 ....

[5]加载C语言内核(从汇编世界进入C语言世界)

[5]加载C语言内核(从汇编世界进入C语言世界)

生成C语言程序的过程: 说明:.o文件是可重定位文件,重定位指的是文件里面所用的符号还没有安排地址,这些符号的地址需要将来与其他目标文件“组成”一个可执行文件时再重新定位(编排地址) 符号是调用的函数或者变量 可执行文件可由几个目标文件组成,如kernel内核多个代码文件,生成kernel.bin文件 组成即链接操作 编排地址就是对程序中的代码安排对应的地址 具体链接调试过程: int _main(void) { while(1); return 0; } main.C:链接阶段必须明确程序的入口地址,默认的entry symbol 是_start,所以主函数函数名用这个表示。 (入口地址不是代码的起始地址,因为代码开始可能是数据,非指令) 接下来gcc -m32 -c -o main.o main.c ,再ld -m elf_i386 main.o -Ttext 0xc0001500 -o kernel.bin 前面生成可重定位文件,后面可执行文件 -c:生成目标文件,非可执行文件 -Ttext xxx:加载到起始虚拟地址xxx处 默认入口地址用_start表示,若自定义入....

了解x86下的特权级原理

了解x86下的特权级原理

特权级 为什么TSS中只有3个栈信息:因为任务处于最低的3特权级,而TSS中记录的栈是用于特权级从低特权级变成高特权级时,CPU会自动进行栈更新的作用,所以3特权级没有比它更低的特权级了,不需要放在TSS中。 那高特权返回到低特权级的情况下,cpu如何找到3特权级栈呢? 方法是:一般是用户程序调用函数进入依从代码段下的原函数前,在高特权级栈中记录返回栈指针和返回地址,之后retf或iret返回时可以从栈中恢复。 CPL: CPU当前特权级,等于CS段描述符的RPL值 DPL:“如果你想访问我,你应该具备什么样的权限” RPL:用什么权限去访问一个段 ,用于解决CPU“越权”问题 平坦模式下,用户进程不需要再提供选择子,所以调用门可以用中断门代替了 ?? 在调用内核服务例程时,段寄存器可能会加载到0特权级的段,但是在retf返回时CPU并不会压入段寄存器或者重新加载用户的段寄存器,这就导致返回到用户态后,存在段寄存器(CS和SS除外)还是内核特权级别的危险。 解决方法: Linux调用内核例程使用中断门,在中断处理程序返回前手动更新所有寄存器(恢复上下文)。 处理器中进行特权级检查,如....

杭电操作系统实验三:linux进程管理

杭电操作系统实验三:linux进程管理

实验三:linux进程管理 1)实现一个模拟的shell 问题:编写三个cmd1.c、cmd2.c、cmd3.c程序,功能自定。需要一个仿shell的程序和实现类似执行grep、find等命令的程序。通过在仿shell中输入命令(字符串和参数),创建子进程来执行相应的命令程序,父进程需要等待子进程处理结束后,才能再去查看是否有新的命令。输入“exit”退出shell程序。输入无效命令则显示“Command not found”,等待下一个新命令。 前说下,刚开始把问题看复杂了,除了要求之外还写了cd、pwd、exit、mkdir,所以可以自行删改(不麻烦),或者有兴趣可以加更多的命令玩玩 : ) 处理方法: myshell.c: 提供循环输入命令模块 解析命令 判断命令是内置命令还是外置命令(可以不用) 内置命令直接调用函数,外置命令用fork()来创建一个子进程, 在进程中执行命令程序采用exec族的函数来调用函数执行。 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #in....

[3]cpu的8086实模式、显卡、硬盘

[3]cpu的8086实模式、显卡、硬盘

cpu的8086实模式、显卡、硬盘相关信息。

Life Is Like A Boat