跳过正文
  1. 博客/
  2. 随笔/
  3. 编程/

引导和操作系统的交互

·3 分钟· ·
随笔 编程 MIT6.828
目录

引言
#

本来自己查了很多资料,想自己写出来,结果下笔的时候发现别人已经把我想写的部分全部写出来了,而且比我想的还要具体,所以我就不写了,把链接放出了,顺便我补充一些

http://leenjewel.github.io/blog/2014/07/29/%5B%28xue-xi-xv6%29%5D-cong-shi-mo-shi-dao-bao-hu-mo-shi/

http://leenjewel.github.io/blog/2015/05/26/%5B%28xue-xi-xv6%29%5D-jia-zai-bing-yun-xing-nei-he/

ELF文件
#

首先你要知道什么是ELF,可以看一下这篇博客,简单来说就是编译完C后的机器码,前面加了一些数据表记录程序的分布情况

为了帮助我们逆向分析这些代码有什么,我们必须要借助两个工具

  • objdump
  • readelf

我们接下来就用实际例子解读mit6.828里面的引导和核心

引导
#

首先我们查看一下引导文件,在boot/目录下有两个文件

  • boot.S
  • main.c

两者是通过gcc编译器将汇编和C编译成为一个elf文件,具体在Makefile文件中(boot/Makefrag),我将它简单翻译一下

 gcc -N -e start -Ttext 0x7C00 -o boot.out boot.o main.o
  

boot.omain.o就是boot.Smain.c编译后的文件,-e start意思程序从boot.Sstart中开始运行(这样就能从汇编开始执行),-Ttexttext代表代码段,也就是说直接指定代码入口地址为0x7C00,我们可以用readelf验证一下

mit-6.828-2014 ➤ readelf -h obj/boot/boot.out                         git:lab1*
  
ELF Header:
  
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  
  Class:                             ELF32
  
  Data:                              2's complement, little endian
  
  Version:                           1 (current)
  
  OS/ABI:                            UNIX - System V
  
  ABI Version:                       0
  
  Type:                              EXEC (Executable file)
  
  Machine:                           Intel 80386
  
  Version:                           0x1
  
  Entry point address:               0x7c00
  
  Start of program headers:          52 (bytes into file)
  
  Start of section headers:          4868 (bytes into file)
  
  Flags:                             0x0
  
  Size of this header:               52 (bytes)
  
  Size of program headers:           32 (bytes)
  
  Number of program headers:         2
  
  Size of section headers:           40 (bytes)
  
  Number of section headers:         9
  
  Section header string table index: 6
  

我们读取了一下生成的elf文件头部,我们可以看到Entry point address这个字段,就是我们设定的0x7c00,要了解这个地址的含义我们必须知道虚拟地址和物理地址的区别,可以看一下这篇博客,接着我们看一下反汇编的汇编代码obj/boot/boot.asm中,我们知道现在0x7c00代表程序把自己当做在内存上的真实内存上面,但是不一定会真的存在这块上,所以我们称它为虚拟的

首先我们了解一个系统知识,因为电脑启动后会按照启动盘顺序,把每个盘第一个扇形区512B取出来,如果最后两个字节为0xAA55的话就把它放到内存上面的0x7c00上去,我们看一下我们生成的obj/boot/boot

使用hexdump obj/boot/boo可以看到(我把最后一行复制出来)

00001f0 0000 0000 0000 0000 0000 0000 0000 aa55
  

最后连个字节为0xaa55,且文件大小刚刚好512B,这时候你可以有一个疑惑了,我们知道gcc我们生成的boot.out的elf文件,但是这个文件还有头部存贮数据,我们如果把整个文件放到磁盘上,当程序在内存0x7c00处执行时,那么文件头部碰到的就是elf头了,所以
为了把机器码提取出来并生成合适文件(512B尾部为0xaa55),程序干了两件事

  • 用objcopy将elf文件中执行代码提取出来(相当于去掉elf头部)
  • 用脚本修改尾部两字节(在boot/sign.pl用了perl程序来将生成512B且尾部为0xaa55boot文件)

总结
#

后面将核心加载到内存,上面的给出资料写的很详细,我就不多说,只不过由于当前2014的版本同资料有点不同,这里我提一下

当前版本是将内核头加载在0x10000上,然后在把内核代码加载到0x100000上(前面4个0,后面5个0,我当初看错了,百思不得其解),并将内核地址映射到f0100000上。

由于资料给的操作系统与2016的操作系统实现细节有点不同,其中最主要的就是一个很重要的KERNBASE常量值由0x80000000变成0xf0000000,这个变量牵扯到了在给出的book-rev8.pdf资料中第一章的最后一个问题,我就把我对这个问题的思考放到这篇文章中。

引用
#

http://leenjewel.github.io/blog/2014/07/29/%5B%28xue-xi-xv6%29%5D-cong-shi-mo-shi-dao-bao-hu-mo-shi/

https://my.oschina.net/u/864891/blog/87965

端口信息

相关文章

内存分页
·2 分钟
随笔 编程 MIT6.828
引言 # 本来自己查了很多资料,想自己写出来,结果下笔的时候发现别人已经把我想写的部分全部写出来了,而且比我想的还要具体,所以我就不写了,把链接放出了,顺便我补充一些
什么是操作系统
·8 分钟
随笔 编程 MIT6.828
引言 # 本文是基于mit6.828 的lab1对操作系统的思考,网上有不少关于lab1的博客,大部分都是介绍如何完成lab1的问题,介绍的比较详细的有这个博客,在这里我就不从问题出发,建议大家看完上面的博客在看我这篇博文,我这篇博文就是从把我遇到的疑惑提炼出知识点,然后再把这些知识点串起来
从CS寄存器看段的前世今生
·2 分钟
随笔 编程 MIT6.828
引言 # Intel作为作为微处理器的航头老大,一直引导CPU的进步发展,也正是因为Intel是一个有着历史包袱的企业,所以站在现代CPU看起来,有一些非常奇葩的设计遗留下来,这些设计一开始是为了兼容,慢慢的将这种兼容又发展成新的功能,把“包袱”转换成“亮点”,段设计就是其中的一个很重要的代表,要想搞懂这个设计在不同的CPU的如何保持兼容和强化,我们必须要慢慢的把CPU的历史给捋顺。
mit6.828课程总结
·2 分钟
随笔 编程 MIT6.828
引言 # 一开始想直接做一个操作系统,但是万事开头难,学习操作系统需要太多基础知识了,所以就按照网上推荐先学习mit6.828的课程,先把xvf6操作系统搞懂,然后在来实现自己的操作系统,下面就是学习这个课程的体会,按照各个lab的顺序,介绍自己的心得体会
AVL树实现原理
·2 分钟
随笔 编程
本篇博客主要基于这篇博客的扩展,建议阅读前先阅读这篇博文,这篇博文详细介绍AVL树的实现原理,完整代码在github的avl.go文件中 浅谈"树"这种数据结构 Github 可视化页面 引言 # AVL树是在对二叉搜索树的一种优化,通过构造一棵高度平衡的二叉搜索树从而实现提高空间利用率,所以在了解如何实现之前,必须了解如何构造一棵二叉搜索树,你可以阅读我的这篇博客了解如何构建一棵二叉搜索树,虽然我是用Go来实现的,但是不必了解太多Go方面的知识,我在博客中尽量使用图片的方式来介绍实现原理
二叉搜索树实现原理
·4 分钟
随笔 编程
本篇博客主要基于这篇博客的扩展,建议阅读前先阅读这篇博文,这篇博文详细介绍二叉搜索树的实现原理,完整代码在github的binary.go文件中 浅谈"树"这种数据结构 Github 可视化页面 引言 # 之所以使用Go来实现,个人还是比较喜欢Go的,作为一个基础数据结构,Go用来实现这个速度比Java、C++都快,而且相比Java也能节省内存,而且我也不喜欢换使用冒号。