热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

linux卡在grub_浅析GRUB如何加载Linuxkernel

前言对于GRUB的加载流程,网上绝大部分都是写对menu.lst,grub.cfg这些GRUB配置文件的编写流程,就像是写脚本语言一样,用

前言

对于 GRUB 的加载流程,网上绝大部分都是写对 menu.lst, grub.cfg 这些 GRUB 配置文件的编写流程,就像是写脚本语言一样,用些关键字就能让 PC机能正确启动桌面 Linux 了。但这只是 GRUB 的使用,而不是GRUB的分析。

本来是没有想要探究 GRUB 的想法,直到我在自制toy kernel 的学习中进入了 “虚拟内存管理”这一章节。很多介绍虚拟内存管理的时候都会说到 Linux 的内存管理,Linux 内核会加载到系统 3G~4G 的虚拟内存中, 但 GRUB 是没有开启虚拟内存的,Linux 内核的加载是被谁,又是如何加载相应段到 3G~4G 区的呢。

分析 kernel

vmLinux

我们看下内核源码编译后的最原始文件 vmLinux。该文件是 ELF 文件,使用 readelf 读下该文件的 Section header.

这里只截了几个段显示,后面的段都类似. 可以看到这些需要加载的段的地址的确是在 0xC0000000 之后。但 vmLinux 并不是可引导的Linux 内核文件。

Linux启动的相关信息一般都在 `/boot` 下,我们看下里面的内容.

可以看到 grub 文件夹,grub 就是引导 Linux 进行启动的 bootloader,我们看下 `/boot/grub/grub.cfg` 文件的内容。

menuentry 'Linux Mint 17 {

recordfail

gfxmode $linux_gfx_mode

insmod gzio

insmod part_msdos

insmod ext2

set root='hd0,msdos1'

linux /boot/vmlinuz-3.13.0-24-generic

initrd /boot/initrd.img-3.13.0-24-generic

}

带有 linux 的一行就指定了启动的内核,可以看到不是 vmlinux 文件,而是 vmlinuz 文件。

vmlinuz

搜索后可以看到 vmlinuz 是**可引导的,压缩**的内核。 initrd 是"initial ramdisk" 的简写,是临时的虚拟磁盘,暂时不讨论。 因为我电脑上 vmlinuz 是64 bit的,对 64bit不太了解,所以找了个 32bit 的vmlinuz 文件来作解析。先试试`readelf`命令。

# readelf -S vmlinuz

readelf:错误: Unable to read in 0x7269 bytes of 节头

readelf:错误: 不是 ELF 文件 - 它开头的 magic 字节错误

不是 ELF 文件, 那试试 `objdump` 吧。

# objdump -afh vmlinuz

objdump: vmlinuz: 不可识别的文件格式

还是不行。

这个时候之所以会相当用这些命令看 vmlinuz 文件的段信息,因为在我的 toy kernel 中使用的是 ELF 文件,而且是使用 grub 加载的,对于 ELF 文件来说内部保护若干 section, 执行时这些 section 必须要在特地的内存地址上. 使用 `readelf` 查看toy kernel 的 section header 信息如下.

可以看到 Addr 段就是内核运行时这些段在内存中的地址。而加载我的内核的 grub 的配置如下

title toy kernel

root (fd0)

kernel /zkernel

module /initrd

vmlinuz 之所以叫做压缩的内核,是因为它是使用 gzip 压缩后得来,而且不单单是个纯数据包,在文件开头部分内嵌有 gzip 解压缩代码,相当于"自解压"。我的内核需要由grub加载好相应的 section, 但 vmlinuz 都读不出来段如何让 grub 加载?

其实答案就在上面的 grub 配置文件里,在 linux 中声明内核使用的是 *linux* 关键字,在我的配置中声明内核使用的却是 *kernel*. 可以明确看出,grub对 linux 的加载是特殊对待的, 但具体怎么特使对待,只能从源代码里看了。



推荐阅读
  • GPS 校验和 代码_Linux recovery 移除签名校验
    原创作者:王锐,多年Linux系统、龙芯平台移植与优化研发经验,LinuxContributor、Mozillian。背景某个设备配套的刷 ... [详细]
  • 是不是zlib是这些库的压缩算法的实现库,而这么多库它们只是在打包的时候使用了zlib进行压缩而已.而具体的打包格式就有ZIP,BZIP2,GZ之分?但是在我们在用gz压缩时候通常之前 ... [详细]
  • iic协议
    IIC简介IIC,Inter-IntegratedCircuit,集成电路总线,需要2根线连接拓扑,是半双工,适用于”字节型”设备。I2C总线物理拓扑结构IIC通信原理: 通过对S ... [详细]
  • 互联网世界 9 种基本的商业模式
    互联网世界9种基本的商业模式一个商业模式是运行一个公司的方法;通过该模式的运作,一个公司能维持自己的生存,就是说,能有收益。商业模式意味着一个公司是如何通过在价值链中定位自己,从而获 ... [详细]
  • i2c扩展32路gpio_【STM32Cube_13】使用硬件I2C读写EEPROM(AT24C02)
    寻求更好的阅读体验,请移步Mculover666的个人博客:【STM32Cube_13】使用硬件I2C读写EEPROM(AT24C02&# ... [详细]
  • 2022年Python面试题一.Python基础二.企业面试题结束语🥇🥇🥇✅作者简介:大家好我是编程IDὌ ... [详细]
  • 3寄存器操作实现ENC28j60的寄存器操作分为222部分,分别为写寄存器和读寄存器部分,读缓冲区和写缓冲区部分,写PHY寄存器和读PH ... [详细]
  • apk简单介绍APK的组成apk安装流程app的启动过程apk打包流程AIDLAIDL介绍为什么要设计这门语言它有哪些语法?默认支持的数据类型包括什么是apk打包流程 ... [详细]
  • c语言自定义BOOL函数C语言没有BOOL类型变量boolean类型是C++所独有的由于使用BOOL类型可以使代码更具有可读性,很多编程者都在C中自己定义了类似的应用,一般方法有两 ... [详细]
  • 一、域名解析记录说明记录类型A:用来指定域名的IPv4地址(如:8.8.8.8),如果需要将域名指向一个IP ... [详细]
  • Linux文件目录和权限
    Linux文件目录和权限前言:Linux一般将文件可存取的身份分为三个类别,分别是ownergroupothers,根据权限划分,每个目录都可以拥有相对身份的-rwx[可读可写可执 ... [详细]
  • 猪猪猫.CNWINXPSP2电脑城装机12DVD[豪华版]
    直接下载地址http:bt.jujumao.cn点击下载种子下载信息[点击浏览该文件:2007-12-19猪猪猫.cn-winxpsp2电脑城装机12豪华版.torrent]| ... [详细]
  • 【Modbus 】Modbus 协议
    Modbus协议简介Modbus协议是一项应用层报文传输协议,包括ASCII、RTU、TCP三种报文类型。标准的Modbus协议物理层接口有RS232、RS422 ... [详细]
  • hadoop完全分布式搭建
    原文链接:hadoop完全分布式搭建主机分配以及地址要求:角色主机名IP地址Namenodemaster192.168.222.201Datanodeslave ... [详细]
  • P1144 最短路计数· BFS/dijkstra
    题解其实题目很简单不写了,这里总结一下从这道题目里学到的知识:当最短路的边权都是1时,dijkstraspfa就是BFS如果使用优先队列,内部结构是pair时 ... [详细]
author-avatar
宝贝小妖精芳_555
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有