首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

MIT 6.828 操作系统工程 lab1 2018 fall part1 & part2 笔记 and 中文注释源代码阅读

当BIOS找到可引导的软盘或硬盘时,它将512字节的引导扇区加载到物理地址0x7c00至0x7dff的内存中,然后使用jmp指令将CS:IP设置为0000:7c00,将控制权传递给引导程序装载机。...* * 启动步骤 * * 当CPU启动时,它将BIOS加载到内存中并执行 * * * BIOS初始化设备,中断例程集以及 * 读取引导设备的第一个扇区(例如,硬盘驱动器) *...,然后是几个程序段,每个程序段都是要在指定地址加载到内存中的连续代码或数据块。...00000000 0000145c 2**0 CONTENTS, READONLY 引导加载程序使用ELF 程序标头来决定如何加载这些部分,程序标头指定要加载到内存中的...检查程序头:objdump -x obj/kern/kernel ELF对象需要加载到内存中的区域是标记为“ LOAD”的区域。

2.1K50

操作系统启动顺序bios在哪里寻址机制bootloader结构建立段机制使能保护模式

bios在哪里 bios是固化在内存EPROM中的,断电不会丢失(非易失性),这样biod的地址是固定的,因为在cpu第一次加电了之后,寄存器就会有缺省的初始值,所以bios地址=寻址寄存器的缺省值就好啦...因为内存很大,而且在一段时间内操作的内存具有空间局部性,所以可以将内存分为一段一段由段寄存器来定位,这一段的内存中再由指令指针来定位到具体的代码、数据 段寄存器: CS——code segment,代码段寄存器...因为实模式只有20位寻址,所以最大可调用的空间只有1M bios bios是负责做硬件自检并初始化以及将bootloader加载到内存中 要保证硬盘、内存...在后续工作中不会出错。...然后将bootloader加载到内存中的0x7c00,然后跳转到0x7c00执行。...段机制就是中间做了一层映射,CS先定位到GDT(全局描述表)相应的段描述符,再从段描述符中找到段的起始地址,与IP组成物理地址。

1.2K100
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    java开发系统内核:使用LDT保护进程数据和代码

    恶意程序通过在全局描述符表中查找,当找到目标程序的内存描述符后,将对应的描述符加载到自己的ds寄存器里,于是恶意程序访问内存时,就相当于读写目标程序的内存。...要防范此类入侵,最好的办法是让恶意程序无法读取自己内存段对应的描述符,但是如果不把自己的内存描述符放置在全局描述符表中的话,还能放哪里呢?Intel X86架构还给我们提供了另一种选择。...进入multi_task.c看看如何将附带在进程对象上的局部描述符加载到CPU里。...,后面的参数18+4,表示数据段在表中的下标是1,加4也是告诉CPU到局部描述符表中去查找相应的段。...根据加载的TSS数据结构信息,把用户进程的代码和数据加载到内存中。

    78930

    ARM与x86架构对比:从编程视角解析

    与x86相比,ARM架构的设计理念是简化指令集,减少指令数量,提高执行效率。ARM架构通常具有更多数量的通用寄存器,简化了编译器的工作,有助于实现高效、低功耗的运行环境。...x86示例 mov eax, 1 ; 将1加载到eax寄存器 add eax, 2 ; 将eax与2相加 ARM示例 ADD r0, #1 ; 将r0与1相加 ADD r0, r0, #2 ; 将r0与...2相加 ARM架构中使用寄存器(如r0)而非x86中的eax这样的命名寄存器。...此外,ARM中的加法指令可以立即数作为操作数,而x86通常需要先将立即数加载到寄存器中。...内存模型与数据类型 x86内存模型 x86架构支持复杂的寻址模式,如基址加变址、基址加变址加位移等,这使得在访问数组和结构体时更加灵活。然而,这种灵活性也可能导致更复杂的编译器优化和调试工作。

    1.4K10

    【Linux】详解动态库链接和加载&&对可执行程序底层的理解

    三、可执行程序的理解 3.1、可执行程序中区域的划分   可执行程序本身是有自己的格式信息的。我们的可执行程序在被加载到内存中之前,程序当中本身就有地址,可执行程序的每一行都是被编址的。...通常,text (或 code)的大小表示了程序中的指令数量。 data: 这部分包含了程序中已经初始化的全局变量和静态变量的值。 data段的大小表示了程序中已初始化数据的大小。...bss: 这部分用于存储未初始化的全局变量和静态变量。 与 data不同,bss段在程序加载到内存时并不包含实际的数据值,而是只预留了足够的空间。这些变量的初始值通常是0。...hex (hexadecimal): 这表示某个段或整个程序大小的十六进制表示。 与 dec类似,hex值可能是 text、data、bss或整个程序大小的十六进制表示。  ...我们调用的动态库也是要被加载到内存中的,并被映射到进程地址空间的共享区中。当我们的程序执行到动态库调用处,就会根据动态库首地址加偏移量找到页表中在内存中的物理地址,进而就能调用动态库中的方法了。

    2K10

    五万字 | 深入理解Linux内存管理

    在分段内存中,软件可以把物理内存分成一个一个的段,每个段都有段基址和段限长,还有段类型和段权限。段基址和段限长确定一个段的范围,可以防止内存访问越界。...段与段之间也可以互相访问,但是不能随便访问,有一定的规则限制。段类型分为代码段和数据段,正好对应程序的代码和数据,代码段是只读和可执行的,数据段有只读数据段和读写数据段。...分段机制无法禁用的原因是因为CPU特权级是在分段机制中实现的,分页机制没有单独的CPU特权级机制。...(node_data); 查找内存节点的代码如下:linux-src/arch/x86/include/asm/mmzone_64.h extern struct pglist_data *node_data...在异步回收中,内存规整有单独的线程kcompactd,此类线程一个node一个,线程名是[kcompactd/nodeid],页帧回收也有单独的线程kswapd,此类线程也是一个node一个,线程名是[

    3.8K45

    xv6 启动理论部分

    ,以及 APIC ID $0x7c00-0x7dff$,MBR 被加载到此处运行 $0x7c00$ 下面一部分可用区域在 xv6 里面被当作临时栈 $0x7e00-0x9fbff$ 之间的空闲区域 xv6...物理内存与物理地址空间 上述所讨论的内存都是物理内存,所看到的地址都是实际的物理地址。计算机中的内存靠地址总线进行访问,地址总线能够寻址到的空间就叫做物理地址空间。...这样的话寻找合适的内存区域时就很灵活,解决了上述问题。 一级页表与多级页表 页级地址转换 一级页表与多级页表的优缺点是经常讨论的一个问题,这里多级页表我就拿二级页表来举例。...printf 中的格式串,switch-case 中的跳转表 .data:已初始化的全局变量和局部静态变量 .bss:未初始化的全局变量和局部静态变量 .symtab:symbol table,符号表...MBR 主要就是找到这么一个活动分区,将其中的操作系统引导程序加载到内存中,然后将接力棒交给它来执行。

    35700

    学习计算机基础的知识汇总

    内存中存放着程序,程序是指令和数据的集合 I/O中临时存放着用于与周边设备进行输入输出的数据 iO不需要内存那么多的地址引脚(因为内存需要存储大量的程序和数据)只需要能够标识 传输 哪个端口 哪种数据即可...程序里面一般会内置dll文件,便于上层开发对这个设备的处理程序 操作系统内置驱动程序 启动过程中有一个环节就是把当前可用设备的驱动程序加载到运行的系统中(也就是加载到内存中)。...局部变量的内存空间是定义在栈里面的,和全局变量不同的是 并没有单独的data和bss段存储,而是在栈里面通过寄存器和栈里面的内存空间存储的。...在运行时需要的时候会找到这个位置的目标文件并加载到内存中;如果其他程序也需要 就可以直接用这个加载好的而不用像静态链接库一样把本地的 库目标文件再次加载到内存里面。...段的起始地址是运行时候动态分配的 ,目标文件会在开头添加 再配置信息,再配置信息里面会表述 如何将虚拟地址转换为真实的内存地址(再配置信息里面会存储各个不同段和对应段的起始虚拟地址和真实地址的映射关系)

    16510

    浅谈计算机中的存储模型(二)虚拟存储器

    然而物理内存是有限的,如果每个进程都要全部加载到内存中内存肯定不够,后来先辈们就发现我为什么要把进程全部内容加载到内存中去呢。 根据二八定理,百分之百的内容常用的也就百分之二十。...所以只需要将每个进程常用的加载到内存中,不用的先暂存到磁盘,如果需要它时在从磁盘中将它加载出来。...段式管理是通过段表(和页表类似)进行的,它包括段号或段名、段起点、装入位、段的长度等。此外还需要主存占用区域表、主存可用区域表。 在段式存储管理中,每个段地址的说明为两个量:一个段名和一个位移。...在段内,是连续完整存放的。而在段与段之间是不一定连续编址的。段名和位移构成了一种二维编址。 段式管理是不连续分配内存技术中的一种。...段页式内存管理有段表和页表,先通过段表来找到段,在通过段表的段内偏移其实是页框号加页内偏移,这样就再次索引页表来定位。 因为段页式管理是段式管理的页式管理方案结合而成的,所以具有它们二者的优点。

    65400

    segment 寄存器的真实结构

    这里讲解的是 user segment 寄存器,包括: Code 段寄存器:CS Data 段寄存器:ES, SS, DS, FS 以及 GS 这些段寄存器由 user segment descriptor...segment 来说代表 default stack size,B = 1 时 32 位 stack size, B = 0 时 16 位 stack size P 属性:present 位,表示是否加载到内存中...这也就是说:加载到 CS 寄存器的 code segment descriptor 你必须将它的 S 属性设为 1,C/D 属性设为 1 才能加载到 CS 寄存器中 S 属性用来设置 system 还是...user 的段寄存器,属性 system 的段寄存器有:LDTR 寄存器和 TR 寄存器 C/D 属性用来指示是 Code 还是 Data 段。...descriptor 的 S 属性需设为 1,C/D 属性需设为 0 才能加载到 data segment registers 中 对 DS 段寄存器来说,S 必须为 1 并且 C/D 为 0 表明它是用户的数据段寄存器

    1.7K20

    程序员需要了解的硬核知识之汇编语言(一)

    段定义的英文表达具有区域的意思,在这个程序中,段定义指的是命令和数据等程序的集合体的意思,一个程序由多个段定义构成。...段定义是一段连续的内存空间 而group 这个伪指令表示的是将 _BSS和_DATA 这两个段定义汇总名为 DGROUP 的组 DGROUP group _BSS,_DATA 围起 _AddNum 和...本地代码需要加载到内存后才能运行,内存中存储着构成本地代码的指令和数据。程序运行时,CPU会从内存中把数据和指令读出来,然后放在 CPU 内部的寄存器中进行处理。 ?...寄存器是 CPU 中的存储区域,寄存器除了具有临时存储和计算的功能之外,还具有运算功能,x86 系列的主要种类和角色如下图所示 ?...向栈中存储数据称为 入栈 ,从栈中读出数据称为 出栈,32位 x86 系列的 CPU 中,进行1次 push 或者 pop,即可处理 32 位(4字节)的数据。

    63710

    AArch64 学习(一) 基础指令, 内存布局, 以及基础栈操作

    RISC 的一些特点: 精简指令集提供的指令更简单, 更基础一些, 也就是说, 和 x86/64 相比, 同样的代码, 生成的指令会多一些. 内存访问和计算是完全分离的....Operation 描述指令的作用, 比如 ADD 表示加, AND 进行逻辑与操作 Destination 总是为寄存器, 存放操作的结果 Op1, 指令的第一个输入参数, 总是为寄存器 Op2, 指令的第二个输入参数...X0 str X0, [X1] // 访问内存可以加一个 offset, 相当于把 X0 保存到 新地址 = (地址 X1 + 4) 对应的内存中. lrd 也同理. str X0, [X1, #4...进程内存布局 熟悉程序加载到内存之后的布局, 对编写/阅读汇编代码至关重要, 这里我们熟悉一下经典的内存布局, 主要目的是方面理解后面的汇编代码. 这里不展开西说, 更详细的大家可以自行查询资料....堆, 堆空间主要是用来动态分配内存的, 我们用的 malloc, new 等申请的内存空间都会在这个区域, 权限会读写. 分配的虚拟内存地址由小增大, 所以是向上增长的.

    2.6K30

    嵌入式:ARM汇编语言程序设计基础教程

    ; R2作为计数器 LDR R3, [R0] ; 将源数据块x中第一个数加载到R3中 compare ADD R0, R0, #4 ; 每进行一次比较,将R0指针地址加4...LDR R0, =n ; 将数据段中自然数的个数n的地址加载到R0寄存器 LDR R1, =sum ; 将数据段中自然数的累加和sum的地址加载到...这样编写程序时,就不必重复写这段代码了,而这样的程序段称为子程序或子过程。 子程序的调用与返回 主程序中使用BL指令实现子程序的调用 BL 子程序名 在子程序结束处,使用如下指令返回到主程序中。...三种参数传递方式 寄存器传递参数方式 存储区域传递参数方式 堆栈传递参数方式 寄存器传递参数方式 例:用子程序实现内存区里的字符串拷贝功能,即将存储单元中源字符串对应拷贝到目的字符串中。...实现方法:当主程序与子程序有较多的数据需要传递时,可以通过共享内存区或传内存数据块地址方式来传递批量数据。

    1.3K30

    实战局部描述符表 LDT

    内存中只能有一个 GDT,但却可以存在多个 LDT,如上图所示,每个 LDT 作为 GDT 中一个描述符描述的内存段。 通常,一个 LDT 用于划分一个特定任务执行过程中需要使用的内存分段。 3....描述符结构 LDT 描述符与 GDT 描述符的结构是一模一样的: 可以参看: 详解 32 位保护模式与内存分段机制 4....后记 在例如 80286 等没有分页功能的处理器上,LDT 提供了多个进程实现独立地址空间的功能,每个用户进程分配一个单独的 LDT 来描述私有内存,实现每个进程单独的内存特权级等属性的定义,同时,GDT...由于 GDT 描述的内存对于所有进程来说都是可见的,且具有相同权限,如果需要为每个进程单独定义权限,也可以通过定义 LDT 的方式来解决,具体做法是创建 LDT 描述符,定义独立的属性,但内存指向 GDT...但是,通过 LDT 来解决进程间内存独立的问题,其代价是寄存器的反复加载,这对于 CPU 来说是一件较为耗时的操作,于是,80386 开始,Intel 引入了内存分页功能,相比于 LDT,更为灵活高效,

    83330

    连接器 -- Scatter File & Linker Script File

    @(嵌入式) [TOC] 源文件编译后生成 elf 格式的目标文件(各种.o), 与运行时库经过连接器处理后,生成可以被写入嵌入式设备 ROM 中的 elf 格式文件。...-- “rom 中”) 输出段 1 (运行时对应的一块存储区域 -- “ram中”’) 输入段 1(编译出来个各个.o) 输入段 2 多个输入段 输入段 包含代码/数据 (属性可能是 : R0...举个例子, 字符串 uint8* hell = "hell world"编译后,运行前保存在ROM中的地址 A, 在运行时被加载到内存中 B, 这里 A 就是加载时地址, 而程序运行时读取的地址时B,...运行时地址 映像文件运行后加载到存储器的地址 举个例子 区域 加载时地址 --> 运行时地址 RAM RAM ZI段 RAM RW段 ROM RW段 ROM RO段 RO段 程序运行时...当运行时, 数据被加载到内存区域 ARM 映像文件入口点 地址分类 : 映像文件运行时入口地点, 称为初始入口点 (Intial Entry Point) 唯一性,加载文件后跳转到的入口 普通入口点

    1.9K20

    程序的组成、存储与运行

    一般 MCU 包含的存储空间有:片内 Flash 与片内 RAM, RAM 相当于内存, Flash 相当于硬盘。编译器会将一个程序分类为好几个部分,分别存储在 MCU 不同的存储区。...fromelf 转换成.bin或.hex文件,交给下载器下载到芯片的 FLASH 或 ROM 中。...Program Size 包含以下几个部分: 1) Code:代码段,存放程序的代码部分; 2) RO-data:只读数据段,存放程序中定义的常量; 3) RW-data:读写数据段,存放初始化为非...左图是可执行映像文件烧录到 STM32 后的内存分布,它包含 RO 段和 RW 段两个部分:其中 RO 段中保存了Code、 RO-data 的数据, RW 段保存了 RW-data 的数据,由于 ZI-data...另外根据编译器给出的 ZI 地址和大小分配出 ZI 段,并将这块 RAM 区域清零。

    1.4K31

    4 汇编语言程序设计

    4 汇编语言程序设计 表达式中的运算符和操作符在 x86 汇编语言中的用法。 表达式 表达式是由常数、变量、操作符和运算符组合而成的计算公式。...运算符类型 算术运算符: +(加)、-(减)、*(乘)、/(除)、MOD(取模) 这些用于基本的数学运算。...操作符类型 分析运算符: OFFSET:返回变量或标号的偏移量(地址的低16位)。常用于将内存地址加载到寄存器中。...示例:MOV SI, OFFSET BUF(将 BUF 的偏移量存入 SI 寄存器) SEG:返回变量或标号所在段的基址。常用于将段地址加载到寄存器中。...示例:MOV BYTE PTR [SI], 200(将 200 存入 SI 指定的内存地址处,强制按字节存储) 简单例子 假设我们有一个内存地址 BUF,需要将它的偏移量加载到 SI,并把它所在段的段基址加载到

    10410

    ELF文件程序表头和代码实现ELF文件加载

    程序表头反映的是当ELF加载到内存后所形成的“视图”或结构,也就是说ELF文件存在硬盘上或者被加载到内存,它展现出来的形态不一致。....dynamic,这意味着这些段需要加载到内存中,同时每个表头对应的段都要合成一个整体加载到表头中所指定的位置。...PT_FLAGS对应段加载到内存后的读写权限,常用的值有PF_X,PF_W,PF_R。PF_X表示表头对应的段可以被执行,PF_W对应加载的那些段可以被修改,PT_R表示加载的段可以被读取。...p_offset表示表头对应那些段的起始地址,p_vaddr表示表头对应段该加载的虚拟位置,p_filesz表示表头对应段在硬盘上的大小,p_memsz表示表头对应段在加载到内存后的大小。...load_binary是来自libbfd库提供的函数,它将elf文件加载到内存中。

    1.7K30

    xv6(2) 启动代码部分

    ,内存低 $1M$ 的顶部 $64KB$ 都是分配给 系统$BIOS$ 的,所以此时内存布局为: $BIOS$ 是一个只读的 $ROM$ 区域,操作系统无能为力,一般是不能改动 $BIOS$ 程序的,但是我们知道它的执行流程...) # data seg 数据段描述符 写权限 段选择子($mmu.h$): #define SEG_KCODE 1 // kernel code #define SEG_KDATA...2 // kernel data+stack 根据 $SEG_ASM$ 宏构建了两个段描述符:代码段描述符和数据段描述符,因为代码段在 GDT 中的索引设为 1,所以先构建的代码段描述符。...$ 将 $elf$ 文件展开到正确的内存区域 来捋捋加载内核时的内存变化情况,$bootmain$ 加载内核,怎么加载的,加载到哪儿。...jmp *%eax,使用间接跳转,直接从 $eax$ 中获取目的地的绝对地址,否则使用直接跳转的话,会生成相对寻址的编码,也就是会将目标指令的地址与紧跟在跳转指令后面那条指令的地址之间的差作为编码 $main

    39800

    Linux内核之旅张凯捷——系统调用分析(2)

    主要信息有: (1)sysenter与sysexit指令配套,可以以比较高的执行效率在用户态执行要在系统态执行的系统调用。...(174H):指定要执行Ring0代码的代码段选择符,也能得出目标Ring0所用堆栈段的段选择符 - IA32_SYSENTER_EIP(176H):指定要执行的Ring0代码的起始地址...将SYSENTER_EIP_MSR的值装在到eip寄存器。 将SYSENTER_CS_MSR的值加8(Ring0的堆栈段描述符)装载到ss寄存器。...在Ring0代码执行完毕,调用sysexit指令退回Ring3时,CPU会做出如下操作: 将SYSENTER_CS_MSR的值加16(Ring3的代码段描述符)装载到cs寄存器。...将寄存器edx的值装载到eip寄存器。 将SYSENTER_CS_MSR的值加24(Ring3的堆栈段描述符)装载到ss寄存器。 将寄存器ecx的值装载到esp寄存器。 将特权级切换到Ring3。

    2K20
    领券