00_build_env.sh | ||
01_build_src.sh | ||
02_build_img.sh | ||
03_run_qemu.sh | ||
04_run_docker.sh | ||
cat_img.sh | ||
env.sh | ||
make_sdb.sh | ||
mk_drv.sh | ||
mk_sdb.sh | ||
mk_strip.sh | ||
README.md |
smart-os 一个小巧的 linux 系统
本项目给大家演示了怎么样快速制作一个小巧的 linux 操作系统
功能与特点
- 支持挂载多块硬盘
- 支持网络功能
- 支持 DNS 域名解析
- 支持 GCC 编译器
- 支持 smart_rtmpd 运行
- 支持 qemu 启动
- 支持 docker 启动
- 最精简模式 64 M
- 支持驱动相关演示
用途与场景
- 操作系统原理教学
- IoT场景操作系统定制
- 流媒体服务器定制
- 云主机系统
说明
由于初版比较着急,脚本及代码还有说明做的都比较粗糙,后续会慢慢完善!
环境说明
本脚本 Ubuntu 18.04 上做的,别的系统应该改动不大,有需要的朋友可以自行修改。
-
准备系统环境
由于内核需要编译,需要安装内核编译所需要的环境 由于 busybox 需要编译,根据需要自行安装所需环境
./00_build_env.sh -
编译源码 ( kernel, glibc, busyboxy, gcc, binutils)
./01_build_src.sh -
制作系统盘 ( 重要,此步骤把系统安装到一个系统文件内 )
./02_build_img.sh -
运行 smart-os 系统
./03_run_qemu.sh 或 ./04_run_docker.sh
是不是制作一个操作系统很简单! 磁盘空间可以任意扩展,可以上网,可以根据需要扩展自己想要的组件,我已经试验成功,在 smart-os 内运行流媒体服务器 smart_rtmpd 了
TODO 列表
- 增加 arm 版本
- 增加图形界面演示
- 支持 ISO 制作
- 账号和密码
- 防火墙
拓展知识
ramfs : ramfs是一种非常简单的文件系统,它直接利用linux内核已有的高速缓存机制(所以其实现代码很小, 也由于这个原因, ramfs特性不能通过内核配置参数屏蔽, 它是内核的天然属性), 使用系统的物理内存,做成一个大小可以动态变化的的基于内存的文件系统, 系统不会回收, 只有 root 用户使用它
tmpfs : tmpfs是ramfs的衍生物,在ramfs的基础上增加了容量大小的限制和允许向交换空间(swap) 写入数据。由于增加了这两个特性,所以普通用户也可以使用tmpfs。 tmpfs 占用的是虚拟内存,不全是 RAM ,性能可能没 ramfs 高
ramdisk : ramdisk是一种将内存中的的一块区域作为物理磁盘来使用的一种技术,也可以说,ramdisk是在一块内存区 域中创建的块设备,用于存放文件系统。对于用 户来说,可以把ramdisk与通常的硬盘分区同等对待来使用。系统读写它还会在内存中存储一份对应的缓存,污染 CPU 缓存,性能也差,需要对应驱动支持
rootfs : rootfs是一个特定的ramfs(或tmpfs,如果tmpfs被启用)的实例,它始终存在于linux2.6的系统中。rootfs不能被卸载(与其添加特殊代码用来维护空的链表, 不如把rootfs节点始终加入,因此便于kernel维护。rootfs是ramfs的一个空实例,占用空间极小)。大部分其他的文件系统安装于rootfs之上,然后忽略它。 它是内核启动初始化根文件系统。
rootfs又分为虚拟rootfs和真实rootfs。 虚拟rootfs由内核自己创建和加载,仅仅存在于内存之中(后续的InitRamfs也是在这种基础上实现),其文件系统是tmpfs类型或者ramfs类型。 真实rootfs则是指根文件系统存在于存储设备上,内核在启动过程中会在虚拟rootfs上挂载这个存储设备,然后将/目录节点切换到这个存储设备上,这样存储 设备上的文件系统就会被作为根文件系统使用(后续InitRamdisk是在这种基础上实现),其文件系统类型更加丰富,可以是ext2、yaffs、yaffs2等等类型, 由具体的存储设备的类型决定。
我们的启动文件系统其实就是为 rootfs 准备文件,让内核按照我们的意愿执行 在早期的linux系统中,一般只有硬盘或者软盘被用来作为linux根文件系统的存储设备,因此也就很容易把这些设备的驱动程序集成到内核中。但是现在的嵌入式 系统中可能将根文件系统保存到各种存储设备上,包括scsi、sata,u-disk等等。因此把这些设备的驱动代码全部编译到内核中显然就不是很方便。 在内核模块自动加载机制udev中,我们看到利用udevd可以实现内核模块的自动加载,因此我们希望如果存储根文件系统的存储设备的驱动程序也能够实现自动加载, 那就好了。但是这里有一个矛盾,udevd是一个可执行文件,在根文件系统被挂载前,是不可能执行udevd的,但是如果udevd没有启动,那就无法自动加载存储根文件 系统设备的驱动程序,同时也无法在/dev目录下建立相应的设备节点。 为了解决这一矛盾,于是出现了基于ramdisk的initrd( bootloader initialized RAM disk )。Initrd是一个被压缩过的小型根目录,这个目录中包含了启动阶段中 必须的驱动模块,可执行文件和启动脚本,也包括上面提到的udevd(实现udev机制的demon)。当系统启动的时候,bootloader会把initrd文件读到内存中,然后把 initrd文件在内存中的起始地址和大小传递给内核。内核在启动初始化过程中会解压缩initrd文件,然后将解压后的initrd挂载为根目录,然后执行根目录中的 /init 脚本(cpio格式的initrd为/init,而image格式的initrd<也称老式块设备的initrd或传统的文件镜像格式的initrd>为/initrc),您就可以在这个脚本中运行initrd 文件系统中的udevd,让它来自动加载realfs(真实文件系统)存放设备的驱动程序以及在/dev目录下建立必要的设备节点。在udevd自动加载磁盘驱动程序之后,就 可以mount真正的根目录,并切换到这个根目录中来。