摘要:1 #define _INTSIZEOF(n) ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) ) 2 #define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) ) //第一个可选参数地址 3 #define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) //下一个参数地址 上面定义的三个宏在可变函数参数的时候用的到下面解释下第三个这里注意下括号ap += _INTSIZEOF(t))这里改变ap这
阅读全文
摘要:复制页目录项和页表的函数是 1 int copy_page_tables(unsigned long from,unsigned long to,long size) 2 { 3 unsigned long * from_page_table; 4 unsigned long * to_page_table; 5 unsigned long this_page; 6 unsigned long * from_dir, * to_dir; 7 unsigned long new_page; 8 unsigned long nr; 9 10 ...
阅读全文
摘要:系统调用是一个软中断,中断号是0x80,它是上层应用程序与Linux系统内核进行交互通信的唯一接口。这个中断的设置在kernel/sched.c中443行函数中 1 void sched_init(void) 2 { 3 int i; 4 struct desc_struct * p; 5 6 if (sizeof(struct sigaction) != 16) 7 panic("Struct sigaction MUST be 16 bytes"); 8 set_tss_desc(gdt+FIRST_TSS_ENTRY,&(init_tas...
阅读全文
摘要:中断分为两种硬件中断和软件中断硬件中断可分为内部中断和外部中断 ,内部中断如除0错误,外部中断如键盘中断另外在提到和外部中断相关的一个芯片,8259A,该芯片用于管理外部中断软件中断用int实现
阅读全文
摘要:第一遍看书时不明白,今天偶然又看到了这一点,顿时豁然开朗linux0.12系统中共用了四种堆栈1. 系统引导初始化时临时使用的堆栈,此时我的理解是系统还在实模式2. 进入保护模式之后提供内核程序初始化使用的堆栈,位于内核代码地址空间固定位置处,该堆栈也是后来任务0的用户态堆栈,个人理解任务0比较特殊,它的内核态堆栈还是用户态堆栈都在内核中。3. 每个任务通过系统调用,执行内核程序时使用的堆栈,我们称之为任务的内核态堆栈,每个人物都有自己的内核态堆栈,内核态堆栈是和任务数据结构一起定义4.任务在用户态执行的堆栈,位于任务逻辑地址空间的末端处。以前有一段时间还怀疑过linux0.12中内核态堆栈和
阅读全文
摘要:软件或处理器可以用以下方式中的任何一种来调度任务执行: 用 CALL 指令显式地调用任务。 用 JMP 指令显式地跳转到任务。 (由处理器)隐式地调用中断处理程序任务。 隐式地调用异常处理程序任务。 EFLAGS 寄存器的NT 标志置位时的任务返回(由IRET 指令发出)。所有这些调度方法都是用指向任务门或任务TSS 的段选择子来识别被调度的任务的。当用CALL 或JMP 指令调度任务时,指令中的选择子可以直接指向TSS,也可以指向包含TSS 选择子的任务门。通过调度任务来处理中断或异常时,相应中断或异常对应的IDT 项必须包含一个任务门,门中含有指向中断或异常处理程序任务
阅读全文
摘要:当处理器执行一个对异常或中断处理例程的调用时:如果将要执行的处理例程特权级数值较小,就进行栈切换。当栈切换发生时:a.处理程序使用的栈的段选择子和栈指针是从当前运行任务的TSS 中获取的。处理器把被中断例程的栈段选择子和栈指针压入新的栈中。b.处理器随后把EFLAGS 寄存器、CS 寄存器、EIP 寄存器的当前值保存进新栈中c.如果异常同时产生了一个错误码,则把它压入栈中,位于EIP 之后。如果将要执行的处理例程与被中断的例程特权级相同:a.处理器在当前栈中保存当前EFLAGS 寄存器、CS 寄存器和EIP 寄存器的值 b.如果异常的错误码也保存在那里,则把它保存在当前栈的EIP 值之后。
阅读全文
摘要:kdb:只能在汇编代码级进行调试; 优点是不需要两台机器进行调试。 gdb:在调试模块时缺少一些至关重要的功能,它可用来查看内核的运行情况,包括反汇编内核函数。 kgdb:能很方便的在源码级对内核进行调试,缺点是kgdb只能进行远程调试,它需要一根串口线及两台机器来调试内核(也可以是在同一台主机上用vmware软件运行两个操作系统来调试)printk() 是调试内核代码时最常用的一种技术。在内核代码中的特定位置加入printk() 调试调用,可以直接把所关心的信息打打印到屏幕上,从而可以观察程序的执行路径和所关心的变量、指针等信息。 Linux 内核调试器(Linux kernel de...
阅读全文
摘要:RET, and its exact synonym RETN, pop IP or EIP from the stack and transfer control to the new address. Optionally, if a numeric second operand is provided, they increment the stack pointer by a further imm16 bytes after popping the return address.ret:也可以叫做近返回,即段内返回。处理器从堆栈中弹出IP或者EIP,然后根据当前的CS:IP跳转到新的
阅读全文
摘要:当段限长为0的时候,代码段的长度并不是零,而是1个长度单位。长度单位取决于颗粒度。当颗粒度为0的时候,段的长度单位是字节,限长0代表段的长度是1字节,即段中可以存储1个字节的内容当颗粒度为1的时候,段的长度单位是4KB,限长0代表段的长度是4KB,即段中可以存储4KB的内容抽象出,当段限长为n的时候,段的长度是(n+1)个长度单位。
阅读全文
摘要:free_page()释放物理地址addr处的一页内存本帖最后由 Gen216ius 于 2011-8-14 21:26 编辑具体解读对着图片看,图片的英文就是代码的变量,注意这里的from是线性地址int free_page_tables (unsigned long from, unsigned long size){ unsigned long *pg_table; unsigned long *dir, nr; if (from & 0x3fffff)// 要释放内存块的地址需以4M 为边界。 panic ("free_page_tables calle...
阅读全文
摘要:1typedef int (*fn_ptr)(); (无内容)typedef int (*funcptr)();// funcptr is synonym for "pointer // to function returning int"funcptr table[10]; // Equivalent to "int (*table[10])();"table[]函数指针数组,每个元素都保存一个函数的入口比如int fun();table[1] = fun;int i = table[1]( );即调用了一个函数fun,并将返回值赋予i。2ret 和i
阅读全文
摘要:init进程调用的init函数1、setup((void*)&drive_info);a.setup函数用的是main.c中Line 25的inline _syscall1(int,setup,void *,BIOS),_syscall1()函数调用来自于include/unistd.h中的Line 1461#define_syscall1(type,name,atype,a)\2typename(atypea)\3{\4long__res;\5__asm__volatile("int$0x80"\6:"=a"(__res)\7:"0&
阅读全文
摘要:读写文件,是作为一个操作系统所提供的最基本接口之一。我们就从写文件过程:open,write,close这几个接口来说起,描述写文件的那些事儿。平时,我们做应用程序的时候,常常用到读写文件的函数接口,就拿写文件来说,我们用C/C++编写时,用到了以下的函数接口:1>FILE* fopen(const char* restrict filename,const char* restrict mode);2>size_t fwrite(const void* restrict buffer,size_t size,size_t n,FILE * restrict fp);3>in
阅读全文
摘要:学习过程中遇到一个对保护模式总结很好的Blog,转来分享一下。先说下特权级的概念,在保护模式下,系统依靠特权级来实施代码和数据的保护,相当于权限啦。特权级共有4个级别,0,1,2,3,数字越小表示权限越高。如图:较为核心的代码和数据放在较高(靠内)的层级中,处理器用此来防止较低特权的任务在不被允许的情况下访问处于高特权级的段。为了防止概念混淆,我们不用特权级大小来说明,改为内层(高),外层(低)来讲。特权级有3种:CPL,DPL和RPL,每个都是有4个等级。我对他们的关系理解是这样:一般来说,CPL代表当前代码段的权限,如果它想要去访问一个段或门,首先要看看对方的权限如何,也就是检查对方的DP
阅读全文
摘要:as86(1) 名称as86 - as86-8086..80386处理器的汇编程序概要格式 as86 [-0123agjuw] [-lm[list]] [-n name] [-o obj] [-b[bin]] [-s sym] [-t textseg] src as86_encap prog.s prog.v [prefix_] [as86 options]描述 as86是8086..80386处理器下的汇编程序,它所采用的语法与Intel/MS采取的语法类似,而不同于广泛运用于UNIX下的汇编语法(译注,gas中的语法,...
阅读全文