做单挣钱的网站,做汽车配件的都在那个网站做呀,wap手机网站建站,教你如何建立网站第一章
配置bochs#xff0c;进入bochs simulator后一直是黑屏#xff0c;原来默认是调试模式#xff0c;需要输入C#xff08;continue#xff09;来让调试继续。
第二章
主讲MBR及进入MBR前的步骤 1.实模式只能访问1MB的内存空间。 2.BIOS在ROM中。 3.开机上电后CS进入bochs simulator后一直是黑屏原来默认是调试模式需要输入Ccontinue来让调试继续。
第二章
主讲MBR及进入MBR前的步骤 1.实模式只能访问1MB的内存空间。 2.BIOS在ROM中。 3.开机上电后CSIP指向内存0xfff0这里有个跳转语句转到fe05b才是真正的BIOS程序之后检测内存显卡灯建立数据结构中断向量表和填写中断例程。
第三章
主讲实模式 段的大小统一64KB段基址代表内存的起始偏移地址代表段内偏移量。 section:节只是为了让程序员在逻辑上将程序划分为几个部分伪指令 vstart:告诉编译器以新的数字作为后面数据的地址的起始值
第四章
进入保护模式 段描述符专门用来描述一个内存段大小为8字节 全局描述符(GDT) 1.相当于描述符的数组可以用选择子中提供的下标在全局描述符表中索引描述符。 2.位于内存中需要GDTR寄存器指向他CPU才知道在哪。通过lgdt加载GDTR指令格式是lgdt48位内存数据48位前16位是以字节为单位的界限值后32位是GDT的起始地址。2^166553665536/88192所以最多存储8192个段或门。 3.在保护模式下由于段基址已经存入段描述符段寄存器没必要再存段基址了所以段寄存器存入选择子通过选择子在GDT中找到段描述符从而得到内存段起始地址和段界限值。选择子低2位存储了RPL可以表示0、1、2、3四种特权级第2位是TI位用来选择是GDT还是LDT索引描述符。而选择子的索引部分有13位所以最多索引8192个段和GDT存储的数量相同 注意GDT中第0个段描述符是不可用的原因是如果选择子忘记初始化则值为0为避免误操作如果访问第0个描述符处理器将发出异常。 局部描述符(LDT) 现代操作系统中很少使用LDT CPU厂商建议每个任务的私有内存段都应该放到自己的段描述符表中该表就是LDT即每个任务都有自己的LDT随着任务切换也要切换相应任务的LDT。下面是Linux0.11内核中描述符的关系 从相应的内核代码中我们看到在task_struct的声明中有如下内容
struct task_struct { ... struct desc_struct ldt[3]; struct tss_struct tss; }; 这说明ldt是和每个task有关。每当需要创建新的process时就需要在内存中把一块相应的区域划分给这个process的LDT。 部分参考自http://blog.csdn.net/aotony_1988/article/details/50935897
第五章
先回忆下上章内容并解释一些不清楚的地方。 一个进程的地址空间从用户的角度看是由若干的段segment组成的这些段可以分为两种私有段private、共享段shared。cpu也是按照用户的逻辑进行内存管理的分段Intel Pentium规定了每种段最多有8K个每个segment最大4G。一个cpu对应有一个GDTglobal descriptor table该表详细描述了shared segment这个表为所有进程共享的一个process对应有一个LDTlocal该表详细描述了该process的private segment这个表是进程私有的。 我们的程序是处在一个个的Segment中的无论是指令还是数据。我们在程序中打印出一个变量的地址其实是段内的偏移地址32位程序的16bit段号由操作系统分配管理我们是看不见的但是的确存在。 注意注意注意以上的解释中为简单没有说明分页
总之SegmentSelector16bit 段内Offset32bit 一个32bit的地址值 其实这个就是虚拟地址。将这个地址转换为物理地址就需要用他到页目录表中找到页表的地址再到页表中找到真实物理地址。 部分参考自http://blog.csdn.net/yleek/article/details/8204393 如果存储器采用基本分页机制那么操作系统会为每个进程或任务建立一个页表这个页表可能是一级的也可能是多级的。整个操作系统中有多个进程在运行那么系统就会有多个页表。页表在内存中的存储位置由寄存器CR3给出。 如果存储器采用基本分段机制那么操作系统会为每个进程或任务建立一个段表一般不用多级用于记录数据段、代码段等各类段在内存中的具体位置。 如果采用段页式结合的机制那么一般一个进程或任务操作系统会给其建立一个段表而段表中的每个段又会对应一个页表也就是说段页式机制的每个进程有一个段表有多个页表。 对于典型的Linux系统而言操作系统会维护一个全局描述符表相当于系统的段表全局描述符表中用于记录系统任务和用户任务的描述符其中用户任务的描述符又指向用户任务的局部描述符表相当于用户任务的段表。因此要说linux中的分段机制用的是一张大表我个人认为也是有道理的。
这本书里采用的是第一种方案一个进程一个页表这个页表是二级的。将页目录表和页表紧挨在一起如下图所示 这里将两个表都存在内核空间的低端内存处这样通过cr3的物理地址可以马上找到页表因为内核空间是真实线性的即虚拟地址和物理地址一样。每一个进程的页表都放在一起其实还有其他的放置方法可见此贴http://bbs.csdn.net/topics/390956135?page1
快表
虚拟地址到物理地址转换有一个缓存器快表存储少量的转换关系能加快转换速度。转换时一般先查快表查不到再查页表项。
启动分页流程
1准备好目录表和页表 2将页表地址写入控制寄存器cr3 又称为页目录基址寄存器 3寄存器cr0的PG位置1 tips 在64位的Linux下gcc 编译 32 位程序需要添加参数 -m32 ld需要添加参数是 -m elf_i386。
第六章
本章讲了一些函数调用 汇编和C语言混合编程等知识 1.cdecl调用由调用者清理栈空间即将栈顶往上加。 2.LINUX系统调用入口只有一个 0X80 中断描述符表中的一项 具体调用子功能由eax指定。 3.调用函数当输入的参数小于等于 5 个时, Linux 用寄存器传递参数。当参数个数大于 5 个时,把参数按照顺序放入连续的内存区域,并将该区域的首地址放到 ebx 寄存器。tips fatal error: sys/cdefs.h: No such file or directory| Try these: sudo apt-get purge libc6-dev sudo apt-get install libc6-dev
In case of -m32: sudo apt-get install libc6-dev-i386
源码中LOADER_STRAT_SELECTOR一直在boot.inc里定义位0x2 所以Loader.bin应放到硬盘第二个扇区 --------------------- 作者月黑风高云游诗人 来源CSDN 原文https://blog.csdn.net/lqygame/article/details/73801091 版权声明本文为博主原创文章转载请附上博文链接