init repo

This commit is contained in:
superconvert 2022-07-24 23:14:23 +08:00 committed by GitHub
commit e1611d3675
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 548 additions and 0 deletions

81
01_run_nat.sh Normal file
View File

@ -0,0 +1,81 @@
#!/bin/sh
#---------------------
# 停掉 NAT
#---------------------
stop() {
# 停掉 tap0
ip link set tap0 down
# 断开与网桥链接
brctl delif br0 tap0
# 停掉网桥
ip link set br0 down
# 删除设备 tap0
ip tuntap del mode tap tap0
# 删除网桥
brctl delbr br0
}
#---------------------
# 启动 NAT
#---------------------
start() {
# 创建虚拟网桥
brctl addbr br0
# 创建虚拟tap设备
ip tuntap add dev tap0 mode tap
# 将tap设备介入网桥
brctl addif br0 tap0
# 配置网桥ip
ip addr add 192.168.100.1/24 dev br0
ip addr add 192.168.100.2/24 dev tap0
# 启动桥设备和虚拟网卡设备
ip link set br0 up
ip link set tap0 up
# 配置iptables forward转发规则
# 在基本环境搭建这一节中设置了一个本地网络虚机只能访问host无法访问外网如果需要访问外网需要设置SNAT
iptables -t nat -A POSTROUTING -s 192.168.100.0/24 ! -d 192.168.100.0/24 -j MASQUERADE
# 开启物理网卡的转发功能:
sysctl -w net.ipv4.ip_forward=1
# 如果有防火墙的特别是centos系统中记得放开防火墙
iptables -A FORWARD -s 192.168.100.0/24 -j ACCEPT
}
#----------------------
# DNS 服务
#----------------------
start_dns() {
# 准备dnsmasq配置文件,启动dnsmasq服务这样就能为虚拟机自动分配IP了
cat<<EOF>dnsmasq.conf
strict-order
pid-file=/var/run/dnsmasq.pid
except-interface=lo
bind-interfaces
listen-address=192.168.0.1
dhcp-range=192.168.100.2,192.168.100.254
dhcp-no-override
dhcp-leasefile=/var/lib/libvirt/dnsmasq/default.leases
dhcp-lease-max=253
dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile
addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts
EOF
/usr/sbin/dnsmasq --conf-file=./dnsmasq.conf
}
stop_dns() {
# 杀掉 dhcp 服务
killall dnsmasq
}
#----------------------------------------------
# 运行 smart-os 前,先启动这个,这样就能上网了
#----------------------------------------------
if [ -n "$1" ];then
stop
echo "stop"
else
start
echo "start"
fi

37
02_make_sdb.sh Normal file
View File

@ -0,0 +1,37 @@
#!/bin/sh
#----------------------------------------------
#
# 制作磁盘
#
#----------------------------------------------
echo "${CYAN}开始制作磁盘...${NC}"
# 创建磁盘 64M
dd if=/dev/zero of=extra.img bs=1M count=64
# 对磁盘进行分区一个主分区
fdisk extra.img << EOF
n
p
w
EOF
echo "${GREEN}磁盘制作成功!!!${NC}"
echo ".........................................................."
# 磁盘镜像挂载到具体设备
loop_dev=$(losetup -f)
# fdisk -l disk.img 查看 start 为 2048, unit 512 所以 -o 偏移扇区 1048576 = 2048 x 512
losetup -o 1048576 ${loop_dev} extra.img
# 对磁盘进行格式化
mkfs.ext3 ${loop_dev}
losetup -d ${loop_dev}

282
03_build_disk.sh Normal file
View File

@ -0,0 +1,282 @@
#!/bin/sh
red='\e[0;41m' # 红色
RED='\e[1;31m'
green='\e[0;32m' # 绿色
GREEN='\e[1;32m'
yellow='\e[5;43m' # 黄色
YELLOW='\e[1;33m'
blue='\e[0;34m' # 蓝色
BLUE='\e[1;34m'
purple='\e[0;35m' # 紫色
PURPLE='\e[1;35m'
cyan='\e[4;36m' # 蓝绿色
CYAN='\e[1;36m'
WHITE='\e[1;37m' # 白色
NC='\e[0m' # 没有颜色
#----------------------------------------------
#
# 制作磁盘
#
#----------------------------------------------
# 创建磁盘 64M
dd if=/dev/zero of=disk.img bs=1M count=64
# 对磁盘进行分区一个主分区
fdisk disk.img << EOF
n
p
w
EOF
echo ".........................................................."
# 磁盘镜像挂载到具体设备
loop_dev=$(losetup -f)
# fdisk -l disk.img 查看 start 为 2048, unit 512 所以 -o 偏移扇区 1048576 = 2048 x 512
losetup -o 1048576 ${loop_dev} disk.img
# 对磁盘进行格式化
mkfs.ext3 ${loop_dev}
diskfs="diskfs"
# 挂载磁盘到本地目录
mkdir -pv ${diskfs}
mount -t ext3 ${loop_dev} ${diskfs}
# 安装grub 引导
grub-install --boot-directory=${diskfs}/boot/ --target=i386-pc --modules=part_msdos disk.img
#----------------------------------------------
#
# 下载源码
#
#----------------------------------------------
mkdir -pv source
cd source
#KERNEL_SOURCE_URL=https://kernel.org/pub/linux/kernel/v4.x/linux-4.14.9.tar.xz
KERNEL_SOURCE_URL=https://mirror.bjtu.edu.cn/kernel/linux/kernel/v4.x/linux-4.14.9.tar.xz
if [ ! -f "linux-4.14.9.tar.xz" ]; then
wget $KERNEL_SOURCE_URL
fi
BUSYBOX_SOURCE_URL=https://busybox.net/downloads/busybox-1.34.1.tar.bz2
if [ ! -f "busybox-1.34.1.tar.bz2" ]; then
wget $BUSYBOX_SOURCE_URL
fi
cd ..
#---------------------------------------------
#
# 制作内核和 rootfs
#
#---------------------------------------------
mkdir -pv work
mkdir -pv rootfs
mkdir -pv rootfs/dev
mkdir -pv rootfs/etc
mkdir -pv rootfs/sys
mkdir -pv rootfs/mnt
mkdir -pv rootfs/tmp
mkdir -pv rootfs/lib
mkdir -pv rootfs/sbin
mkdir -pv rootfs/proc
mkdir -pv rootfs/root
mkdir -pv rootfs/lib64
mkdir -pv rootfs/lib/modules
if [ ! -d "./work/linux-4.14.9" ]; then
tar xvf source/linux-4.14.9.tar.xz -C work/
fi
if [ ! -d "./work/busybox-1.34.1" ]; then
tar xvf source/busybox-1.34.1.tar.bz2 -C work/
fi
cd work
# 编译内核, 最终所有模块都装到目录 /lib/modules/4.14.9
if [ ! -f "./linux-4.14.9/arch/x86_64/boot/bzImage" ]; then
# Enable the VESA framebuffer for graphics support.
# 网络需要 TUN/TAP 驱动 [ Device Drivers ] ---> [ Network device support ] ---> [ Universal TUN/TAP device driver support ]
cd linux-4.14.9 && make x86_64_defconfig && sed -i "s/.*CONFIG_FB_VESA.*/CONFIG_FB_VESA=y/" .config && make bzImage -j8 && cd ..
#cd linux-4.14.9 && make x86_64_defconfig && make bzImage -j8 && make modules && make modules_install && cd ..
fi
# 拷贝内核镜像
cp linux-4.14.9/arch/x86_64/boot/bzImage ../${diskfs}/boot/bzImage
# 编译 busybox
if [ ! -d "./busybox-1.34.1/_install" ]; then
# 静态编译 sed -i "s/# CONFIG_STATIC is not set/CONFIG_STATIC=y/g" .config
cd busybox-1.34.1 && make defconfig && make -j8 && make install && cd ..
fi
# 拷贝 busybox 到 rootfs
echo "${CYAN}开始制作rootfs...${NC}"
cp busybox-1.34.1/_install/* ../rootfs/ -r
cd ..
#-----------------------------------------------
#
# 制作启动文件系统 initramfs
#
#-----------------------------------------------
cd rootfs
# 这种方法也可以 mkinitramfs -k -o ./${diskfs}/boot/initrd 4.14.9
# 利用 Busybox 采用脚本制作 init 脚本 https://blog.csdn.net/embeddedman/article/details/7721926
make_init() {
cat<<"EOF">init
#!/bin/sh
# 必须首先挂载,否则 mdev 不能正常工作
mount -t sysfs none /sys
mount -t proc none /proc
mount -t devtmpfs none /dev
mount -t tmpfs none /tmp -o mode=1777
# 必须挂载一下,否则下面的 mount 不上
mdev -s
mount -t ext3 /dev/sda1 /mnt
# 关闭内核烦人的输出信息
echo 0 > /proc/sys/kernel/printk
echo -e "\n\e[0;32mBoot took $(cut -d' ' -f1 /proc/uptime) seconds\e[0m"
mkdir -p /dev/pts
mount -t devpts none /dev/pts
# 切换之前,修改 mount 路径
mount --move /dev /mnt/dev
mount --move /sys /mnt/sys
mount --move /proc /mnt/proc
mount --move /tmp /mnt/tmp
# 切换到真正的磁盘系统上 rootfs(initramfs) ---> diskfs
exec switch_root /mnt /sbin/init
EOF
# /sbin/init [switch_root 执行] ---> /etc/inittab [定义了启动顺序] --->
# /etc/init.d/rcS [系统 mount, 安装驱动,配置网络] --->
# /etc/init.d/rc.local [文件配置应用程序需要的环境变量] --->
# /etc/profile [部分初始化]
chmod +x init
}
make_init
# 下面这些不用了,利用脚本里面的 busybox 的 mdev -s 自动挂载
# mknod -m 644 dev/tty0 c 4 1
# mknod -m 644 dev/tty c 5 0
# mknod -m 600 dev/console c 5 1
# mknod -m 644 dev/null c 1 3
# mknod -m 640 dev/sda1 b 8 1
# 指定了利用 /etc/init.d/rcS 启动
cat<<"EOF">etc/inittab
::sysinit:echo "sysinit 1++++++++++++++++++++++++++++++++++++++"
::sysinit:/etc/init.d/rcS
::sysinit:echo "sysinit 2++++++++++++++++++++++++++++++++++++++"
::restart:/sbin/init
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
tty1::once:echo "hello smart-os tty1"
tty1::respawn:/bin/sh
tty2::once:echo "hello smart-os tty2"
tty2::respawn:/bin/sh
tty3::once:echo "hello smart-os tty3"
tty3::respawn:/bin/sh
EOF
# dns 测试
# 0. 启动脚本 run_nat.sh
# 1. busybox 必须动态编译
# 2. ifconfig eth0 192.168.100.6 && ifconfig eth0 up
# 3. route add default gw 192.168.100.1
# 4. echo "nameserver 114.114.114.114" >> /etc/resolv.conf
cp -rf ../fixed/lib* lib/ && cp ../fixed/ld-linux-x86-64.so.2 lib64/
find . | cpio -R root:root -H newc -o | gzip -9 > ../${diskfs}/boot/initrd
echo "${GREEN}rootfs制作成功!!!${NC}"
echo ".........................................................."
cd ..
#--------------------------------------------------------------
#
# 生成磁盘文件系统(利用 busybox 结构,省的自己创建了)
#
#--------------------------------------------------------------
echo "${CYAN}开始制作diskfs...${NC}"
cp rootfs/* ${diskfs} -r
rm -rf ${diskfs}/init && rm -rf ${diskfs}/linuxrc && rm -rf ${diskfs}/lost+found
# 我们测试驱动, 制作的镜像启动后,我们进入此目录 insmod hello_world.ko 即可
./make_driver.sh $(pwd)/${diskfs}/lib/modules
# 编译网卡驱动 ( 目前版本内核已集成 e1000 )
# cd work/linux-4.14.9 && make M=drivers/net/ethernet/intel/e1000/ && cd ../..
# 生成 grub.cfg 文件
cat - > ${diskfs}/boot/grub/grub.cfg << EOF
set timeout=6
menuentry "smart-os" {
root=(hd0,msdos1)
linux /boot/bzImage console=tty0
initrd /boot/initrd
}
EOF
# 生成 rcS 文件
title=$(cat<<EOF
\e[0;36m
..######..##.....##....###....########..########..........#######...######.
.##....##.###...###...##.##...##.....##....##............##.....##.##....##
.##.......####.####..##...##..##.....##....##............##.....##.##......
..######..##.###.##.##.....##.########.....##....#######.##.....##..######.
.......##.##.....##.#########.##...##......##............##.....##.......##
.##....##.##.....##.##.....##.##....##.....##............##.....##.##....##
..######..##.....##.##.....##.##.....##....##.............#######...######.
\e[0m
EOF
)
mkdir -pv ${diskfs}/etc/init.d
cat - > ${diskfs}/etc/init.d/rcS << EOF
#!/bin/sh
echo -e "\n“${title}”\n"
# 测试驱动加载
cd /lib/modules && insmod hello_world.ko
# dns 测试
ifconfig eth0 192.168.100.6 && ifconfig eth0 up
route add default gw 192.168.100.1
echo "nameserver 114.114.114.114" >> /etc/resolv.conf
# exec 执行 /etc/init.d/rc.local 脚本
EOF
chmod +x ${diskfs}/etc/init.d/rcS
cat -> ${diskfs}/rtmpd.sh << EOF
wget http://www.qiyicc.com/download/rtmpd.zip
unzip rtmpd.zip
rm rtmpd.zip -rf
cd rtmpd
mv smart_rtmp/smart_rtmpd.multithread.centos* ./
tar zxvf *.tar.gz
rm *.tar.gz -rf
rm smart_rtmp -rf
EOF
chmod +x ${diskfs}/rtmpd.sh
echo "${GREEN}diskfs制作成功!!!${NC}"
echo ".........................................................."
# 卸载映射
umount ${loop_dev}
losetup -d ${loop_dev}

44
04_run_docker.sh Normal file
View File

@ -0,0 +1,44 @@
#!/bin/sh
dock_name=smart-os
loop_dev=$(losetup -f)
# fdisk -l disk.img 查看 start 为 2048, unit 512 所以 -o 偏移扇区 1048576 = 2048 x 512
losetup -o 1048576 ${loop_dev} disk.img
# 挂载磁盘到本地目录
mkdir -p ./tmp_docker
mount -t ext3 ${loop_dev} ./tmp_docker
cd ./tmp_docker
tar -cvpf ../${dock_name}.tar --directory=./ --exclude=proc --exclude=sys --exclude=dev --exclude=run --exclude=boot .
cd ..
umount ./tmp_docker
rm -rf ./tmp_docker
losetup -d ${loop_dev}
# 删除镜像
clear() {
if [ ! "`docker ps -a | grep ${dock_name}`" = "" ] ; then
docker stop `docker ps -a | grep ${dock_name} | awk '{print $1}'`
docker rm `docker ps -a | grep ${dock_name} | awk '{print $1}'`
fi
if [ ! "`docker images -a | grep ${dock_name}`" = "" ] ; then
docker rmi `docker images -a | grep ${dock_name} | awk '{print $1}'`:1.0
fi
}
# 导入镜像
run() {
cat smart-os.tar | docker import - ${dock_name}:1.0
docker run -t -i ${dock_name}:1.0 /bin/sh
}
clear
run
clear
# 删除镜像文件
if [ -f "${dock_name}.tar" ]; then
rm -rf ${dock_name}.tar
fi

12
04_run_qemu.sh Normal file
View File

@ -0,0 +1,12 @@
#!/bin/sh
# 启动镜像 网络对应 run_nat.sh 里面的配置
qemu-system-x86_64 -drive format=raw,file=disk.img -netdev tap,id=nd0,ifname=tap0 -device e1000,netdev=nd0
#----------------------------------------------------
#
# 多硬盘测试 -hdb extra.img
#
#----------------------------------------------------
# make_sdb.sh
# qemu-system-x86_64 -drive format=raw,file=disk.img -hdb extra.img

35
README.md Normal file
View File

@ -0,0 +1,35 @@
# 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、satau-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真正的根目录并切换到这个根目录中来。

21
cat_disk.sh Normal file
View File

@ -0,0 +1,21 @@
loop_dev=$(losetup -f)
# fdisk -l disk.img 查看 start 为 2048, unit 512 所以 -o 偏移扇区 1048576 = 2048 x 512
losetup -o 1048576 ${loop_dev} disk.img
# 挂载磁盘到本地目录
mkdir -p ./mnt1
mount -t ext3 ${loop_dev} ./mnt1
echo "/ ---------------------------------------"
ls ./mnt1/
echo "boot ---------------------------------------"
ls ./mnt1/boot
echo "sbin ---------------------------------------"
ls ./mnt1/sbin
echo "etc ---------------------------------------"
ls ./mnt1/etc
echo "dev ---------------------------------------"
ls ./mnt1/dev
umount ./mnt1
rm -rf mnt1
losetup -d ${loop_dev}

36
make_driver.sh Normal file
View File

@ -0,0 +1,36 @@
#!/bin/sh
mkdir -pv driver && cd driver
cat<<EOF>hello_world.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
MODULE_LICENSE("GPL");
static int __init hello_world_init(void)
{
printk(KERN_DEBUG "hello world!!!\n");
return 0;
}
static void __exit hello_world_exit(void)
{
printk(KERN_DEBUG "goodbye world!!!\n");
}
module_init(hello_world_init);
module_exit(hello_world_exit);
EOF
cat<<EOF>Makefile
obj-m += hello_world.o
all:
make -C ../work/linux-4.14.9 M=`pwd` modules
clean:
make -C ../work/linux-4.14.9 M=`pwd` clean
EOF
echo $1
make && mv hello_world.ko $1 && make clean && cd .. && rm -rf driver