Skip to content

定制 Linux 系统

ChangeLog:

  • 20180409 – remount operation、mke2fs、nls package
  • 20180404 – build minimal rootfs with busybox

本文实验环境为 BeagleBone Black

0,编译 U-Boot 与 Linux Kernel

U-Boot:

Kernel:

1,准备一个 SD 卡,大小 1 G 左右即可;

删除分区:

$ sudo dd if=/dev/urandom of=/dev/mmcblk0 bs=1M count=30

拔插 SD 卡,用 lsblk 命令查看分区是否被删除

3,写 MLO 及 u-boot.img

sudo dd if=MLO of=/dev/mmcblk0 count=1 seek=1 bs=128k

sudo dd if=u-boot.img of=/dev/mmcblk0 count=2 seek=1 bs=384k

4,新建分区

$ sudo sfdisk /dev/mmcblk0 <<-EOF

>>4M,,L,*

>>EOF

$ sudo mkfs.ext4 -L GNU/Linux /dev/mmcblk0p1

$ sudo mount /dev/mmcblk0p1 /mnt/

2,放置根文件系统

$ sudo tar xvf ~/Downloads/debian-9.3-minimal-armhf-2017-12-09/armhf-rootfs-debian-stretch.tar -C /mnt/

3,拷贝编译好的 dtbs 及 linux 内核

$ sudo cp arch/arm/boot/zImage /mnt/boot/vmlinuz-4.14.29

$ sudo mkdir -p /mnt/boot/dtbs/4.14.29

$ sudo cp arch/arm/boot/dts/am335x-boneblack*.dtb /mnt/boot/dtbs/4.14.29

$ sudo touch /mnt/boot/uEnv.txt

$ sudo sh -c 'echo "uname_r=4.14.29" >> /mnt/boot/uEnv.txt'

$ sync

$ sudo umount /mnt

5,按住 S2 启动

出现 无法登录 Linux 错误

6,修改权限

$ sudo mount /dev/mmcblk0p1 /mnt

$ sudo chmod 755 /mnt

$ sync

7,再次启动之后成功登录!

8,定制化的根文件系统

上述流程中,debian-9.3-minimal-armhf-2017-12-09 这个根文件系统是制作好的,在定制化产品设计时我们很可能需要自己剪裁制作根文件系统,将不需要的命令,库都剪掉,保证系统的足够的小。以下简述基于 busybox 制作根文件系统的大致流程:

  • 下载 busybox 源码;
  • 配置并编译 busybox;
  • 创建 dev/console、dev/null;
  • 复制 /usr/arm-linux-gnueabi/lib/* 里面的 C 库到 lib 目录;
  • echo "console::askfirst:-/bin/sh" >> etc/inittab;
  • 制作好后根文件系统目录:bin boot dev etc lib linuxrc sbin usr
  1. bin linuxec sbin usr: 编译 busybox 安装以后得到的;
  2. boot: 存放 uEnv.txt,和上述流程中的一致;
  3. dev:  存放 console、null 两个字符设备;
  4. etc:  存放 inittab;
  5. lib:  存放 C 库;

9,再次启动

 

 

10,挂接 proc 文件系统

很多应用程序需要使用到 proc 文件系统,例如 ps、ifconfig 等,因此挂载 proc 文件系统。

mount -t proc proc /proc

11,挂接 NFS 文件系统

NFS (Network File System) 在嵌入式开发中可以极大便利调试过程,目标机器通过 mount 命令将服务器的某个目录(nfs文件系统)挂接到本地,这样就可以在服务器编译开发程序,在目标机器里执行验证程序。以下简述 NFS 的使用:

服务器端:

搭建 NFS Server

sudo apt-get install nfs-kernel-server

cat /etc/exports

/home/user/exportfs 192.168.1.*(rw,sync,no_root_squash,no_subtree_check)

将这个配置填入 /etc/exports 为 nfs server 所用,对 192.168.1 网段的所有客户机开放 /home/user/exportfs 目录 nfs 挂接。

更新 nfs table

sudo exportfs -a

重新加载 nfs 服务

sudo /etc/init.d/nfs-kernel-server reload

目标机端:

/ # mount -t nfs -o nolock 192.168.1.11:/home/gimcuan/exportfs /mnt

这里 192.168.1.11 即为服务器某网卡的 ip 地址。需要注意的是,目标机的网络地址需要和服务器处于同一网段。

12,自动挂接

如何实现自动挂接文件系统?在 init 进程启动时会去 /etc/inittab 遍历需要执行的 actions,因此我们可以在 /etc/inittab 里面添加:

::sysinit:/etc/init.d/rcS

cat /etc/inittab

console::askfirst:-/bin/sh
::sysinit:/etc/init.d/rcS

内核启动 init 进程后,init 进程会去执行 /etc/init.d/rcS 脚本:

cat /etc/init.d/rcS

mount -t proc none /proc

13,重新挂载根文件系统

根据上述步驟中制作好的根文件系统被挂接为只读,用以下命令重新挂载为可读写

mount -o rw,remount /

14,文件系统格式工具 – mke2fs

mkfs.ext2、mkfs.ext3、mkfs.ext4 均为指向 mke2fs 的软链接,mke2fs 为 e2fsprogs 程序包编译而来

15,eMMC 挂载失败解决办法

错误一:

[ 5706.828042] FAT-fs (mmcblk1p1): codepage cp437 not found

需加载 nls_cp437.ko 内核模块: insmod nls_cp437.ko

错误二:

[ 6199.821599] FAT-fs (mmcblk1p1): IO charset ascii not found

需加载 nls_ascii.ko 内核模块: insmod nls_ascii.ko

mount -t vfat /dev/mmcblk1p1 /tmp/boot/ -o sync

-t vfat 表明 /dev/mmcblk1p1 为 FAT 文件系统格式,可以省略掉

外部链接:

1,Build U-Boot and Linux Kernel for Beaglebone and Beaglebone Black

2,NFS Server setup

程序员的自我修养

做软件开发已经快三年啦,总结一些个人观点,看官见笑了。

1,代码风格

作为一名底层开发者,我更倾向于Linux内核编码风格。但工作往往需要交接别人的项目,代码风格往往与自己的不一样。这种情况下我会遵循这份代码的风格进行。当然,还有一种更常见的情况就是大部分项目都是由多个人协同开发,每个人风格也往往不一致。这种情况下,至少应该做到模块代码风格一致,修改别人代码的时候按照别人的风格来,而不是改成自己喜欢的‘款式’。

2,参与开源项目

作为一名程序员,会多门编程语言可以提高自己的视野格局,知道这些语言各自的优势与不足。但往往很难同时对几个语言保持很熟悉,可以信手拈来的状态。因为工作的时候用得多的往往就是一门主要的编程语言,而参与著名的开源项目就可以完美解决这个问题。还有附带的好处就是在观摩诸位大神的补丁时能学到很多东西。架构师看到的是美的架构,入门者看到是简洁的代码,那就是一千个 Programmers 眼里有一千个学问。技多不压身,诸位可以参考此法。

3,有自己的项目

作为一位虚荣的程序员,我会想有自己的项目,然后用余生去维护它。是不是,原来一个程序员也可以很浪漫的。比如我 17 年开发的个人项目 Totoro,一个 ARM 系统内核,她让我理解了多线程切换在底层具体是如何实现的,以及如何编写一个简单的信号量,还有即将开发的软中断特性。

4,坚守自己的价值观

不要为了钱轻易去转行。08年互联网开始大热,大批程序员涌向互联网,至今这种风气依旧盛行。这大部分人可能觉得钱多就去哪里,所谓的‘面向工资编程’。看起来很可笑,却很多人在走着这样的路,或朝着这样的路走去。对此我深感悲痛。我认为一个有好的价值观的程序员,应该思考如何在自己的领域更加精进一步,发现这个领域的魅力,领悟它,感受它,甚至完善它。

5,修改代码的习惯

该删除的,不需要的代码都删掉,不要留着。用版本管理工具去管理代码,而不是一堆中文注释,一堆没用的垃圾代码。

本科四年

第一次知道单片机,是在开学的新老生交流会上,当时大三的胡学长跟我们大一讲的,当时就被这个神奇的词汇所吸引住了。便和舍友一起到图书馆借书,我借了一本叫《单片微型计算机原理及其C语言程序设计/陈光东》的单片机书籍。当时刚好军训结束,又遇上了长假七天的国庆节,便把书带回家,一到家里便热情万丈地阅读了起来。结合郭天祥的十天学会单片机视频教程,我几乎在废寝忘食的七天把51架构的一款单片机学得差不多了。当然,对于当时的差不多,现在看来是严重不足的。跟着老师做几个肤浅的实验哪能研究出什么来呢?当时想,至少我是领先的,大家都没在学,只有我学了。就这样在自我保持优越感中度过了大一。总结了一下,大一的时候思想一直比较稚嫩,比较单纯,吃过亏,但从来没后悔过每一个决定,大一的生活,我就已经开始了一个人四点一线的生活,其中滋味也只有自己才能品尝出些来吧。

很快就来到了大二,因为大一确实过得很无聊,至少对我来说是这样的。没有目标,没有追求,几乎什么概念都没有。一次偶然的机会(其实带着必然),胡学长因为要出去工作了,学校里还有一个项目没有完成,我就轻而易举的得到了挑战杯比赛的一个很好的名额。充当着这个比赛队伍里唯一的技术人员,我用一个月的时间把自己的任务完成了。用stm32采集摄像头数据,并显示在了液晶屏上,算是一个小型的简易摄像机,只不过没有存储的功能(哈哈)。最终只获得了省二等,很遗憾的跟这个比赛说再见了。大二下学期,也参加了全国范围的智能车比赛,经过一个学期的努力奋斗,外挂一科,也只在华南赛区获得三等奖。又差不多跟这个比赛说再见了。这是第一次挂科,第二次就是在大三了。大二,认识了一些其他学院的同学,交际能力似乎处于平行上升的一个状态,平行,是指迂回,上升又是一种自我感觉良好的心情。不管怎样,人要有自己的想法,不能被大众化的思维所误导了。但又不能太过标新立异,怕中枪。这么说来,为人处世确实是一门大学问啊。遇到过喜欢的女生,也接近过,交流过,最不好的就是那个时候发现思维对不上,爱情,我觉得就是一种两个人互相欣赏,看到对方都能有一种很愉悦的心情的一种活动,不需粉饰,也可以浪漫得起来的一种情感。总结一下,大二的生活似乎比大一更艰难了点,因为价值观受到了一次次猛烈的冲击。但内心比较强大,一直保持比较好的心态,我是一个比较能包容的人。整体来说,是一个比较好的阶段,因为努力,敢于追求,不后悔,因为执着。

终于来到了期盼已久的大三,一直以为大三是一个展示自己的舞台与时刻。我开始挑战自学嵌入式Linux应用开发技术,结合各培训机构的视频课程乐滋滋的学了起来。第一天就是13年9月3号,第三年。然而,当我装完虚拟机,并在上面安装了Ubuntu操作系统之后,我发现我到底应不应该继续学习下去,Linux手册里繁杂众多的操作命令,我是不是要一个个学下来?我这样学对不对?尽管我是按照从网上下载培训资料的课程顺序学的,却对自己发出了这样的疑问。一个多月后我终于撑不住了,果断停止对它的学习。看着身边的同学,有的开始准备考研了,我也在想了,要不要考研?经过一段时间的思索,我便开始着手买了一些考研的书籍,把嵌入式学习扔在一边了。开始了为期一个月的考研。也就是我准备了一个月后,又放弃了!天,我怎么这样优柔寡断?后面,实验室的老师把我叫去了,迫于情面,我开始了第二次智能车生涯。寒假的二十几天,差不多把任务完成了,准备开学进行交接就先撤了。命运的女神如此的残酷,我又不得不继续在实验室待下去了。(其实我有选择权,但总是碍于情面)直到下学期的期末考快要来临的时候,我又开始再思考,要不要继续考研?在我纠结万分的那个时候,她出现了。她似乎是上帝派来拯救我的吧!我便毅然决然地向老师辞去了差事。开始人生的第一个正式的恋爱。曾经有句话:当上帝关上一扇窗后,他会为你打开另一扇门。唯一觉得做得正确的是,当时的勇气与果断!不让自己后悔。我们一起考研直到考研结束,一起应付期末考直到期末结束,那段日子,好美。总结一下,大三似乎是最最幸福的了。(哈)

这篇文章是对过去的总结,更作为一个新的开始!我想从事IT行业,并热衷于此。算法之路,今起程!铭记,十年磨一剑!

写于2015年2月6号晚至7号晨。