注:关于我电脑遇到的问题,不是一两句话能够说清楚的。为了能够比较完整的呈现问题的某些细节,在这篇博客中我会添加许多问题发生的背景,如果当中有观点与您的三观不合,请立即停止阅读,及时止损。
注:此篇文章可能出现错误或者不严谨的知识,比如系统引导那一部分是个人回忆+理解写出来的,只供参考。希望看出有问题的同学不吝赐教,谢谢!


第一次进入计算机专业

大学选的是计算机专业,但与这个专业的真正接触,却是在一次重装系统当中。(个人觉得)和身边大多数同学一样,在学习学校开设的计算机课程中,我也没有爱上“计算机”。而那时候,正是Windows 10的推广时期。当时我们那一批人买的电脑估计都是Windows 7/8,而我的电脑,正是windows 8。当时Windows 10的推广软文和windows 8的“黑帖子”使得我没怎么思考便懵懵懂懂地加入了“升级Windows 10大军”中去了。

虽然已经学了一点C语言和数据结构,但是对于计算机的使用来讲,我几乎停留在“聊QQ看视频听音乐”(那时不玩游戏)的层次上,十足十一个“没见过世面的小白”。
此前我从来没有装过系统。所以关于怎么装系统,我问了百度(很久之后才知道可以在Windows设置里直接升级)。

阴差阳错,我误装了了另外一个系统--Ubuntu。莫名其妙之下,看了几篇文章,才知道这个世界原来不只是有Windows系统,还有(类)Unix系统等等......。这些文章一下子让我迷上了Linux系统,很快地我便买了一本多人推荐的书:《鸟哥的私房菜--基础版》。那时候呀,就像一个情窦初开的少年,一下子找到了心爱的姑娘,我怀着无比激动的心情,花了一周多把这本书看完了,也照着里面的代码敲了一遍。从此,我才算真正的进入了计算机专业,成为了无数求学学子中普通的一员。

说了这么久,这里我要交代一下我脑的配置了,以为往后的故事,都与之有关。
我电脑配置是这样:联想拯救者14-ISK(i7经典版)
BIOS版本是这样:


开始进入装双系统的“坑”

装双系统向来比较流行,大概20天后我便来了装双系统的兴趣。因为几乎什么都不懂,所以只能跟着一些博客文章一步步做,愣着不懂mbr分区和GPT分区的异同,搞了很久也没有搞定。很多次都是装好了linux系统,但启动的时候只能进入Windows 系统。后来不知道是哪儿看的重刷BIOS能解决问题,所谓初生牛犊不怕虎,我便不假思索便刷了BIOS。刷完BIOS就,把固态格式化,将分区换成了MBR,也在BIOS做了相应设置,最后终于成功地搞定了双系统启动。强烈的满足感让我很长一段时间都很激动。
之后我便几乎都在linux下用vim来敲C语言。


三系统!

大概花了半年时间,我学习了C语言和一部分shell命令,同时也对linux的使用熟悉了很多。后来网上冲浪时,我发现原来可以在普通的笔记本上装上苹果系统mac OS,也就是俗称的黑苹果。毫无悬念,我被这个“旁门左道”(我叔叔这么说的)牢牢地套住了,接下来的几乎一个月,我几乎每天六点起床,装了一百多次系统。看了许多篇文章,每次失败,都得按(先装Windows,再装ubuntu,再装黑苹果)这个顺序重来一遍。直到我发现了这个网站tonymacx86,很吃力地看了里面许多教程,多次利用easyuefi,才成功地装好了三系统。由于电脑固态只有可怜的128G,我经过多次思考,终于想到了一个办法,就是把Clover 引导程序装在u盘efi分区里(装黑苹果需要在U盘划分EFI分区),Windows10和ubuntu装在固态里,Mac OS装在机械硬盘里。
大概是这样:

  • Windows 10 大概80G(固态里)(EFI分区和MSR分区也在这里,但下图中MSR分区没显示出来);
  • ubuntu: 大概39G(固态里);

  • Mac OS: 100G(机械硬盘里);

然后按下面步骤干活:

  1. 用U盘EFI里的引导程序进入硬盘上的MAC OS系统;
  2. 在MAC OS里,先把固态下EFI里的Windows引导程序和ubuntu引导程序备份好;
  3. 再把U盘上EFI分区的EFI文件复制到电脑上的EFI分区里,最后再把开始你备份的固态下EFI里的Windows引导程序和ubuntu引导程序复制进clover文件夹里。

理论上你进入其他系统也能将U盘EFI分区里的文件复制到固态里的EFI分区里,但由于mac os下挂在efi分区比较方便,我一直是在mac os里对efi进行复制移动文件操作

做到这里,如果你没有U盘,你是进不去电脑上的系统,你得再借助U盘进入Windows系统,然后借助easyuefi把clover引导条目添加到BIOS启动项目里,这时候,不需要U盘,你也能进入电脑中任何一个系统了。
启动界面大概这样:

然而成功点亮系统只是第一步,黑苹果里面的很多驱动,得自己修改源码(当然有教程),才能继而点亮驱动。所以,之后的几乎一年里,我基本上都在搞三系统。也就是在这段时间里:

  1. 我意识到英语十分重要,花了很大功夫在学习英语里;
  2. 解决事情之前,你需要良好的知识背景才能让你想出清晰正确的思路;

开始遇到问题!

同时也是装三系统那段时间里,我的电脑固态坏了,联想售后给我免费换了一条。也就是这个时候,我的电脑无法再次写入新条目(也就是BIOS里无法添加新的Boot引导)。我到现在都无法判断,为什么无论我重装了多少次电脑,还是不能在BIOS里写入新的条目,哪怕我只装Windows系统,也不行。

为了测试,我把电脑机械硬盘拆下来,把固态硬盘重新格式化,重新分区,然后再重装Windows 10系统,还是不行,无法在BIOS启动项里添加新条目,大概就是下面这样:

但如上图所示,虽然说不能在BIOS的Boot Priority Order里添加新引导项,但还是能够进入系统的,但启动速度肯定会有影响,而且BIOS系统在硬盘寻找EFI分区中的启动项是可能会出错,导致无法启动,这时候你可以尝试重复按F8,F8代表以上次正确的环境进入系统,很多时候你无法进入系统就是因为某些特殊的硬件环境发生了改变。所以过去的一年里,我一直使用Windows,偶尔需要linux环境通过虚拟机\云主机\git软件解决(git bash挺好的),而我的时间更多是花在编程上了。但问题还是一直没有被解决:无法往BIOS添加新条目,也就是无法添加开机引导!!!


亟需解决问题

由于跟了导师做项目,需要真正的linux环境,所以维持一年左右的纯Windows环境被打破了。这一次也经历了十几次重装系统,每次都遇到ubuntu下“无法将grub-efi-amd64-signed软件包安装到/target”问题,虽然应用某些技巧可以正常双启动,但在使用ubuntu时时不时会遇到和“grub-efi-amd64-signed”相关的错误或者直接死机了。这使得我十分苦恼。

之后凭借经验和阅读相关文章,我知道是采取GPT分区格式时,需要设置一些参数,才能装好系统。但我不想再装ubuntu了。换了manjaro,一次点亮,成功双启动!除了无法往BIOS添加新条目,其他一切都好了。

但这一切美好,在今天下午又被打破了,我升级了Windows 10系统,估计是个大升级,Windows 10系统自己又多分了一个恢复分区,而EFI里的东西也被更新了,所以我现在只能这样启动系统:

按照正常来说,进入manjaro后,更新grub就可以了,但是“无法往BIOS添加新条目”问题让我无法更新grub!如下:

我尝试把grub装在EFI分区/dev/sdb1和整个硬盘开头位置/dev/sdb都不成功。后来我想到了还没挂载,于是我就先挂载,再装grub,但还是失败,原因还是没空间,如下:

猜想问题根源

根据电脑本身一直存在的问题无法往BIOS添加新条目和linux下的报错信息,还有阅读了一些文章帖子帖子1帖子2,我终于把我电脑的问题根源和NVROM联想到一起。只是我无法确定:

  1. 是因为我使用easyuefi对boot引导操作不当/太频繁;
  2. 还是我重刷了BIOS版本留下了暗病;
  3. 还是我装太多次电脑对主板NVROM造成了损害;

才最后造成我的NVRAM没有空间写入新条目呢?


怎么解决?

我联系了联想的工程师,把我的情况和linux下的输出信息发送给他们看,得到下面回复(注:本人对联想工程师态度中立,并无黑他们之意,计算机知识很多,不可能都懂,他们没遇到过我的问题是正常的):

还是没解决问题。打算明天去联想售后看一下。

(⊙o⊙)…

今天去了联想3C服务站点,可能是我描述得不清楚,又或者是我遇到的这个问题太过冷门,最后还是没能把我的问题解决。在回来的时候我心绪万千,想着回到宿舍一定要认认真真去学一下UEFI。回到宿舍之后,我内心是有点疲惫的,我想在学习UEFI之前好好google一把,看能不能把我的问题给解决了。果然,望天不负有心人,我找到了Grub installation failed,里面说到了释放NVROM空间的办法!!!由于别人答案已经很好,没必要为了加东西而加东西,我就拿来主义,直接翻译过来给需要的同学看看:

  1. 为了修补efibootmgr 错误,我们首先挂载Boot variables:
    # mount -t efivarfs efivarfs /sys/firmware/efi/efivars
  2. 然后efibootmgr返回空间不足的信息:
    Could not prepare Boot variable: No space left on device
  3. 删除dump文件(也就是清除NVROM中的无效/垃圾项):
    # rm /sys/firmware/efi/efivars/dump-*
  4. 然后在root模式下(或者普通用户用sudo来更新grub):
    update-grub
    grub-install -v --target=x86_64-efi --recheck /dev/sda

至此,大功告成!!进入BIOS可以看到相应的启动项了:


一些说明

本文章说的是解决我个人电脑问题的一个大概过程,只供参考,并不一定适用于所有电脑,请理性参考。造成一切后果本人概不负责。

记一次关于NVROM中遇到的“Could not prepare Boot variable:No space left on device”问题的解决历程的更多相关文章

  1. Nancy总结(二)记一次Nancy 框架中遇到的坑

    记一次Nancy 框架中遇到的坑 前几天,公司一个项目运行很久的Nancy框架的网站,遇到了一个很诡异的问题.Session 对象跳转到另外一个页面的时候,session对象被清空了,导致用户登录不上 ...

  2. 记一次SpringBoot 开发中所遇到的坑和解决方法

    记一次SpringBoot 开发中所遇到的坑和解决方法 mybatis返回Integer为0,自动转型出现空指针异常 当我们使用Integer去接受数据库中表的数据,如果返回的数据中为0,那么Inte ...

  3. eclipse中tomcat无法加载spring boot

    转自: http://blog.csdn.net/u010797575/article/details/50517777 最近搭建一套spring boot框架,作为 application 启动项目 ...

  4. XP系统中IIS访问无法显示网页,目前访问网站的用户过多。终极解决办法

    无法显示网页 目前访问网站的用户过多. -------------------------------------------------------------------------------- ...

  5. Perl Tk在IC设计中的应用、Windows、Linux平台下的安装-各种错误的摸索解决

    本文转自:自己的微信公众号<集成电路设计及EDA教程> <Perl Tk在IC设计中的应用.Windows.Linux平台下的安装-各种错误的摸索解决> Perl在IC设计中有 ...

  6. node 在centos 6.5 上 安装过程中出现/usr/lib64/libstdc++.so.6: version 'GLIBCXX_3.4.19' not found问题的解决

    node  在centos 6.5 上 安装过程中出现/usr/lib64/libstdc++.so.6: version 'GLIBCXX_3.4.19' not found问题的解决 在linux ...

  7. 记一次WinForm程序中主进程打开子进程并传递参数的操作过程(进程间传递参数)

    目标:想在WinForm程序之间传递参数.以便子进程作出相应的处理. 一种错误的方法 父进程的主程序: ProcessStartInfo psi = new ProcessStartInfo(); p ...

  8. 记一次在java中的日期parse错误

    String dateString = "2014101517"; new SimpleDateFormat("yyyyMMddHH").parse(dateS ...

  9. 记OC迁移至swift中笔记20tips

    写久了OC后来写swift,总感觉写着是swift的皮毛,但是实际上是OC的核心,这里整理了OC迁移至swift中的一些小细节. 1 在当前类中,实例方法调用属性以及方法都可以将self省略掉,而且是 ...

随机推荐

  1. Tarjan's algorithm

    Tarjan算法可以用来求有向图的强连通分量个数,之前十分粗略的写了Kosaraju算法,这里打算比较认真的分析一下Tarjan算法,然后给出算法实现代码. Tarjan算法的主要算法部分也是dfs( ...

  2. 正确的上网姿势:ubuntu18.04使用clash

    本文为本人将CFW(Clash For Windows)上的配置文件应用到ubuntu上面的操作备忘,仅供个人使用 首先下载已经打包的clash压缩包:https://github.com/Dream ...

  3. python两个_多个字典合并相加

    这只是符合比较正常的需求和场景. #一.适用合并两个字典(key不能相同否则会被覆盖),简单,好用. A = {'a': 11, 'b': 22} B = {'c': 48, 'd': 13} #up ...

  4. Java后台技术(线程安全)

    前端时间一个同事因为后台线程安全问题出了一次生产事故,今天我就对线程安全问题进行一次总结. 首先,我们来大致看以下我同事写的代码,代码我进行了精简,大致如下: for (final String re ...

  5. Hibernate学习(七)

    Hibernate缓存 1.一级缓存:Session 级别的缓存 2.二级缓存: SessionFactory 级别的缓存 3.查询缓存:需二级缓存的支持,查询缓存依赖二级缓存 一级缓存 1.依赖于 ...

  6. 配置SVTI

    路由器SVTI站点到站点VPN         在IOS 12.4之前建立安全的站点间隧道只能采用GRE over IPSec,从IOS 12.4之后设计了一种全新的隧道技术,即VIT(Virtual ...

  7. Nexus-vPC基础实验

    一.实验拓扑: 由于条件有限,使用两个N5K做基本的vPC实验,Peer Keepalive Link使用的是两个Nexus 5K的Mgm0接口. 二.配置步骤:1.先构建vPC domain,并在d ...

  8. 文件的读取与保存(try-with-resource优雅关闭)

    借鉴:https://www.cnblogs.com/itZhy/p/7636615.html 一.背景 在Java编程过程中,如果打开了外部资源(文件.数据库连接.网络连接等),我们必须在这些外部资 ...

  9. tf.app.run()的作用

    tf.app.run() 如果你的代码中的入口函数不叫main(),而是一个其他名字的函数,如test(),则你应该这样写入口tf.app.run(test) 如果你的代码中的入口函数叫main(), ...

  10. mybatis源码探索笔记-3(使用代理mapper执行方法)

    前言 前面两章我们构建了SqlSessionFactory,并通过SqlSessionFactory创建了我们需要的SqlSession,并通过这个SqlSession获取了我们需要的代理mapper ...