树莓派折腾笔记_2_最小文件系统制作及u-boot引导

树莓派最小文件系统制作

在上一篇博客中,我们已经在树莓派中正常的启动了u-boot,并把控制权交给了u-boot,那么我们如果要正常的使用一个linux系统的话,就还需要通过u-boot去引导一个linux系统,将系统控制权交给linux。所以在本篇博客中,我们首先制作一个最小的linux系统,然后再让u-boot去引导它。

准备工作

树莓派3B

SD卡

读卡器

linux kernel源码:https://github.com/raspberrypi/linux.git

busybox源码:https://busybox.net/downloads/

说明:在本文中,我是用的busybox源码是busybox-1.31.0,linux kernel源码是linux-rpi-4.19.y

 

制作最小的linux文件系统

首先,我们需要构建一个最小的linux文件系统,也就是放在我上一篇博客中提到的rootfs分区。而busybox作为linux系统的瑞士军刀,提供了三百多个常用的linux命令和工具软件,如ls,cd,cat等等,所以,在这里我们使用busybox去构建一个最小的linux文件系统。

busybox编译

首先进入busybox源码目录,只想下面的命令。生成配置.config文件

make defconfig

之后,如还需要进行一些自定义的配置,可以通过make menuconfig命令,进行图形化配置

make menuconfig

在图形化界面,进入Settings 、设置Cross conpiler prefix 和install 目录

树莓派折腾笔记_2_最小文件系统制作及u-boot引导_第1张图片

在这里我将交叉编译器设置为arm-linux-gnueabi-,安装目录为当前目录的rootfs目录,这个你可以根据你的交叉编译器自己设定。

设置后,保存并退出。

然后再源码根目录make,进行编译。

编译完成后,执行make install

然后,你就会在当前目录下,看到一个rootfs目录,该目录下,会有bin、sbin、usr三个文件夹和linuxrc文件,当然这三个文件夹还是不够的

添加必要的配置文件和目录

1、首先创建一些必备的文件夹

mkdir dev etc lib mnt proc sys tmp var
/*
 * 说明
 * dev 目录主要共系统生成各类设备节点
 * etc 系统的配置文件
 * lib 系统需要的各类库文件
 * mnt 一般用来挂载其他设备的的目录
 * sys 系统文件
 * tmp 临时文件
 * var
 * proc 内存虚拟文件系统节点
 */

2、在etc目录下,创建init.d文件夹

3、在init.d文件夹下,创建rcS文件 vim rcS,并输入以下内容:

#! /bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:

runlevel=S

prevlevel=N

umask 022

export PATH runlevel prevlevel


#
 
# Trap CTRL-C &c only in this shell so we can interrupt subprocesses.
 
#
 
trap ":" INT QUIT TSTP
 
/bin/hostname 4Log


#/bin/mount -n -t proc none /proc
 
#/bin/mount -n -t sysfs none /sys
 
#/bin/mount -n -t usbfs none /proc/bus/usb

#/bin/mount -t ramfs none /dev

[ -e /proc/1 ] || /bin/mount -n -t proc none /proc

[ -e /sys/class ] || /bin/mount -n -t sysfs none /sys

[ -e /dev/tty ] || /bin/mount -t ramfs none /dev


# support hotplug with mdev
echo /sbin/mdev > /proc/sys/kernel/hotplug

/sbin/mdev -s


# mounting file system specified in /etc/fstab
 
mkdir -p /dev/pts
 
mkdir -p /dev/shm
 
/bin/mount -n -t devpts none /dev/pts -o mode=0622
 
/bin/mount -n -t tmpfs tmpfs /dev/shm
 
#/bin/mount -n -t ramfs none /tmp
 
#/bin/mount -n -t ramfs none /var
 
mkdir -p /var/empty
 
mkdir -p /var/log
 
mkdir -p /var/log/boa
 
mkdir -p /var/lock
 
mkdir -p /var/run
 
mkdir -p /var/tmp



ln -sf /dev/ttyS2 /dev/tty2
 
ln -sf /dev/ttyS2 /dev/tty3
 
ln -sf /dev/ttyS2 /dev/tty4
 
 
syslogd
  
 
#echo "-------------------------------------"
 
#echo "                4Log                 "
 
#echo "-------------------------------------"

然后将修改rcS文件权限

chmod 755 rcS

4、在etc目录创建passwd文件,并键入以下内容:

root::0:0:root:/:/bin/sh
 
bin:*:1:1:bin:/bin:
 
daemon:*:2:2:daemon:/sbin:
 
nobody:*:99:99:Nobody:/:

修改权限

chmod 755 passwd

5、在etc目录创建profile文件,并键入一些内容

ulimit -S -c 0 > /dev/null 2>&1


USER="`id -un`"
 
LOGNAME=$USER
 
PS1='[$USER@$HOSTNAME]# '
 
PATH=$PATH
 
 
HOSTNAME=`/bin/hostname`
 
export USER LOGNAME PS1 PATH

修改权限

chmod 755 profile

6、进入var目录,mkdir lib lock log run tmp

7、拷贝必须的lib文件,因为我们使用的交叉编译,在编译过程中,会依赖很多库,如C库,所以我们需要去将交叉编译器的lib库全部拷进lib文件夹。

 这里需要注意的是,一定要找到你编译用的交叉编译器用的lib库。

至此,整个文件系统就准备完成了,接下来就需要将该文件系统放到SD卡的rootfs分区中去。

在这里有两种办法,一个是将rootfs文件夹制作成img文件,通过dd命令,将img文件写入/dev/sdb2中,还有一种办法是将/dev/sdb2 mount 都进文件系统,然后将整个rootfs文件夹下的内容拷贝到那个节点。

kernel编译

拷贝进去后,我们已经完成了文件系统的制作,接下来就是kernel编译。

进入下载好的源码根目录中。

执行下面的命令,进行kernel的编译。

export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabi-
make bcmrpi_defconfig
make

这里需要注意的是,请根据自己实际使用的交叉编译器,替换我这里的arm-linux-gnueabi-

等个十来分钟后,

将编译好的zImage文件cp到SD卡的boot分区,并命名为kernel.img

然后插入树莓派,上电后不断的按空格键,打断uboot的自动引导,使系统停在u-boot阶段,如下图:

树莓派折腾笔记_2_最小文件系统制作及u-boot引导_第2张图片

进入u-boot后,输入printenv命令,我们可以看到整个u-boot中所有的变量值,在这里我先简单介绍下uboot的引导过程,后面会有详细的博客讲解这一内容。

在uboot中,用户如果没有按空格键去干预uboot自动引导,uboot会首先去执行bootcmd脚本,也就是键入printenv命令后,输出中的bootcmd=****后面的内容

知道这个的话,我们就可以去修改这个变量的值,通过修改这个值来启动自己的kernel镜像。

首先,通过以下的命令修改这一值:

setenv selfcmd mmc dev 0;fatload mmc 0:1 0x00080000 kernel.img; fatload mmc 0:1 2eff9400 bcm2837-rpi-3-b.dtb;bootz 0x00080000 - 2eff9400

setenv bootcmd run selfcmd


saveenv

在这里需要说明的是,selfcmd变量的值的意思

mmc dev 0; //切换到0分区,也就是boot分区

fatload mmc 0:1 0x00080000 kernel.img; 将kernel.img 加载到0x00080000处

fatload mmc 0:1 2eff9400 bcm2837-rpi-3-b.dtb; 将设备树加载到0x2eff9400处

bootz 0x00080000 - 2eff9400 引导kernel.img 并指定设备树文件

需要说明的是,这里的两个地址,可以参考fdt_addr、fdt_addr_r、kernel_addr_r三个变量,这三个变量在printenv中可以看到。

 

还有一个变量bootdelay变量可以设置等待用户空格键的时常。

 

至此,重新上电后,系统就会自动引导kernel,并进入最小的linux系统

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(树莓派)