热度 2
2023-10-28 15:30
448 次阅读|
0 个评论
一、Linu启动流程简要分析 想要适配rootfs,就得先了解Linux开发板常见启动流程。详细的启动过程我们这里就不再多说了,别的大佬说的更好。 这里简单说明一下,开发板上电后,当然是Bootloader先启动了,不同的板子有不同的过程。 然后UBoot启动完之后,会传递启动参数给内核,然后跳转到内核。 内核启动后会尝试加载rootfs,并从里面特定目录里查找init程序。 然后init程序会开始运行初始化系统服务的程序(我们的镜像用的OpenRC),然后OpenRC负责启动各种服务。 例如这是传递了一个有问题的rootfs给内核,内核找不到init程序,然后报错了。 二、docker运行Alpine Linux容器 其实docker是个不错的rootfs提取工具,基本上各个平台的发行版都有。 下载速度还很快,版本任你选,还可以在集成到SDK之前在电脑上把想安装的软包和源都给处理好。 废话不多说,现在开始搞。 2.1 先创建一个100M的临时文件,用来存储新的rootfs dd if=/dev/zero of=rootfs.ext4 bs=1M count=100 2.2 格式化该临时文件 mkfs.ext4 rootfs.ext4 2.3 挂载该临时文件系统到/tmp/my-rootfs mkdir /tmp/my-rootfs sudo mount rootfs.ext4 /tmp/my-rootfs 2.4 开启虚拟化支持(如果重启了WSL或者电脑,就需要从这一步开始) docker run --rm --privileged multiarch/qemu-user-static --reset --persistent yes 2.5 创建名称为armv7alpine的容器 docker run -it \ --name armv7alpine \ --net=host \ -v /tmp/my-rootfs:/my-rootfs \ arm32v7/alpine 接下来所有的操作都是在这个armv7alpine容器内完成的,一直到创建Alpine根文件系统压缩包完成。 三、修改源 由于官方源速度比较慢,我们需要将Alpine Linux的官方源替换成阿里源。修改好用apk update命令测试一下。 sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories apk update 四、安装启动服务软件和配置串口 4.1 安装openrc 根据第一节内容的说明,大家已经简单了解了Linux的启动过程。 安装openrc很简单,就是输入下面这一行命令就行了。 apk add openrc 安装完OpenRC,还需要配置一些东西,接下来继续搞。 4.2 启动必要服务 rc-update add devfs boot rc-update add procfs boot rc-update add sysfs boot 4.3 设置串口自动登录 在设置前,我们需要确认内核使用的默认串口设备是哪个。可以通过cat /proc/cmdline指令来确认内核使用的串口设备。 同时也可以在官方SDK里输入ls /dev/tty*来查看板子默认开启了哪些串口。 其实图片里是有tty1,tty3,tty4的,但是一般我们只用到ttyFIQ0,也懒得记这么多串口引脚。 4.3.1 添加串口到配置文件,这个文件是负责管理哪个串口能登录root用户 /etc/securetty 4.3.2 修改/etc/inittab文件,这个文件负责在串口设备上开启登录服务和别的一些东西 删除tty1到tty6开始的行,这一步一定要做,否则串口启动会卡死在找ttyX上。 添加这一行,允许串口自动登陆 ttyFIQ0::respawn:/sbin/agetty —autologin root ttyFIQ0 vt100 修改好的内容 # /etc/inittab ::sysinit:/sbin/openrc sysinit ::sysinit:/sbin/openrc boot ::wait:/sbin/openrc default # Set up a couple of getty's 这下面的删除掉 # Put a agetty on the serial port 这下面一行的改成这样,其他不变 ttyFIQ0::respawn:/sbin/agetty --autologin root ttyFIQ0 vt100 # Stuff to do for the 3-finger salute ::ctrlaltdel:/sbin/reboot # Stuff to do before rebooting ::shutdown:/sbin/openrc shutdown 好的,改完这些,现在的rootfs已经可以启动了。只是还不能使用网络安装软件包。 五、配置网络 5.1 添加网络接口配置 跟很多发行版一样,想永久配置网络设置,可以修改/etc/network/interfaces这个文件。 默认是没有这个文件的,使用以下命令新建 vi /etc/network/interfaces 然后将以下内容复制进去,记得改成自己的IP和对应网段,网关。 个人建议是使用静态IP,这样就不用反复去路由器确认自动获取的IP地址了。 auto eth0 iface eth0 inet static address 192.168.50.59 netmask 255.255.255.0 gateway 192.168.50.1 修改为记得将networking服务添加到默认启动队列,如果发现板子没有IP可以检查networking服务是否正常运行。 rc-update add networking default 5.2 修改域名解析服务器 编辑/etc/resolv.conf文件,将DNS服务器的IP地址更换成自己当地的服务器IP。 注意:这个文件在重启docker容器、重启电脑后会恢复 # This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry# # generateResolvConf = false nameserver 202.103.224.68 5.3 修改主机名称 编辑/etc/hostname这个文件,把里面的内容换成主机名称,例如这里是修改成了Luckfox。 主机名称在ssh远程登录进入shell、串口登录时会显示,用来标识主机。 六、安装和配置ssh服务 6.1 安装openssh软件包 没啥好说的,直接apk add openssh就行了 apk add openssh 6.2 配置ssh 打开/etc/ssh/sshd_config文件 将内容32行和57行修改成以下内容 # Authentication: #LoginGraceTime 2m PermitRootLogin yes #StrictModes yes #MaxAuthTries 6 #MaxSessions 10 #PubkeyAuthentication yes # To disable tunneled clear text passwords, change to no here! PasswordAuthentication yes 6.3 将sshd添加到默认级别队列,实现开机启动sshd rc-update add sshd default 七、配置开机启动ntpd实现网络校时 7.1 创建本地启动服务脚本 新建/etc/local.d/crond.start这个文件,在文件内添加一下内容。 这个开机服务脚本只做三件事情:ntp网络校时、开启crond定时任务、关闭板子led灯 #!/bin/bash ntpd -d -q && crond /sys/class/leds/work/brightness 保存后,给脚本添加可执行权限 chmod a+x /etc/local.d/crond.start 7.2 配置ntp服务器 新建/etc/ntp.conf文件,添加ntp服务器,这里用的是阿里云校时服务器。 文件内容如下: server ntp.aliyun.com iburst server ntp0.aliyun.com iburst server ntp1.aliyun.com iburst server ntp2.aliyun.com iburst 7.3 将local添加到默认级别队列 rc-update add local default 7.4 设置时区 Alpine Linux默认是不带多国语言支持和时区支持的。 需要安装tzdata包,复制了上海时区数据后,就可以把这个包删除了,能省一点是一点。 apk add tzdata && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \ /etc/timezone && apk del tzdata 做到这里,开机校时服务就完成了,但是busybox的ntpd程序只进行一次校时。 如果板子需要长期开启,期间需要更准确的时间,清按下一步步骤添加定时ntp校时配置。 7.5 设置crond定时任务 注意:这一步要烧录到板子之后,串口启动再做。现在做了也白搭,具体原因我也没去了解和分析。 7.5.1 创建/var/spool/cron/crontabs目录,用于保存定时配置 mkdir -p /var/spool/cron/crontabs 7.5.2 输入crontab -e命令编辑定时任务 crontab -e 然后将以下内容复制进去,保存 # do daily/weekly/monthly maintenance # min hour day month weekday command 0 */6 * * * ntpd -d -q 八、安装需要用到的软件包 到这一步,rootfs的定制工作基本上完成了,剩下的就是安装一些自己需要用到的软件包到rootfs里。 根据自己的需要进行调整,个人建议util-linux、btop、bash都安装一下。 apk add util-linux apk add sqlite btop apk add bash bash-completion 修改root用户默认登录的shell,打开/etc/passwd文件,将root这一行的末尾,ash修改成bash。 如下图所示: root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin 九、将rootfs打包并集成到SDK里完成镜像构建 9.1 打包rootfs 在/目录下执行以下命令 for d in bin etc lib root sbin usr; do tar c "$d" | tar x -C /my-rootfs; done for dir in dev proc run sys var; do mkdir /my-rootfs/${dir}; done cd /my-rootfs/ && tar czf alpine.tar.gz * 执行完毕之后,可以看到/tmp/my-rootfs目录下有一个alpine.tar.gz文件。 将这个文件复制到Luckfox的官方SDK的sysdrv/custom_rootfs目录下(自行创建目录)。 如下图所示 9.2 修改官方SDK根目录下的build.sh文件 打开SDK的build.sh,找到1044行的function __PACKAGE_ROOTFS()函数, 将build_get_sdk_version前的内容替换成以下内容: ``` function __PACKAGE_ROOTFS() { local rootfs_tarball _target_dir _install_dir if ; then if ; then rootfs_tarball="$RK_PROJECT_PATH_SYSDRV/rootfs_${RK_LIBC_TPYE}_${RK_CHIP}.tar" tar xf $rootfs_tarball -C $RK_PROJECT_OUTPUT else rootfs_tarball="$RK_CUSTOM_ROOTFS" if ; then mkdir $RK_PROJECT_PACKAGE_ROOTFS_DIR fi tar xf $rootfs_tarball -C $RK_PROJECT_PACKAGE_ROOTFS_DIR fi else msg_error "Not found rootfs tarball: $rootfs_tarball" exit 1 fi build_get_sdk_version ``` 9.3 修改SDK根目录下的.BoardConfig.mk文件 在文件末尾添加以下内容 # 配置自定义镜像目录 export RK_CUSTOM_ROOTFS=../sysdrv/custom_rootfs/alpine.tar.gz 然后执行以下命令删除output/out/rootfs_uclibc_rv1106目录 rm -rf output/out/rootfs_uclibc_rv1106 这个目录只是构建系统生成的临时rootfs,删除后能确保我们的rootfs生效 然后重新执行build.sh命令生成镜像即可,生成镜像后按常规方式烧录到Nand Flash就行了。 TF卡镜像目前还没研究好怎样处理,烧录后能用,就是根分区大小不能拓展。 ./build.sh 清理临时文件系统 如果以后很少用到,不想再自己折腾文件系统的,可以按此步骤执行。 关闭docker容器 docker stop armv7alpine 取消挂载 sudo umount /tmp/my-rootfs 删除文件 rm rootfs.ext4 参考文档 现代 Linux 的五大初始化系统 https://linux.cn/article-7873-1.html 史上最详细linux启动过程讲解—-没有之一 https://cloud.tencent.com/developer/article/1114481 Creating Custom rootfs and kernel Images https://www.cnblogs.com/dream397/p/13786186.html