GRUB2 分析 (三)
接上一篇
从地址0x8200开始的是lzma_decompress.img。这是由startup_raw.S编译生成的。这个文件稍微复杂点。首先一开始就是个跳转指令:
ljmp $0, $ABS(LOCAL (codestart)) /* 机器码:ea 1c 82 */
跳转到0x821c,这里是真正的开始代码。0x8203到0x821b之间存放的是一些特殊数据,如压缩数据前后的长度、冗余数据的长度等,由GRUB安装时填写,后面会用到。
接下来设置实模式堆栈后,切换到保护模式:DATA32 call real_to_prot
然后打开Gate A20,即第21根地址线的控制线: call grub_gate_a20 这是在80286时代IBM想出来的通过开闭Gate A20来兼容8086/8088实模式的方法。在保护模式下,为了正常寻址必须把Gate A20打开。
然后开始利用里德-所罗门(Reed Solomon)算法对GRUB受保护数据进行检查和修复:
call EXT_C (grub_reed_solomon_recover)
RS恢复代码是用C写的,文件是lib/reed_solomon.c。编译时会先编译成rs_decoder.S然后被startup_raw.S包含。(最新的GRUB版本应该生成的文件名是rs_decoder.h,只是改了个名字。)
RS保护的范围以reed_solomon_part标记开始(Gate A20代码后,多重启动代码前),到lzma_decompress.img结尾,再到后面接着的压缩过的kernel.img映像结尾。在此后面是冗余数据区。冗余数据是被算法利用对受保护数据进行修复的。
这样算来GRUB数据的前5个扇区(0-4)以及部分第6个扇区是不受保护的,其他都受到了保护。
为什么要做这件事情?如之前提到的,硬盘2-62号扇区是不安全的,有可能被其他软件写入数据破坏。利用冗余数据,GRUB有能力从这种破坏中正常引导,如果破坏的数据量在可接受范围内的话。我记得GRUB社区有一场讨论,关于如何处理与其他软件冲突的问题。就像一场罗马元老院辩论一样,有人忿忿不平,觉得这种在保留扇区写隐藏数据的行为是邪恶的,GRUB应该以牙还牙,数据恢复过来后,就应该写回硬盘,虽然这会造成其他软件不能工作。也有人认为,普通用户并不会理解这里面的是非曲折,而把一切问题怪罪到GRUB头上,GRUB应仅仅支持防御性的操作。
RS恢复操作执行完后跳转到标记post_reed_solomon对余下的压缩过的kernel.img进行解压缩:
jmp post_reed_solomon /* 偏移量:0x07a6,不同版本会有差异 */
解压后的数据存放在地址0x100000开始的内存区域。
解压算法采用LZMA算法。具体实现在lzma_decode.S中,是手工优化精简的版本。
最后执行跳转指令:
jmp *%esi /* GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR = 0x100000 */
跳转到地址0x100000执行下一条指令。也就是刚才解压缩出来的第一条指令。
至此startup_raw.S执行完毕。
GRUB2 分析 (三)的更多相关文章
- tomcat源码分析(三)一次http请求的旅行-从Socket说起
p { margin-bottom: 0.25cm; line-height: 120% } tomcat源码分析(三)一次http请求的旅行 在http请求旅行之前,我们先来准备下我们所需要的工具. ...
- 一些有用的javascript实例分析(三)
原文:一些有用的javascript实例分析(三) 10 输入两个数字,比较大小 window.onload = function () { var aInput = document.getElem ...
- Java线程池ThreadPoolExecutor使用和分析(三) - 终止线程池原理
相关文章目录: Java线程池ThreadPoolExecutor使用和分析(一) Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理 Java线程池Thr ...
- 使用react全家桶制作博客后台管理系统 网站PWA升级 移动端常见问题处理 循序渐进学.Net Core Web Api开发系列【4】:前端访问WebApi [Abp 源码分析]四、模块配置 [Abp 源码分析]三、依赖注入
使用react全家桶制作博客后台管理系统 前面的话 笔者在做一个完整的博客上线项目,包括前台.后台.后端接口和服务器配置.本文将详细介绍使用react全家桶制作的博客后台管理系统 概述 该项目是基 ...
- Nouveau源代码分析(三):NVIDIA设备初始化之nouveau_drm_probe
Nouveau源代码分析(三) 向DRM注冊了Nouveau驱动之后,内核中的PCI模块就会扫描全部没有相应驱动的设备,然后和nouveau_drm_pci_table对比. 对于匹配的设备,PCI模 ...
- Linux I2C驱动分析(三)----i2c_dev驱动和应用层分析 【转】
本文转载自:http://blog.chinaunix.net/uid-21558711-id-3959287.html 分类: LINUX 原文地址:Linux I2C驱动分析(三)----i2c_ ...
- [ipsec][strongswan] strongswan源码分析-- (三) xfrm与strongswan内核接口分析
目录 strongwan sa分析(三) xfrm与strongswan内核接口分析 1. strongswan的实现 2. 交互机制 4. xfrm的消息通信的实现 strongwan sa分析(三 ...
- 13 数组 Java内存分析 三种初始化
Java内存分析 三种初始化 静态初始化 //静态初始化 创建+赋值 int[] a = {1,2,3}; Man[] mans = {new Man(1,1),new Man(2,2)}; 动态初始 ...
- ABP源码分析三:ABP Module
Abp是一种基于模块化设计的思想构建的.开发人员可以将自定义的功能以模块(module)的形式集成到ABP中.具体的功能都可以设计成一个单独的Module.Abp底层框架提供便捷的方法集成每个Modu ...
随机推荐
- 从远程(包括ftp,http等协议)地址获取文件流信息
URL url = new URL("ftp://172.18.251.155:8010/recordsImg/2019-01-28/000008_1548649813267.jpg&quo ...
- string整理
/* scanf是c语言的,而string是c++的类,所以不能使用scanf直接读入 */ #include<cstdio> #include<string>//注意支持库 ...
- kindeditor在Java项目中的应用以及图片上传配置
在官网下载Kindededitor的开发包 在项目中javaweb项目中导入kindeditor必须要使用的Jar包(用于文件上传,除非你的富文本编辑器不使用图片上传)jar包可以在官网的开发包中 ...
- Tortoise SVN 使用
1.添加文件或文件夹 2.删除文件或文件夹 ①If you want to delete an item from the repository, but keep it locally as an ...
- 2017 Multi-University Training Contest - Team 3—HDU6058 Kanade's sum
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6058 题目意思:给你一个排列,求所有区间长度大于等于k的区间第k大的数的和…… 思路:一开始看到区间k ...
- c#自定义控件窗体Click无法点击Lable的处理解决方案
自定义控件做按钮,不继承Button,用Lable来做按钮文字时,点击空白处有效,但是点击lable不起作用的处理方案. 很简单,就是在Lable添加Click事件,事件中添加代码:OnClick(e ...
- 自己开发Thinkpad电源管理程序
自己开发Thinkpad电源管理程序 - 知乎 https://zhuanlan.zhihu.com/p/20706403
- mysql json
SELECT name, profile->"$.twitter" AS `twitter` FROM `user` WHERE profile->"$.tw ...
- 正则表达式验证合法的IP地址
IPv4地址 最初设计互联网络时,为了便于寻址和层次化构造网络,每个IP地址包括两个标识码(ID),即网络ID和主机ID.同一个物理网络上的所有主机都使用同一个网络ID,网络上的一个主机(包括网络上的 ...
- 如何理解PHP的单例模式
单例模式就是让类的一个对象成为系统中的唯一实例,避免大量的 new 操作消耗的资源. PHP的单例模式实现要求: 1.一个private的__construct是必须的,单例类不能在其它类中实例化,只 ...