根文件系统移植:bulidroot根文件系统搭建详细步骤

news2024/10/6 6:41:16

bulidroot根文件系统


文章目录

  • bulidroot根文件系统
  • 1.buildroot 下载
  • 2 配置 buildroot
    • 1、配置 Target options
    • 2、配置 Toolchain
    • 3、 配置 System configuration
    • 4、配置 Filesystem images
    • 5、 禁止编译 Linux 内核和 uboot
    • 6、配置 Target packages
  • 3 编译 buildroot
  • 4 buildroot 根文件系统测试
  • root用户登录
  • 5.buildroot 第三方软件和库的配置
  • 6.buildroot 下的 busybox 配置
    • 1.busybox 配置
    • 2 busybox 中文字符的支持
    • 3 编译 busybox
  • 7 根文件系统测试


使用 busybox 构建文件系统, busybox 仅仅只是帮我们构建好了一些常用的命令和文件,像 lib 库、 /etc 目录下的一些文件都需要我们自己手动创建,而且 busybox 构建的根文件系统默认没有用户名和密码设置。在后续的实验中,我们还要自己去移植一些第三方软件和库,比如 alsa、 iperf、 mplayer 等等。那么有没有一种傻瓜式的方法或软件,它不仅包含了 busybox 的功能,而且里面还集成了各种软件,需要什么软件就选择什么软件,不需要我们去移植。答案肯定是有的, buildroot 就是这样一种工具, buildroot比 busybox 更上一层楼, buildroot 不仅集成了 busybox,而且还集成了各种常见的第三方库和软件,需要什么就选择什么,就跟我们去吃自助餐一样,想吃什么就拿什么。 buildroot 极大的方便了我们嵌入式 Linux 开发人员构建实用的根文件系统。
从 busybox 开始一步一步的构建根文件系统适合学习、了解根文件系统的组成,但是不适合做产品(主要是自己构建的话会有很多不完善、没有注意到的细节)。 buildroot 会帮我们处理好各种细节,根文件系统也会更加的合理、有效。因此在做产品的时候推荐大家使用 buildroot 来构建自己的根文件系统,当然了,类似 buildroot 的软件还有很多,比如后面要讲的 yocto。buildroot 和 uboot、 Linux Kernel 很类似,我们需要到其官网上下载源码,然后对其进行配置,比如设置交叉编译器、设置目标 CPU 参数等,最主要的就是选择所需要的第三方库或软件。一切配置好以后就可以进行编译,编译完成了以后就会在一个文件夹里面存放好编译结果,也就是根文件系统

1.buildroot 下载

buildroot 源码肯定是要从 buildroot 官网下载,官网地址为 https://buildroot.org/, 打开以后的官网界面如图
在这里插入图片描述

2 配置 buildroot

将 buildroot 源码 buildroot-2019.02.6.tar.bz2 拷贝到 ubuntu 中,也就是我们前面创建的 tool目录下。拷贝完成以后对其进行解压,命令如下:

tar -vxjf buildroot-2019.02.6.tar.bz2

解压完成以后就会得到一个名为“buildroot-2019.02.6”的目录,此目录就是我们解压得到的 buildroot 源码,进入到此目录中,此目录下的文件如图
在这里插入图片描述

uildroot 和 uboot、 Linux kernel 一样也支持图形化配置,输入如下命令即可打开图形化配置界:

make menuconfig

打开以后的图形化配置界面如图

接下来我们就依次配置 buildroot,配置完成以后就可以进行编译了。

1、配置 Target options

首先配置 Target options 选项,需要配置的项目和其对应的内容如下(“=”号后面是配置项要选择的内容! ):

Target options
-> Target Architecture                             = ARM (little endian)
-> Target Binary Format                         = ELF
-> Target Architecture Variant                = cortex-A7
-> Target ABI                                          = EABIhf
-> Floating point strategy                       = NEON/VFPv4
-> ARM instruction set                           = ARM

配置完成以后如图所示:
在这里插入图片描述

2、配置 Toolchain

此配置项用于配置交叉编译工具链,也就是交叉编译器,这里设置为我们自己所使用的交叉编译器即可。 buildroot 其实是可以自动下载交叉编译器的,但是都是从国外服务器下载的,鉴于国内的网络环境,强烈推荐大家设置成自己所使用的交叉编译器。需要配置的项目和其对应的内容如下:

Toolchain
-> Toolchain type    = External toolchain
-> Toolchain            = Custom toolchain                //用户自己的交叉编译器
-> Toolchain origin = Pre-installed toolchain         //预装的编译器
-> Toolchain path    =/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf
-> Toolchain prefix         = $(ARCH)-linux-gnueabihf  //前缀
-> External toolchain gcc version                   = 4.9.x
-> External toolchain kernel headers series    = 4.1.x
-> External toolchain C library                       = glibc/eglibc
-> [] Toolchain has SSP support? (NEW)    //选中-> [] Toolchain has RPC support? (NEW)   //选中
-> [] Toolchain has C++ support?                 //选中-> [] Enable MMU support (NEW)              //选中

在这里插入图片描述

Toolchain 下几个比较重要的选项需要说明一下,如下所示:
Toolchain:设置为 Custom toolchain,表示使用用户自己的交叉编译器。
Toolchain origin:设置为 Pre-installed toolchain,表示使用预装的交叉编译器。
Toolchain path:设置自己安装的交叉编译器绝对路径!buildroot 要用到。
Toolchain prefix:设置交叉编译器前缀,要根据自己实际所使用的交叉编译器来设置,比如我们使用的是 arm-linux-gnueabihf-gcc,因此前缀就是$(ARCH)-linux-gnueabihf,其中 ARCH我们前面已经设置为了 arm。

3、 配置 System configuration

此选项用于设置一些系统配置,比如开发板名字、欢迎语、用户名、密码等。需要配置的项目和其对应的内容如下:

System configuration
-> System hostname               = alpha_imx6ull                      //平台名字,自行设置
-> System banner                    = Welcome to alpha i.mx6ull  //欢迎语
-> Init system                          = BusyBox                              //使用 busybox
-> /dev management               = Dynamic using devtmpfs + mdev       //使用 mdev
-> [*] Enable root login with password (NEW)                     //使能登录密码
    -> Root password           = 123456                                 //登录密码为 123456

在这里插入图片描述

在 System configuration 选项中可以配置平台名字,登录密码等信息。

4、配置 Filesystem images

此选项配置我们最终制作的根文件系统为什么格式的,配置如下:

-> [*] ext2/3/4 root filesystem                //如果是 EMMC 或SD 卡的话就用 ext3/ext4
-> ext2/3/4 variant          = ext4      //选择 ext4 格式
-> Filesystem images
-> [*] ubi image containing an ubifs root filesystem    //如果使用NAND 的话就用ubifs

在这里插入图片描述

对于 I.MX6U 来说此选项不用配置,因为我们是通过 Mfgtool 工具将根文件系统烧写到开发板上的 EMMC/SD 卡中,烧写的时候需要自己对根文件系统进行打包。

5、 禁止编译 Linux 内核和 uboot

buildroot 不仅仅能构建根文件系统,也可以编译 linux 内核和 uboot。当配置 buildroot,使能 linux 内核和 uboot 以后 buildroot 就会自动下载最新的 linux 内核和 uboot 源码并编译。但是我们一般都不会使用 buildroot 下载的 linux 内核和 uboot,因为 buildroot 下载的 linux 和 uboot官方源码,里面会缺少很多驱动文件,而且最新的 linux 内核和 uboot 会对编译器版本号有要求,可能导致编译失败。因此我们需要配置 buildroot,关闭 linux 内核和 uboot 的编译,只使用buildroot 来构建根文件系统, 首先是禁止 Linux 内核的编译, 配置如下:

-> Kernel
    -> [ ] Linux Kernel //不要选择编译 Linux Kernel 选项!

在这里插入图片描述

接着禁止编译 Uboot, 配置如下:

-> Bootloaders
    -> [ ] U-Boot //不要选择编译 U-Boot 选项!

在这里插入图片描述

6、配置 Target packages

此选项用于配置要选择的第三方库或软件、比如 alsa-utils、 ffmpeg、 iperf 等工具,但是现在我们先不选择第三方库,防止编译不下去!先编译一下最基本的根文件系统,如果没有问题的话再重新配置选择第三方库和软件。否则一口吃太多会容易撑着的,编译出问题的时候都不知道怎么找问题。

3 编译 buildroot

配置完成以后就可以编译 buildroot 了,编译完成以后 buildroot 就会生成编译出来的根文件系统压缩包,我们可以直接使用。输入如下命令开始编译:

sudo make //注意,一定要加 sudo,而且不能通过-jx 来指定多核编译!!!

sudo make //注意,一定要加 sudo,而且不能通过-jx 来指定多核编译!!!
sudo make //注意,一定要加 sudo,而且不能通过-jx 来指定多核编译!!!

buildroot 因为要从网上下载源码,因此可能存在有些源码无法下载或下载很慢的情况,比如如图

可以看出图 A1.2.2.1 中正在下载 cmake-3.8.2.tar.gz 这个压缩包,大小是 7.2MB,当前下载网 速 是 1.6KB/S , 需 要 用 时 71 分 钟 , 显 然 这 是 无 法 忍 受 的 ! 我 们 可 以 自 行 到https://cmake.org/files/v3.8/cmake-3.8.2.tar.gz 这个网站上去将 cmake-3.8.2.tar.gz 这个源码下载下来,然后拷贝到 Ubuntu 中 buildroot 源码目录下的 dl 文件夹中, dl 文件夹专用用于存放下载下来的源码。
等待编译完成,编译完成以后就会在 buildroot-2019.02.6/output/images 下生成根文件系统,如图

cd output/images/
ls

在这里插入图片描述

编译出来了多种格式的 rootfs,比如 ext2、 ext4、 ubi 等。其中rootfs.tar 就是打包好的根文件系统,我们就使用 rootfs.tar 进行测试。在 nfs 目录下新建一个名为 buildrootfs 的文件夹,然后将rootfs.tar 拷贝到 buildrootfs 目录下并解压,命令如下:

cd /home/alientek/linux/nfs            //进入到 nfs 目录下
mkdir my_buildrootfs                                   //创建 buildrootfs 目录
cd my_buildrootfs                                       //进入到 buildrootfs 目录
cp /home/alientek/IMX6/buildroot-2019.02.6/output/images/rootfs.tar ./
       //拷贝到 rootfs.tar tar
tar -vxf rootfs.tar                                     //解压缩 rootfs.tar
rm rootfs.tar                                            //删除 rootfs.tar

解压缩完成以后的 buildrootfs 目录
在这里插入图片描述

4 buildroot 根文件系统测试

buildroot 制作出来的根文件系统已经准备好了,接下来就是对其进行测试。测试方法也是通过 nfs 挂载的方式,启动 uboot,修改 bootargs 环境变量,设置 nfsroot 目录为 Ubuntu 中的buildrootfs 目录,命令如下:

setenv bootargs 'console=tty1 console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.10.100:/home/alientek/linux/nfs/my_buildrootfs,proto=tcp rw ip=192.168.10.101:192.168.10.100:192.168.10.1:255.255.255.0::eth0:off'
saveenv

设置好以后启动系统,进入根文件系统以后如图
在这里插入图片描述

首先要进入到/lib/modules 目录,但是默认没有,因此需要我们自行创建此目录。 buildroot 构建的根文件系统启动以后会输出我们前面设置的欢迎语“Welcome to alphai.mx6ull”。然后需要输入用户名和密码,用户名是“root”,密码就是我们前面配置 buildroot 的时候设置的“123456”。输入用户名和密码以后就可以进入系统中,如图所示:(未设置)
在这里插入图片描述

可以看出的 buildroot 构建的根文件系统运行基本没有问题,但是这个根文件系统是最简单的,我们并没有在 buildroot 里面配置任何第三方的库和软件,接下来我们就配置 buildroot,使能一些常见的第三方软件。

root用户登录

您可以通过以下步骤设置Buildroot的根文件系统以自动登录root用户1:
打开/etc/passwd文件,找到root用户的行,删除第二个字段中的x字符。
打开/etc/shadow文件,找到root用户的行,删除第二个字段中的所有字符。
打开/etc/inittab文件,找到console::respawn:/sbin/getty -L console 0 vt100 # GENERIC_SERIAL行,将其注释掉,并在文件末尾添加console::respawn:-/bin/sh行。
保存并退出文件。
这样,Buildroot将自动登录root用户。请注意,这样做会降低系统的安全性。如果您需要更高的安全性,请考虑使用其他方法。

5.buildroot 第三方软件和库的配置

我们不需要自行移植这些第三方软件和库了,可以直接在 buildroot 里面配置使能。比如我们现在配置使能 alsa-lib、 alsa-utils 这两个软件和库。
1、使能 alsa-lib
输入 make menuconfig,打开 buildroot 配置界面,配置路径如下:

Target packages
    -> Libraries
        -> Audio/Sound
            -> -*- alsa-lib    --->    此配置项下的文件全部选中

2、使能 alsa-utils
接下来使能 alsa-utils,路径如下:

Target packages
    -> Audio and video applications
        -> alsa-utils         //      此目录下的软件全部选中

等待编译完成就可以使用新的根文件系统进行测试了,将 buildroot/images/rootfs.tar 拷贝到nfs 目录下的 buildroot 目录中,然后重新解压。注意,以前自己添加的文件并不会被删除掉的,解压命令如下:

cp /home/alientek/IMX6/buildroot-2019.02.6/output/images/rootfs.tar ./
       //拷贝到 rootfs.tar tar
tar -vxf rootfs.tar                                     //解压缩 rootfs.tar
rm rootfs.tar                                            //删除 rootfs.tar
tar -vxf rootfs.tar

6.buildroot 下的 busybox 配置

1.busybox 配置

buildroot 在构建根文件系统的时候也是要用到 busybox 的,既然用到了 busybox 那么就涉及到 busybox 的配置。 buildroot 会自动下载 busybox 压缩包, buildroot 下载的源码压缩包都存放在/dl 目录下,在 dl 目录下就有一个叫做“busybox”的文件夹,此目录下保存着 busybox 压缩包,如图所示:
在这里插入图片描述

可以看出, buildroot 下载的 busybox 版本为 1.29.3。要想编译 busybox,必须对压缩包进行解压缩, buildroot 将所有解压缩后的软件保存在/output/build 软件中,我们可以在找到/output/build/busybox-1.29.3 这个文件夹,此文件夹就是解压后的 busybox 源码,文件内容如图所示:
在这里插入图片描述

如果大家想要修改 busybox 源码的话就直接在图中找到相应的文件,然后修改即可。我们现在是要配置 buildroot 下的 busybox,因此肯定要打开 busybox 的配置界面,在 buildroot下打开 busybox 的配置界面输入如下命令:

sudo make busybox-menuconfig

在这里插入图片描述
在这里插入图片描述

输入以后就会打开 buildroot 下的 busybox 配置界面

2 busybox 中文字符的支持

如果默认直接编译 busybox 的话,在使用 SecureCRT 的时候中文字符是显示不正常的,中文字符会显示为“?”,比如你的中文目录,中文文件都显示为“?”。不知道从哪个版本开始 busybox中的 shell 命令对中文输入即显示做了限制,即使内核支持中文但在 shell 下也依然无法正确显示。
所以我们需要修改 busybox 源码,取消 busybox 对中文显示的限制,打开文件 busybox-1.29.0/libbb/printable_string.c,找到函数 printable_string,函数内容如下:

vi libbb/printable_string.c 
const char* FAST_FUNC printable_string(uni_stat_t *stats, const char *str)
{
    char *dst;
    const char *s; 

    s = str;
    while (1) {
        unsigned char c = *s; 
        if (c == '\0') {
            /* 99+% of inputs do not need conversion */
            if (stats) {
                stats->byte_count = (s - str);
                stats->unicode_count = (s - str);
                stats->unicode_width = (s - str);
            }
            return str;
        }
        if (c < ' ')
            break;
        if (c >= 0x7f)
            break;
        s++;
    }   

#if ENABLE_UNICODE_SUPPORT
    dst = unicode_conv_to_printable(stats, str);
#else
    {   
        char *d = dst = xstrdup(str);
        while (1) {
            unsigned char c = *d; 
            if (c == '\0')
                break;
            if (c < ' ' || c >= 0x7f)
                *d = '?';
            d++;
        }
        if (stats) {
            stats->byte_count = (d - dst);
            stats->unicode_count = (d - dst);
            stats->unicode_width = (d - dst);
        }
    }   
#endif
    return auto_string(dst);
}

20-21行,当字符大于 0X7F 以后就跳出去了。
25-26行,如果支持 UNICODE 码的话,当字符大于 0X7F 就直接输出‘?’。
我们需要对这 4 行代码进行修改,修改以后如下所示:

const char* FAST_FUNC printable_string(uni_stat_t *stats, const char *str)
{
    char *dst;
    const char *s; 

    s = str;
    while (1) {
        unsigned char c = *s; 
        if (c == '\0') {
            /* 99+% of inputs do not need conversion */
            if (stats) {
                stats->byte_count = (s - str);
                stats->unicode_count = (s - str);
                stats->unicode_width = (s - str);
            }
            return str;
        }
        if (c < ' ')
            break;
        /*
        if (c >= 0x7f)
            break;
        */
        s++;
    }   

#if ENABLE_UNICODE_SUPPORT
    dst = unicode_conv_to_printable(stats, str);
#else
    {   
        char *d = dst = xstrdup(str);
        while (1) {
            unsigned char c = *d; 
            if (c == '\0')
                break;
        //  if (c < ' ' || c >= 0x7f)
            if(c < ' ')
                *d = '?';
            d++;
        }
        if (stats) {
            stats->byte_count = (d - dst);
            stats->unicode_count = (d - dst);
            stats->unicode_width = (d - dst);
        }
    }   
#endif
    return auto_string(dst);
}

修改部分,主要就是禁止字符大于 0X7F 以后 break 和输出‘?’。
接着打开文件libbb/unicode.c,找到如下内容:

vi libbb/unicode.c
1003 static char* FAST_FUNC unicode_conv_to_printable2(uni_stat_t *stats, const char *src, unsigned width, int flags)
1004 {
1005     char *dst;
1006     unsigned dst_len;
1007     unsigned uni_count;
1008     unsigned uni_width;
1009 
1010     if (unicode_status != UNICODE_ON) {
1011         char *d;
1012         if (flags & UNI_FLAG_PAD) {
1013             d = dst = xmalloc(width + 1);
1014             while ((int)--width >= 0) {
1015                 unsigned char c = *src;
1016                 if (c == '\0') {
1017                     do
1018                         *d++ = ' ';
1019                     while ((int)--width >= 0);
1020                     break;
1021                 }
1022                 *d++ = (c >= ' ' && c < 0x7f) ? c : '?';
1023                 src++;
1024             }
1025             *d = '\0';
1026         } else {
1027             d = dst = xstrndup(src, width);
1028             while (*d) {
1029                 unsigned char c = *d;
1030                 if (c < ' ' || c >= 0x7f)
1031                     *d = '?';
1032                 d++;
1033             }
1034         }
1035         if (stats) {
1036             stats->byte_count = (d - dst);
1037             stats->unicode_count = (d - dst);
1038             stats->unicode_width = (d - dst);
1039         }
1040         return dst;
1041     }
1042 
1043     dst = NULL;
1044     uni_count = uni_width = 0;
1045     dst_len = 0;
1046     while (1) {
1047         int w;
1048         wchar_t wc;
1049 
1050 #if ENABLE_UNICODE_USING_LOCALE
1051         {
1052             mbstate_t mbst = { 0 };
1053             ssize_t rc = mbsrtowcs(&wc, &src, 1, &mbst);
1054             /* If invalid sequence is seen: -1 is returned,
1055              * src points to the invalid sequence, errno = EILSEQ.
1056              * Else number of wchars (excluding terminating L'\0')
1057              * written to dest is returned.
1058              * If len (here: 1) non-L'\0' wchars stored at dest,
1059              * src points to the next char to be converted.
1060              * If string is completely converted: src = NULL.
1061              */
1062             if (rc == 0) /* end-of-string */
1063                 break;
1064             if (rc < 0) { /* error */
1065                 src++;
1066                 goto subst;
1067             }
1068             if (!iswprint(wc))
1069                 goto subst;
1070         }
1071 #else
1072         src = mbstowc_internal(&wc, src);
1073         /* src is advanced to next mb char
1074          * wc == ERROR_WCHAR: invalid sequence is seen
1075          * else: wc is set
1076          */
1077         if (wc == ERROR_WCHAR) /* error */
1078             goto subst;
1079         if (wc == 0) /* end-of-string */
1080             break;
1081 #endif
1082         if (CONFIG_LAST_SUPPORTED_WCHAR && wc > CONFIG_LAST_SUPPORTED_WCHAR)
1083             goto subst;
1084         w = wcwidth(wc);
1085         if ((ENABLE_UNICODE_COMBINING_WCHARS && w < 0) /* non-printable wchar */
1086          || (!ENABLE_UNICODE_COMBINING_WCHARS && w <= 0)
1087          || (!ENABLE_UNICODE_WIDE_WCHARS && w > 1)
1088         ) {
1089  subst:
1090             wc = CONFIG_SUBST_WCHAR;
1091             w = 1;
1092         }
1093         width -= w;
1094         /* Note: if width == 0, we still may add more chars,
1095          * they may be zero-width or combining ones */
1096         if ((int)width < 0) {
1097             /* can't add this wc, string would become longer than width */
1098             width += w;
1099             break;
1100         }
1101 
1102         uni_count++;
1103         uni_width += w;
1104         dst = xrealloc(dst, dst_len + MB_CUR_MAX);
1105 #if ENABLE_UNICODE_USING_LOCALE
1106         {
1107             mbstate_t mbst = { 0 };
1108             dst_len += wcrtomb(&dst[dst_len], wc, &mbst);
1109         }
1110 #else
1111         dst_len += wcrtomb_internal(&dst[dst_len], wc);
1112 #endif
1113     }
1114 
1115     /* Pad to remaining width */
1116     if (flags & UNI_FLAG_PAD) {
1117         dst = xrealloc(dst, dst_len + width + 1);
1118         uni_count += width;
1119         uni_width += width;
1120         while ((int)--width >= 0) {
1121             dst[dst_len++] = ' ';
1122         }
1123     }
1124     dst[dst_len] = '\0';
1125     if (stats) {
1126         stats->byte_count = dst_len;
1127         stats->unicode_count = uni_count;
1128         stats->unicode_width = uni_width;
1129     }
1130 
1131     return dst;
1132 }

第 1022 行,当字符大于 0X7F 以后, *d++就为‘?’。
第 1030 和 1031 行,当字符大于 0X7F 以后, *d 也为‘?’。
修改代码,修改后内容如下所示:

1013             d = dst = xmalloc(width + 1);
1014             while ((int)--width >= 0) {
1015                 unsigned char c = *src;
1016                 if (c == '\0') {
1017                     do
1018                         *d++ = ' ';
1019                     while ((int)--width >= 0);
1020                     break;
1021                 }
1022             //  *d++ = (c >= ' ' && c < 0x7f) ? c : '?';
1023                 *d++ = (c >= ' ') ? c : '?';
1024                     src++;
1025             }

在这里插入图片描述

1027         } else {
1028             d = dst = xstrndup(src, width);
1029             while (*d) {
1030                 unsigned char c = *d;
1031         //      if (c < ' ' || c >= 0x7f)
1032                 if(c < ' ')
1033                     *d = '?';
1034                 d++;
1035             }
1036         }

在这里插入图片描述

修改部分,同样主要是禁止字符大于 0X7F 的时候设置为‘?’。 busybox 中文字符支持跟代码修改有关的就改好了,最后还需要配置 busybox来使能 unicode 码。

3 编译 busybox

配置好以后就可以重新编译 buildroot 下的 busybox,进入到 buildroot 源码目录下,输入如下命令查看当前 buildroot 所有配置了的目标软件包,也就是 packages:

sudo make show-targets

在这里插入图片描述

列出了当前 buildroot 中所有使能了的 packages 包,其中就包括 busybox,如果我们想单独编译并安装 busybox 的话执行下面命令即可:

sudo make busybox

在这里插入图片描述

上述命令就会重新编译 busybox。编译完成以后重新编译 buildroot,主要是对其进行打包,输入如下命令:

sudo make

在这里插入图片描述

重新编译完成以后查看一下 output/images 目录下 rootfs.tar 的创建时间是否为刚刚编译的,如果不是的话就删除掉 rootfs.tar,然后重新执行“sudo make”重新编译一下即可。最后我们使用新的 rootfs.tar 启动 Linux 系统。

cp /home/alientek/IMX6/buildroot-2019.02.6/output/images/rootfs.tar ./
       //拷贝到 rootfs.tar tar
tar -vxf rootfs.tar                                     //解压缩 rootfs.tar
rm rootfs.tar                                            //删除 rootfs.tar
tar -vxf rootfs.tar

7 根文件系统测试

buildroot 的根文件系统制作好以后就是测试工作了
我们使用构建的根文件系统启动以后会发现,输入命令的时候命令行前面一直都是“#”,如果我们进入到某个目录的话前面并不会显示当前目录路径,
在这里插入图片描述

我们当前所处的目录是/etc,但是前面的提示符一直是“#”,这样不利于我们查看自己当前所处的路径。最好能像 Ubuntu 一样,可以指出当前登录的用户名,主机名以及所处的目录

我们现在就来设置,实现图中所示的效果。我们要先了解一下“PS1”这个环境变量, PS1 用于设置命令提示符格式,格式如下:

PS1 = ‘命令列表’

命令列表中可选的参数如下:

\!  显示该命令的历史记录编号。
\#  显示当前命令的命令编号。
\$  显示$符作为提示符,如果用户是 root 的话,则显示#号。
\\  显示反斜杠。
\d  显示当前日期。
\h  显示主机名。
\n  打印新行。
\nnn  显示 nnn 的八进制值。
\s  显示当前运行的 shell 的名字。
\t  显示当前时间。
\u  显示当前用户的用户名。
\W  显示当前工作目录的名字。
\w  显示当前工作目录的路径

我们打开/etc/profile 文件,找到如下所示内容,然后将其屏蔽掉:

3 if [ "$PS1" ]; then
4    if [ "`id -u`" -eq 0 ]; then
5        export PS1='# '
6    else

7        export PS1='$ '
8    fi
9 fi

上述代码就是原始的设置 PS1 环境变量的配置代码,就是它将命令提示符设置为了固定的“#”,我们将其屏蔽掉,然后输入如下所示内容:

export PATH="/bin:/sbin:/usr/bin:/usr/sbin"

#if [ "$PS1" ]; then
#       if [ "`id -u`" -eq 0 ]; then
#i              export PS1='# '
#       else
#               export PS1='$ '
#       fi
#fi
PS1='[\u@\h]:\w$:'
export PS1
export PAGER='/bin/more'
export EDITOR='/bin/vi'


# Source configuration files from /etc/profile.d
for i in /etc/profile.d/*.sh ; do
        if [ -r "$i" ]; then
                . $i
        fi
done
unset i

在这里插入图片描述

PS1='[\u@\h]:\w$:'
export PS1

第 2 行就是设置 PS1 环境变量,格式就是:

[user@hostname]:currentpath$:

设置好以后的/etc/profile 文件内容如图所示:
/etc/profile 文件修改完成以后重启开发板,这个时候我们就如到某个目录的时候命令行就会有提示
在这里插入图片描述

命令提示符显示正常了,完整的显示除了用户名、主机名和当前路径。至此, buildroot 构建根文件系统就已经全部完成了,当然了,很多第三方软件本章并没有使能,大家可以自行根据实际需求选择对应的第三方软件和库。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/418371.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第一章 计算机网络概述

计算机网络基本概念 计算机网络是计算机技术与通信技术相互融合的产物计算机网络是互连的、自治的计算机的集合 自治——互连的计算机系统彼此独立&#xff0c;不存在主从或者控制与被控制关系互连——利用通信链路连接相互独立的计算机系统 目前最大的、应用最广泛的计算机网…

函数栈帧的创建和销毁(带你进一步深入理解函数的执行流程)

本文主题 什么是函数栈帧&#xff1f; 理解函数栈帧能解决什么问题&#xff1f; 函数栈帧的创建和销毁解析 1. 什么是函数栈帧 &#xff1f; 我们在写C语言代码的时候&#xff0c;经常会把一个独立的功能抽象为函数&#xff0c;所以C程序是以函数为基本单位的。 那函数是如何…

人人都是数据分析师-数据分析之数据图表可视化(上)

BI报表、运营同学的汇报报告中数据图表大多为 表格、折线图、柱状图和饼图&#xff0c;但是实际上还有很多具有代表性的可视化图表&#xff0c;因此将对常见的可视化图表进行介绍&#xff0c;希望这些图表可视化方法能够更好的提供数据的可用性。 导语 数据是我们在数据分析工…

通过1个IP地址同时采集2台西门子S7200 Smart的数据

一、应用场景 制药厂的颗粒包装机&#xff0c;控制系统由2台西门子S7200 Smart的PLC和1台昆仑通泰MCGS的触摸屏组成。现在MES管理系统&#xff0c;需要采集设备的数据&#xff0c;只提供一个IP地址&#xff0c;且IP地址和原系统不在同一个网络段内。 二、原系统架构 2台西门子S…

浅析DNS Rebinding

0x01 攻击简介 DNS Rebinding也叫做DNS重绑定攻击或者DNS重定向攻击。在这种攻击中&#xff0c;恶意网页会导致访问者运行客户端脚本&#xff0c;攻击网络上其他地方的计算机。 在介绍DNS Rebinding攻击机制之前我们先了解一下Web同源策略&#xff0c; Web同源策略 同源策略…

智慧校园人员定位系统解决方案

人员定位是安全管理中最重要的一个环节&#xff0c;尤其是石化、矿业、电力、建筑等高危行业&#xff0c;人员安全管理更是重中之重&#xff0c;除了工业领域&#xff0c;其它领域也需要人员安全管理&#xff0c;比如&#xff1a;学校、医院、养老院、物业、环卫等。下面我们以…

SpringSecurity之基本原理——过滤器加载过程

前言 前一篇讲解了SpringSecurity的过滤器链的基本只是&#xff0c;今天我们就要进入过滤器&#xff0c;看看其加载过程是如何的&#xff1f; 相信认真度过第一篇文章的小伙伴还记得&#xff0c;我说在SpringBoot出现后&#xff0c;帮助我们省去了那些繁琐的配置&#xff0c;…

2023年MathorCup数模A题赛题

A 题 量子计算机在信用评分卡组合优化中的应用 在银行信用卡或相关的贷款等业务中&#xff0c;对客户授信之前&#xff0c;需要先通过 各种审核规则对客户的信用等级进行评定&#xff0c;通过评定后的客户才能获得信 用或贷款资格。规则审核过程实际是经过一重或者多重组合规则…

树的直径问题

一&#xff0c;定义 树的直径就树中所有最短路经距离的最大值 求取树的直径可以使用两遍dfs或者树形dp获得 二&#xff0c;两遍dfs获得树的直径&#xff08;注意&#xff0c;该方法边权必须都为正边权&#xff09; 思路&#xff1a; 我们首先任取一点走dfs&#xff0c;然后…

索引:索引知识重复习,什么是索引、索引的类型、建立索引及【最左匹配原则】、Explain查看sql的执行计划

文章目录什么是索引索引的类型主键索引&#xff08;primary key&#xff09;普通索引&#xff08;index&#xff09;复合索引全文索引&#xff08;fulltext&#xff09;空间索引唯一索引索引修改及删除Explain一、using filesort(减慢查询效率)二、Using temporary三、using in…

TensorFlow 1.x学习(系列二 :3):变量与tensorboard可视化

文章目录1.变量2.可视化学习 Tensorboard3.可视化过程中遇到的问题&#xff1a;import tensorflow as tf1.变量 变量op: 变量也是一种OP&#xff0c;是一种特殊的张量&#xff0c;能够进行存储持久化&#xff0c;它的值就是张量&#xff0c;默认被训练和常量不同&#xff08;…

15个 AI-powered应用,加速学术写作和阅读

文章目录写作方面1.Jenni AI&#xff08;推荐&#xff09;2.Paperpal阅读方面3.Schoarlcy4.chatpdf5.Casper6.SciSpace&#xff08;推荐&#xff09;文献管理/写论文笔记用7.lateral8. ClioVis9.Glasp10. Audiopen学术目的的搜索引擎11. Consensus&#xff08;推荐&#xff09;…

【私有云盘】搭建PHP轻量文件管理器 - TinyFileManager「公网远程访问」

文章目录前言1. Tiny File Manager网站搭建1.1.Tiny file manager下载和安装1.2.Tiny file manager网页测试2. Cpolar内网穿透的安装和注册2.1 本地网页发布2.2 Cpolar云端设置2.3 Cpolar本地设置3. 公网访问测试4. 结语前言 文件共享和查阅是现在网络最常见的应用场景&#x…

windows环境nodejs卸载与安装

windows环境nodejs卸载与安装一、卸载1.1 控制面板卸载程序1.2 手动清理相关文件夹二、安装2.1 下载安装包2.2 安装操作2.3 验证安装是否成功2.4 环境变量设置2.4.1 node程序添加到系统环境变量PATH2.4.2 修改全局模块下载路径2.4.2.1 node_global路径变量2.4.2.2 node_modules…

Docker应用部署

文章目录Docker 应用部署一、部署MySQL二、部署Tomcat三、部署Nginx四、部署RedisDocker 应用部署 一、部署MySQL 搜索mysql镜像 docker search mysql拉取mysql镜像 docker pull mysql:5.6创建容器&#xff0c;设置端口映射、目录映射 # 在/root目录下创建mysql目录用于存…

【Go语言从入门到精通系列-基础篇】Go语言包的管理以及基础语法与使用。

系列文章目录 【Go语言从入门到精通系列-基础篇】Go安装 语言特性&#xff0c;以及开启你人生中的第一个go程序 【Go语言从入门到精通系列-基础篇】Go语言包的管理以及基础语法与使用。 Go语言从入门到精通系列-基础篇系列文章目录前言第二章 Go语言包的管理以及基础语法与使…

zabbix介绍 | 监控搭建和部署

zabbix介绍 | 监控搭建和部署一.Zabbix简介二.Zabbix监控原理三.Zabbix监控的最常见五个程序组件四&#xff0c;搭建zbx监控4.1准备二台虚拟机4.2 服务端客户端获取 zabbix 的下载源4.3 服务端安装修改 192.168.10.104.4 服务端安装 zabbix 所需的数据库&#xff08;192.168.10…

点监督的实例分割

目录Pointly-Supervised Instance Segmentation摘要方法Annotation format and collection训练点标记模型实验结果Pointly-Supervised Instance Segmentation 摘要 点注释来进行实例分割的弱监督标签除了边界框还有一组随机点对PointRend实例分割模块的修改对于每个对象&…

2020年 团体程序设计天梯赛——题解集

Hello各位童学大家好&#xff01;&#x1f60a;&#x1f60a;&#xff0c;茫茫题海你我相遇即是缘分呐&#xff0c;或许日复一日的刷题已经让你感到疲惫甚至厌倦了&#xff0c;但是我们真的真的已经达到了我们自身极限了吗&#xff1f;少一点自我感动&#xff0c;没有结果前别太…

Python爬虫基础之如何对爬取到的数据进行解析

目录1. 前言2. Xpath2.1 插件/库安装2.2 基础使用2.3 Xpath表达式2.4 案例演示2.4.1 某度网站案例3. JsonPath3.1 库安装3.2 基础使用3.2 JsonPath表达式3.3 案例演示4. BeautifulSoup4.1 库安装4.2 基础使用4.3 常见方法4.4 案例演示参考文献原文地址&#xff1a;https://www.…