原文地址:http://shajunxing.tpddns.cn:8888/web/blog/2018-04-06-基于Linux内核的纯手工极简系统研究/index.html

问提由来

Linux操作系统虽然号称遵循着“KISS”原则,但是我感觉现在已经够复杂了,如果复杂是必需的还好说,关键很多都是没有必要的,所谓的“过度设计(Over Engineering, Over Design)”,比如重复造轮子,比如一件事情给你多种选择,比如各种文档只讲怎么做不讲为什么,让人看得云里雾里。

这么多纷乱的软件、配置,稍微哪里出错就可呢造成系统异常,当然这还算好。更严重的是如果被不怀好意的人做些手脚,系统虽然看起来很正常,然而你查都查不到。想查可以啊,先把那些浩如烟海的文档都精通再说,估计这辈子都看不完。

我一向的观点是,不论是易用性还是安全性,复杂向来都是头号的敌人,不要以为用什么SELinux之类的加固就能保证万无一失了,你加固得越多,系统越危险。为什么?道理很简单:这些所谓的加固软件的安全性谁来保证?

所以系统一定要尽可能地简单,简单不是指什么都没有,而是除了必须的功能外,其它通通删掉。

我的思路

作为一个从DOS走到今天的用户,我的想法是,Linux能否像DOS一样简单?

比如启动过程,从磁盘主引导记录加载GRUB,然后加载内核,最后启动一个Init程序完成网络等配置工作,就完成了。

Init及其之后的系统设置、后台服务、命令解释器等都可以用脚本语言完成,比如Python3就非常好。系统各种事件比如设备热插拔,直接用脚本监听并执行相应动作,不需要那么多二进制程序,能用脚本做的都用。

再然后,图形界面,Xorg之类的巨无霸通通干掉,直接基于FrameBuffer弄,现在FrameBuffer升级成DRM/KMS/GEM架构了,QT支持,那么用PyQT写就是了,Chromium Ozone也支持绕过Xorg之类的直接写硬件,那么搞个纯Web的GUI也不错的说。

另外,GLibC的rpath、ld缓存之类的也通通干掉,做一件事情不留多条路,环境变量这种通用的方式就够了。

用虚拟机做试验

试验环境显然不能用真机,所以新建一个VirtualBox虚拟机,桥接网络设置好,挂上空虚拟硬盘。

然后还需要一个带各种工具的,虚拟机能启动的系统。我想到了LiveCD,经过试验,发行版(比如Debian)的LiveCD带的工具很少,而http://www.system-rescue-cd.org/这个非常好用,该有的工具都有了。

启动后是这样的,配色显得很专业:

打开GParted分区工具,给那块空硬盘分两个区,一个Ext4,一个交换分区,然后保存。

然后挂载/dev/sda1。

mount /dev/sda1 /media

接下来使用grub-install命令把GRUB安装到那块硬盘上。GRUB的安装是分为两个步骤的,一是写硬盘的主引导记录,二是复制必要的文件。前者直接操作/dev/sda,而后者需要访问文件系统,这也是上面mount的原因。另外,grub-install默认是往/boot目录里写文件,而在LiveCD启动环境下显然/boot不是那块硬盘的目录,所以要用--boot-directory参数指定挂载后的目录,完整的命令是:

grub-install --boot-directory=/media/boot /dev/sda

注意要写到硬盘主引导记录而不是分区引导记录,也就是应该是/dev/sda而不是/dev/sda1。

命令执行成功后,打开文件管理器看看/media里面有些什么东西,发现多了个boot目录,里面又有一个grub目录,还有很多杂七杂八的文件,显然这些应该就是GRUB必需的了。

然后重新启动试试看吧,竟然能够启动,只不过GRUB没有配置文件,也没有Linux内核,所以就显示出交互界面了。

接下来弄配置文件和内核。我在网上下载了最新版的内核源代码,有一个特别牛逼的命令make allnoconfig,能把几乎所有的可选项全都去掉。执行后用make xconfig命令查看,果然勾勾都没了。之后的make简直飞快,几分钟就得到了一个几百K的bzImage。当然这个就是Linux内核啦,能不能用呢?拷到虚拟机里试试。

System Rescue CD启动后会自动DHCP联网,我用的是SFTP命令拷进去的,当然如果用其它办法也行。把这个bzImage放到那块装了GRUB的硬盘的某个地方,比如/boot目录里。然后新建GRUB配置文件/boot/grub/grub.cfg,加一个菜单项,启动这个bzImage内核。配置文件内容很简单:

menuentry 'test' {linux /boot/bzImage
}

重启,菜单果然出来了:

按下回车键,BOOM!

果然这个极简的内核是无法运行的,当然也有可能在运行,只是没有输出而已。

好吧,把真机里4MB的debian内核拷到虚拟机里再试试,修改grub.cfg然后重新启动,果然有输出了,至此一切正常。

内核配置还是有很多坑的,还需要继续熟悉,现阶段弄个完整环境的虚拟机然后make localyesconfig吧,然后make xconfig把ramdisk和module支持删掉,以后再说。虚拟机硬盘空间一定要大,因为编译会占用很多空间。

对于内核、grub配置之类的,http://www.jinbuguo.com/这个网站很好。

grub的一些注意事项:

一些配置里写着set root=(hd0,msdos1),这是一种快捷写法,一旦这样set之后,grub里的路径就可以省去这部分了,比如:

set root=(hd0,msdos1)
linux /boot/bzImage

相当于:

linux (hd0,msdos1)/boot/bzImage

hd0指的是第一块硬盘,从0开始计,msdos1指msdos格式的第一个分区,从1开始计,grub自带简单的文件系统识别功能,能够根据之后的路径加载文件。

如果没有配置文件,或者启动菜单界面按c,即进入grub命令行界面,写在配置文件里的命令都可以在命令行下面输入执行,比如可以执行以下命令启动Linux:

linux (hd0,msdos1)/boot/bzImage
boot

上面用make localyesconfig编译好内核后,就可以删掉initrd了,比如我虚拟机里这样配置:

menuentry 'test' {linux (hd1,msdos1)/boot/bzImage rootfstype=ext4 root=/dev/sdb1 init=/bin/bash
}

我加了另一块硬盘,所以是hd1

rootfstype、root、init是grub传递给内核的参数,因为现在不用initrd和模块加载了,所以应该用rootfstype告诉内核文件系统类型,root告诉内核应该以哪个硬盘分区作为根分区,注意这是内核辨认出来的而不是grub,init指明替换默认init程序的完整目录。

顺便说以下VFS Unable to mount root fs on unknown block错误。两个可能:第一是没有存储设备对应的驱动,第二是没有对应文件系统的支持。

下面是glibc和python的编译。

我的想法是在虚拟机现有的系统中编译,然后安装到第二块硬盘上,chroot之后测试。但是遇到了一些问题。

先记录几个命令:

  • 在某个目录的所有文件内容里面查找字符串:grep -rnw 目录 -e 字符串
  • 显示二进制文件里的所有字符串:strings 文件名
  • readelf查看elf格式可执行程序相关内容
  • patchelf修改相关内容

/lib/ldXXX.so是可以执行的,可以查看ld.so的manual了解详细用法。它是Linux可执行程序的动态加载器,elf文件头里有记录指明应该使用哪个加载器,可以用readelf -l 程序名查看。

顺便,readelf -d 程序名可以查看程序依赖的动态库。

ldd可以看到程序依赖的动态库的实际位置,但是一旦找不到出错,错误信息都是“not a dynamic executable”,非常云里雾里。查看ldd的源代码(ldd其实就是shell脚本)发现其实就是用的/lib/ldXXX.so的可以直接执行的特点,export LD_TRACE_LOADED_OBJECTS=1,然后/lib/ldXXX.so 程序名就可以看到动态链接库的加载情况,如果找不到就显示XXXX => not found

首先,我极度讨厌ld.so.cache这样一个特性,/lib/ldXXX.so有一个参数“--inhibit-cache”可以禁用cache,但是直接启动应用程序却无法使用这些参数,很遗憾。但是从这个参数入手,我查了ld的源代码,它包含在glibc里面,入口是elf/rtld.c,然后发现USE_LDCONFIG这个宏,在elf/dl-load.c中可以清楚地看到这个宏的功能是完全屏蔽cache。在config.h.in里也有,但是configure选项里却没有,只能在configure手动打开config.h,找到USE_LDCONFIG,修改为0。

然后是编译的路径问题,如果用--prefix指定第二块硬盘的目录,那么make install之后chroot测试,会死活找不到动态链接库。后来才发现,--prefix指定的目录会作为ld的默认寻找目录编译进ldXXX.so里面,可以用strings命令查看到。

解决办法是--prefix指定的必须是目标系统看到的位置,也就是chroot之后的位置,然后make install DESTDIR=指定安装的位置,遗憾的是不一定所有软件都有DESTDIR这个参数,以后碰到再说吧。

另外如果程序无法直接执行,提示"No such file or directory“,但是/lib/ldXXX.so 程序名却可以执行,那估计是elf文件头里记录的加载器位置错误了,得用patchelf改一下。

(待续)

基于Linux内核的纯手工极简系统研究相关推荐

  1. linux内核下网络驱动流程,基于Linux内核驱动的网络带宽测速方法与流程

    本发明涉及一种测速方法,尤其是一种网络带宽测速方法. 背景技术: :电信运营商为客户提供一定带宽的Internet接入:为了检验带宽是否达标,一般均由客户使用个人电脑在网页上直接测速.但是随着智能网关 ...

  2. 直播回顾:如何基于Linux内核构建起商用密码基础设施?| 龙蜥技术

    编者按:本文整理自龙蜥大讲堂技术解读,分享主题为<构建商用密码操作系统>,直播视频回放已上线至龙蜥社区官网(文末阅读原文直接跳转):首页-支持-视频,欢迎观看. 作者张天佳,来⾃阿⾥云操作 ...

  3. 纯文字极简风格平面海报,PSD分层模板!

    极简风海报一般画面会有大量的留白,无论是文案还是图案都是非常精简,给人一种自然又轻 松,大方又简约,这种风格让人赏心悦目,更让人流连忘返,简约并不代表简单,我们都知道 越简单的文案越难设计,所以想要根 ...

  4. YOCTO项目介绍:通过提供模版、工具和方法帮助开发者创建基于linux内核的定制系统

    目录 YOCTO项目介绍 配置内核 build配套 Yocto ,是一个开源社区.它通过提供模版.工具和方法帮助开发者创建基于linux内核的定制系统,支持ARM, PPC, MIPS, x86 (3 ...

  5. UCloud基于Linux内核新特性的下一代外网网关设计及相关开源工作

    2019独角兽企业重金招聘Python工程师标准>>> UCloud外网网关是为了承载外网IP.负载均衡等产品的外网出入向流量,当前基于Linux内核的OVS/GRE tunnel/ ...

  6. linux与windows内核哪个难学,国产操作系统为何都基于Linux内核?又和Windows像?

    [每日科技网] 近年来,国产操作系统不断更新迭代,优化完善,性能更加稳定,软硬件兼容性更强,也得到了越来越多用户的关注,常用软件越来越多. 中兴新支点操作系统 如中兴新支点操作系统是基于Linux内核 ...

  7. linux pppoe优化性能,基于Linux内核模式的PPPoE优化与实现.pdf

    基于Linux内核模式的PPPoE优化与实现.pdf 第18卷第7期 电子设计工程 2010年7月 V01.18 No.7 Electronic Jul.2010 DesignEngineering ...

  8. linux流量控制的基本原理,基于Linux内核的BT流量控制的原理与实现.pdf

    基于Linux内核的BT流量控制的原理与实现 黄山学院学报 2010 年 第 卷第 期 黄山学院学报 Vo1.12,NO.3 12 3 年 月 Journal of Huangshan Univers ...

  9. Mac强大Git客户端Tower 基于Linux 内核开发的Git客户端

    你是否需要一款简单易用的Git客户端呢?快来试试Tower for Mac吧!Tower mac版是运行在mac os系统上的基于Linux 内核开发的Git客户端.Tower可以让Git更简单高效地 ...

最新文章

  1. 以云原生的名义,举办一次技术聚会
  2. Nginx配置实例-反向代理实现浏览器请求Nginx跳转到服务器某页面
  3. clion phpstorm 等jetbrains编辑器激活教程
  4. PL/SQL - 03
  5. 不同路径 IIPython解法
  6. RAID技术超详细讲解
  7. [POJ 1330] Nearest Common Ancestors (倍增法)
  8. Apache Spark 2.2.0 中文文档 - 概述 | ApacheCN
  9. org.apache.axis.ConfigurationException: No service named ldapOperate is available解决方法
  10. Ubuntu中需要安装的
  11. c#+arcAE对图层进行各种渲染操作
  12. 国人魔改后的中文优化版资源管理器,终于解决我多年的难题
  13. 计算机网络与通信技术教案,计算机网络技术教案
  14. CVonline: Image Databases
  15. Arcgis应用(十二)栅格数据翻转(Flip)、镜像(Mirror)、重缩放(Rescale)、旋转(Rotate)、移位(Shift)、弯曲(Warp)
  16. 生产计划排产软件能为企业生产管理提供哪些帮助?
  17. 首批!智领云CTO宋文欣入选“开源GitOps产业联盟技术委员会”成员名单
  18. The e200z4 MMU 学习笔记
  19. 从零开始,带你掌握空状态设计的正确方法
  20. Kooboo CMS - 之后台注册用户流程方法。

热门文章

  1. 采购订单和 采购申请 的表
  2. Enterprise Architect入门:如何利用BABOK指南进行建模
  3. 【第七章】 C语言之牛客网力扣刷题笔记 【点进来保证让知识充实你一整天】
  4. stm32f407zgt6的2.2LCD实例1.2:LCD屏幕程序讲解之LCD驱动底层代码
  5. scons 手册_SCons用户手册 | 学步园
  6. 如何输入“·”间隔号
  7. Python——连接数据库操作
  8. 谷歌使用人工智能来预测航班延误
  9. 微信铃声设置教程,怎么设置微信铃声?
  10. ASCII、Unicode、UTF-8