逆天的 GRUB
参考资料
GRUB 的文档在这里:https://www.gnu.org/software/grub/manual/grub/
Linux 的启动过程和 GRUB 的地位
Linux 系统启动的过程是这样的:先由 BIOS 启动一个系统引导程序;然后系统引导程序负责把 Linux 的内核加载到内存,同时把 initrd 加载到内存,然后把控制权交给 Linux 的内核;Linux 的内核初始化完成后,将控制权交给 init 程序;init 程序负责启动各种服务。如果要启动图形桌面系统,则 init 先启动一个窗口管理器,由窗口管理器负责用户的登录和验证;用户登录和验证成功后,窗口管理器负责启动 X 服务器和客户端,进入桌面系统。如果是不需要图形桌面系统的 Linux,则 init 启动 login 程序,login 程序负责用户的登录和验证,验证成功后,启动一个 shell。
GRUB 就是目前 Linux 系统使用的系统引导程序,是计算机启动后运行的第一个程序(当然,BIOS除外)。它在将 Linux 内核加载到内存的时候,还可以向内核传递各种参数。目前的 Linux 发行版使用的 GRUB 都已经是第 2 版了,它的功能和配置都和以前的版本不一样。网上很多文章都是基于以前的 GRUB Legacy 版本进行的讲解,已经不能适应现在新的形势了,所以才有了我的这篇文章。
从上面的介绍可以看出,GRUB 是计算机启动后运行的第一个程序,这个时候 Linux 的内核还没有加载,其它的程序也都不可能运行。这时有人就会想了,这个 GRUB 的功能应该相当有限吧。我刚开始也是这么想的。但是当我读完上面参考资料中给出的 GRUB 文档后,我的思想被彻底颠覆了。GRUB 的功能太 TM 强了,所以我才把这篇文章取名“逆天的 GRUB”。
GRUB 功能概览
那么这个一开机就启动的简单程序究竟具有哪些让人意想不到的功能呢?请看我列举几条:
- 能够访问任何设备上的数据,不管你是硬盘、软盘还是光盘;
- 能够探测到所有的内存;
- 能够识别大部分的文件系统,不管你是 FAT32、NTFS 还是 ext2/ext3/ext4;
- 能够识别文件系统中的文件,文档中说它可识别大部分可执行文件格式,ELF什么的根本不在话下;
- 能够使用 .png、.jpg 格式的图片作为背景,说明它能够识别一些图片格式;
- 对字体的支持稍微差一点,好像只能使用 PFF2 格式的字体;
- 当然可以读取和输出硬盘上的文本文件;
- 据说还能播放乐曲;
- 支持联网,可以从网络上启动操作系统;
- 可以支持串口输入输出。
这些功能真的是已经超强了,就快赶上一个操作系统了。重要的是,它还提供了一个非常好用的命令行界面,该命令行界面的使用方法和 Linux 系统中的 Shell 及其接近,也支持编程、支持环境变量,其编程的语法也和 Bash 差不多。再加上 GRUB 提供的丰富的命令,该界面使用起来爽得不要不要的。
GRUB实战
实践出真知,下面以 Ubuntu 为例开始实战。
GRUB的界面
刚安装好的 Ubuntu 启动时不显示 GRUB 界面,因为它在设置中把它隐藏了。它的启动画面是这样的:
必须按一下 ESC 键,我们才能够看到 GRUB 的菜单,它是这样的:
上面这个界面想必大家已经很熟悉了。在这个界面中,如果按下 c 键,就会切换到 GRUB 的命令行界面,如下:
还有一种情况就是,如果大家在使用 Linux 过程中不小心删除了 /boot/grub/grub.cfg,或者配置错误,或者删除了 Linux 系统所在的硬盘分区的数据,使得 GRUB 无法正确加载 Linux 系统,也会自动进入到这个命令行界面。
GRUB 支持的命令
GRUB 的命令补全功能非常方便,只要按一下 TAB 键,就可以显示它支持的所有命令。命令之后按 TAB 键,可以自动补全文件名。下面是 GRUB 支持的命令,我按 TAB 键调出来的:
使用 ls
命令可以列出目录和文件,使用cat
命令可以输出文本文件的内容。在 GRUB 中,使用 (hd0, msdos1)
或者 (hd0, gpt1)
识别硬盘分区,使用 (hd0, gptN)/boot/grub/grub.cfg
这样的形式识别文件。由于 GRUB 能自动识别根分区,所以我下面的命令中省略掉了指定硬盘分区的部分。如下图:
在上图中,我使用 cat /etc/fstab
命令显示了我系统中硬盘分区的情况。可以看到,我使用的是 GPT 分区格式和 EFI 固件,硬盘分了三个去,第一个分区的挂载点是 /boot/efi
,并且是 vfat 格式的文件系统,第二个分区的挂载点是根目录 /
,第三个分区是 swap 空间。按照 GRUB 的术语,则分区(hd0, gpt1)
是挂载的/boot/efi
,分区(hd0, gpt2)
是根目录,分区(hd0, gpt3)
是交换分区。可以看到,GRUB 中硬盘是从 0 开始计数的,而分区是从 1 开始计数的。
GRUB 的环境变量
我在之前的某一篇随笔中讲过,命令行参数、环境变量、配置文件是对软件进行配置的三驾马车,GRUB 也不例外,它的很多行为也受环境变量控制。下面看一个例子,当我想查看 GRUB 的启动配置文件/boot/grub/grub.cfg
时,使用cat
命令查看该文件的内容,但是由于该文件太长,一个屏幕显示不完,所以只能看到最后几行,如下两图:
这是非常蛋疼的,但还不是最郁闷的,毕竟/boot/grub/grub.cfg
是系统中的一个文件,大不了我进 Linux 后用 vim 看。最蛋疼的是某些命令的输出,只能看到最后几行,又不能保存下来,真的让人捉急。就像下面这个例子,我使用 videoinfo
命令查看我的 GRUB 支持哪些图形分辨率:
这个时候,就只能通过设置环境变量的方法来解决问题了。使用set pager=1
命令设置环境变量pager
,让 GRUB 的输出启用分页,如下图:
我们还可以通过不带参数的set
命令显示所有可用的环境变量,如下图:
也可以使用echo
命令输入某一个环境变量,如下图:
更改分辨率
我们可以控制 GRUB 显示界面的分辨率,还可以通过 GRUB 控制 Linux 启动进入字符模式后的分辨率。前提条件是要看我们的 BIOS 和显卡支持哪些模式。可以通过 videoinfo
命令查看,如下图:
我使用的是虚拟机,因为玩 GRUB 不使用虚拟机无法截图啊。如果采取的是 EFI 固件,则其输出如下:
如果采取的是 Legacy BIOS,则其输出如下:
可以看到,如果使用的是 Legacy BIOS,它的显示模式是由 ' VESA BIOS Extension Video Driver ' 提供支持的。如果使用的是 EFI,则其显示模式是由 ' EFI GOP driver ' 提供支持的。在我的虚拟机中,它们能提供的最高分辨率也只有 1152 x 864,远远达不到 1920 x 1080。但是在我的物理机中,都是可以达到 1920 x 1080。而且貌似只能进入 1920 x 1080,想改小还改不了。在物理机上,想通过改小分辨率,然后利用显示器的放大功能来放大字体的梦想是破灭了的。
在虚拟机中,我要做的是把分辨率改大,至少让我完全进入 Linux 字符界面的时候有个 1024 x 768 的分辨率吧,不然字符界面用起来岂不是太憋屈。可以通过修改 /etc/default/grub
文件,然后调用sudo update-grub
命令更新 GRUB。如下图,使用sudo vim /etc/default/grub
修改配置文件:
在上面的这个文件中的注释里,也写得很明白了,要修改 GRUB 和 Linux 字符界面的分辨率,可以通过修改 GRUB_GFXMODE
和 GRUB_GFXPAYLOAD_LINUX
参数来设置,而且千万不要设置GRUB_TERMINAL=console
,不然就真的进入只有文字的文字模式了,没有 Graphic 的支持,还谈啥分辨率呢。
然后重启系统,可以看到我们的 GRUB 界面变大了一圈,如下两图:
下面进入 Linux 的字符界面,进入 Linux 字符界面的方式是启动进入 Linux 后,使用 sudo systemctl set-default multi-user.target
,然后重启,在 1024 x 768 的分辨率下开一个 vim 看看,如下图:
又找到了怀旧的感觉,不是吗?唯一的缺憾是字太小。如果是在我的物理机上,15.6寸 1920 x 1080 的屏幕,字会小得根本无法看。下一篇,我们再来探讨 Framebuffer 的正确打开姿势。
逆天的 GRUB的更多相关文章
- Linux 桌面玩家指南:10. 没有 GUI 的时候应该怎么玩
特别说明:要在我的随笔后写评论的小伙伴们请注意了,我的博客开启了 MathJax 数学公式支持,MathJax 使用$标记数学公式的开始和结束.如果某条评论中出现了两个$,MathJax 会将两个$之 ...
- 【资源】.Net 入门@提高 - 逆天的高薪之路!
入门看视频,提高看书籍,飘升做项目.老练研开源,高手读外文,大牛讲低调~ 官方学习计划 http://www.cnblogs.com/dunitian/p/5667901.html ----- ...
- 移动硬盘不能识别的常见7种解决方案 ~ By 逆天经验
服务器汇总:http://www.cnblogs.com/dunitian/p/4822808.html#iis 服务器异常: http://www.cnblogs.com/dunitian/p/45 ...
- 逆天通用水印支持Winform,WPF,Web,WP,Win10。支持位置选择(9个位置 ==》[X])
常用技能:http://www.cnblogs.com/dunitian/p/4822808.html#skill 逆天博客:http://dnt.dkil.net 逆天通用水印扩展篇~新增剪贴板系列 ...
- Dapper逆天入门~强类型,动态类型,多映射,多返回值,增删改查+存储过程+事物案例演示
Dapper的牛逼就不扯蛋了,答应群友做个入门Demo的,现有园友需要,那么公开分享一下: 完整Demo:http://pan.baidu.com/s/1i3TcEzj 注 意 事 项:http:// ...
- 第14章 Linux启动管理(2)_启动引导程序grub
2. 启动引导程序grub 2.1 Grub配置文件 (1)grub中分区的表示 硬盘 分区 Linux设备文件名 Grub中设备文件名 第1块SCSI硬盘 第1个主分区 /dev/sda1 hd(0 ...
- 我为NET狂~群福利:逆天书库
我为NET狂-官方群① 238575862 爱学习,爱研究,福利不断,技能直彪~~ 最近更新:2016-08-30,欢迎补充 暂缺PDF: │ SQL Server 2012 Analysis Ser ...
- 我为NET狂群福利:逆天常用的一些谷歌浏览器插件
逆天书库:http://www.cnblogs.com/dunitian/p/5734677.html 常用工具:http://www.cnblogs.com/dunitian/p/5640147.h ...
- ubuntu关于引导修复[grub命令行][live linux]
第一种:grub命令行: ls 列出所有分区 ls /grub ls /grub 检查确认linux引导分区,如果linux单独/boot分区,就要采用如下命令进行检查: ls /boot/grub ...
随机推荐
- 初学python之路-day09
今天的主要内容为内存管理. 1.引用计数:垃圾回收机制的依据 # 1.变量的值被引用,该值的引用计数 +1 # 2.变量的值被解绑,该值的引用计数 -1 # 3.引用计数为0时就会被垃圾回收机制回收 ...
- MySQL ERROR 1820 (HY000)
You must reset your password using ALTER USER statement before executing this statement报错处理 解决方式如下: ...
- Typescript---03 类、接口、枚举
传统的javascript程序使用函数和基于原型的继承来创建可重用的组件,从ECMAScript2015(ECMAScript 6)开始,可以使用基于类的面向对象方式. 一.类: 定义类(class) ...
- 使用Django的时候,页面请求正常,也没有报任何错误,甚至连警告都没有的情况下,页面却还是原地不动或者闪一下或者无限显示加载动画的情况下的解决办法
这个问题描述比较笼统,但根据我目前遇到过两种情况来看,似乎都比较重要而且实用,所以打算分别讲述一下. 说明:Django的版本是Django2.0 第一种:URL配置错误 页面闪一下,却原地不动,可能 ...
- 编辑请求内容 Charles
1 选中request, 右键选择 Breakpoints 2 再次运行edit request, excute, edit response. excute
- 今天分享三种方法实现Linux系统调用,感兴趣的朋友可以参考一下
系统调用(System Call)是操作系统为在用户态运行的进程与硬件设备(如CPU.磁盘.打印机等)进行交互提供的一组接口.当用户进程需要发生系统调用时,CPU 通过软中断切换到内核态开始执行内核系 ...
- 打包ideaUI本地项目,以供本地使用
#首先我们要在本机进行一些配置 在本机配置环境变量(控制面板->高级系统设置->环境变量->) #用cmd检测是否配置成功 如果你在ideaUI里,配置好了之后.我们现在来打架包 # ...
- 使用Tornado异步接入第三方(支付宝)支付
目前国内比较流行的第三方支付主要有支付宝和微信支付,博主最近研究了下如何用Python接入支付宝支付,这里我以Tornado作为web框架,接入支付宝构造支付接口. 使用Tornado异步接入支付宝支 ...
- ElasticSearch本人启动报错总结
1.报错关键代码如下: Exception in thread "main" 2019-04-28 03:53:04,339 main ERROR No log4j2 config ...
- iOS 轻击、触摸和手势的检测
一.检测捏合手势( UIPinchGestureRecognizer): //设定一个实例变量存储手指之间的其起始距离 @property (assign, nonatomic) CGFloat i ...