0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何进行嵌入式Linux系统开发?

嵌入式IoT 来源:嵌入式IoT 作者:嵌入式IoT 2021-03-22 11:30 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

树莓派4 嵌入式Linux开发过程详解

1.概述

2.开发环境概述

2.1 安装虚拟机环境

2.2 树莓派开发环境搭建

3.交叉编译工具的安装与uboot的编译

3.1 安装arm 64位交叉编译环境

3.2 编译树莓派上的uboot

3.3 将u-boot放到树莓派上运行

4.树莓派4b上的Linux编译和下载

4.1 编译树莓派Linux源代码

4.2 将编译好的Linux固件运行

5.根文件使用

5.1 uboot中设置启动项

5.2 插入SD卡挂在到虚拟机上

5.3 修改文件脚本

6.小结

1.概述

在这篇文章中,将会通过树莓派4的Linux的启动过程,描述如何进行嵌入式Linux系统开发的思路。通过树莓派4B的启动流程,看到一个Linux启动过程,同时,通过一步一步搭建一个完整的树莓派嵌入式Linux开发环境,来指导分析各部分的开发过程。

通过对本文的阅读,可以掌握一些嵌入式Linux开发和环境搭建的方法,也能够对树莓派4的运行流程以及Linux的运行流程有一个大致的了解,从romboot--》uboot--》kernel--》rootfs整个运行流程有了比较清楚的了解后,再去学习linux以及嵌入式底层,将会更加的清晰。

2.开发环境概述

嵌入式软件是独特的,它需要利用PC机编译嵌入式平台可以运行的机器码,这样就需要借助交叉编译工具链进行。在进行Linux的开发工作时,都会利用宿主机进行交叉编译后,将生成的目标代码下载到机器上运行。

一般来说,开发板和PC的连接渠道是串口和网线,UART可以看到基本的调试信息,而网线则可以用来将板子和电脑进行文件传输。

串口连接如下:

网线的连接一般可以将树莓派和PC都在同一个网段下。

当在同一个网段内进行开发时,比较的方便。做嵌入式Linux开发,使用Linux比较方便。由于大部分学习和工作都是在windows下,所以这里可以在Ubuntu下装一个虚拟机进行开发工作。

2.1 安装虚拟机环境

在windows上的虚拟机环境可以安装VMware Workstation 16 Player或者Oracle VM VirtualBox。

2.1.1 镜像下载

比如VMware Workstation 16 Player这个软件,然后从ubuntu的官方下载特定版本。

可以从国内镜像下载,这样比较快。

选择特定的版本进行安装

853e5bb4-891f-11eb-8b86-12bb97331649.png

下一步开始安装ubuntu20.04

然后设置用户名和密码

选择虚拟机硬盘空间的大小,为了方便使用,这里设置40G空间。

接着点击完成开始安装。

等一段时间后,会进入自动安装的界面,全程无需干预。

完成安装后,会自动启动。

2.1.2 必要软件包的安装

下面列出了需要安装的软件包

gitsudo apt install git用于代码管理,代码下载

net-toolssudo apt install net-tools提供ifconfig等功能

vimsudo apt install vim文本编辑工具

tftpsudo apt install tftpd-hpa可以通过tftp与树莓派之间传输文件

nfssudo apt install nfs-kernel-server可以提供网络共享文件

软件名称安装命令说明

git

首先安装git

sudo apt install git

为了管理工程,首先需要创建一个Github的账号,然后配置git的用户名和密码。

git config --global user.name “YOUR_FIRST_NAME YOUR_LAST_NAME” git config --global user.email “YOUR_GIT_ASSOCIATED_EMAIL”

net-tools

输入下面的命令可以进行安装工作

sudo apt install net-tools

要确保网络环境在一个网段,那么就需要设置网卡为桥接模式。

需要注意的是在选择网络适配器时,选择自己的网卡。

在Ubuntu上输入ifconfig,并且在window上输入ipconfig。只要前面的网段一样,最后不一样即可。这样就可以进行下一步的工作了。

tftp

TFTP (Trivial File Transfer Protocol) 是一个简化版的FTP,适合用于简洁的场景,比如嵌入式开发的时候向下位机传输文件。

安装tftp的目的是方便开发,在树莓派上,存储介质是SD卡,如果每次编译完成后,都需要插拔SD卡,然后将Linux的固件进行安装,这样非常的麻烦,这里可以采用uboot通过tftp加载Linux的固件的方式进行加载。

安装过程如下:

首先安装复位程序

sudo apt install tftpd-hpa sudo apt install tftp-hpa

检查服务器的运行状态

sudo systemctl status tftpd-hpa

打开配置文件

sudo vim /etc/default/tftpd-hpa

编辑的内容如下:

TFTP_USERNAME=“tftp” #tftpd程序使用的账户 TFTP_DIRECTORY=“/srv/tftp” #目录 TFTP_ADDRESS=“:69” #端口 TFTP_OPTIONS=“--secure --create” #--secure 不设置会有跨目录的问题 --create是要自己添加的,给客户端写入数据的权力

设置访问目录的权限

sudo chown tftp:tftp /srv/tftp

重启tftp服务器

sudo systemctl restart tftpd-hpa

本地测试tftp服务器

1.首先在/srv/tftp目录中新建一个abc.txt文件。

sudo vim /srv/tftp/abc.txt

2.输入tftp 127.0.0.1

出现上述的现象,表示测试成功。

远程测试

需要保证tftp服务器没有问题,可以在windows上下载一个Tftp64的软件。打开后选择tftp client选择传输的文件即可。

选择put按钮,弹出下面的命令表示成功。如果不成功,需要注意电脑防火墙的设置问题。

检查tftp服务器中的文件,可以正常的见到文件,表示tftp环境搭建成功。

nfs

安装nfs目的是一旦开发Linux上的应用程序时,不希望频繁的传输文件,每次在宿主机上编译好应用程序后,直接拷贝到本地目录,嵌入式平台上的Linux可以通过nfs文件系统访问到宿主机上刚编译好的程序,这样更加的方便Linux的应用程序的开发工作。

sudo apt install nfs-kernel-server

然后创建一个nfs的共享目录,用于存放共享文件。

sudo mkdir /opt/nfs

修改配置文件

sudo vim /etc/exports /opt/nfs 10.1.1.* (rw,async,root_squash)

编辑/etc/exports中的文件如下:

其中10.1.1.*为自己网段的地址信息。

最后重启nfs即可

sudo systemctl restart nfs-kernel-server

测试nfs的安装情况

安装完成后,可以进行nfs客户端的安装

sudo apt install nfs-common

然后创建一个本地的文件夹目录

sudo mkdir -p /opt/nfs-client

最后挂载即可

sudo mount -t nfs 10.1.1.160:/opt/nfs /opt/nfs-client

当在/opt/nfs下创建一个文件,/opt/nfs-client目录同样可以看到,表示成功。

2.2 树莓派开发环境搭建

2.2.1 硬件连接

树莓派4上的实际硬件引脚分布如上图所示,其中需要连接串口RX、TX、GND。

准备一个8g以上的SD卡,然后打开Raspberry Pi Imager,选择树莓派镜像烧录进去。

进行这一步的目的,是因为树莓派启动流程需要从SD卡中加载第一阶段的启动文件。

默认情况下,烧录的固件,连接上串口后是没有输出的,需要自己修改sd卡中的config.txt文件。在末尾加上下面的一句话即可。

enable_uart=1

这样通过mobaxterm工具打开串口,并且连接上电源后,可以看到如下的输出

接着输入用户名,密码如下

raspberrypi login:pi Password:raspberry

这样就可以使用默认的树莓派4串口调试功能了。

2.2.2 树莓派4b启动流程分析

简述一下树莓派4b的启动流程是,上电后,树莓派会自动加载位于SD卡文件中的bootcode.bin文件,该文件是加载到树莓派的GPU中运行,该程序初始化PLL,DDR等,接着读取SD卡文件中的start4.elf文件去执行,该文件执行过程中,会读取config.txt文件,根据配置脚本选择可以执行的固件。

往往做嵌入式开发,其底层的启动逻辑是要非常清晰的,这样才能在任何情况下梳理清楚问题所在,从而确保硬件和软件层面上的一致性。

上图基本上展示了一个通用的嵌入式Linux的启动流程,每一个阶段的特点和功能点都有着很好的描述。

而树莓派4b上的Broadcom BCM2711的启动遵循以下的流程。

第一阶段的bootloader:

第一阶段的BootROM一般是固化在芯片的内部,在GPU中执行,此时ARM核处于复位状态。

树莓派4b的BootROM通过EEPROM加载进来,4b之前都是SD卡上的bootcode.bin文件。

第二阶段的bootloader:

这一阶段的boot固件的加载方式都是从SD卡、网络、USB等等。

在树莓派4上,使用的是SD卡中的start.elf二进制文件。

start.elf文件去SD的文件系统中找到config.txt文件,然后根据里面的信息处理boot流程。

这篇文章中,主要修改config.txt配置文件,进行uboot的启动流程。

3.交叉编译工具的安装与uboot的编译

3.1 安装arm 64位交叉编译环境

因为需要编译64位的程序,所以这里需要安装arm的64位交叉编译环境。

https://www.linaro.org/downloads/

从上面的网站中进去

建议下载gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz。

下载完成后,放到指定的目录。

#创建一个文件夹 sudo mkdir -p /opt/linaro #解压到指定的文件夹路径 sudo tar -xvf gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar -C /opt/linaro

更新环境变量

sudo vim ~/.bashrc

在末尾添加如下的

alias crosscompiler=‘export KERNEL=kernel8;export ARCH=arm64;export CROSS_COMPILE=/opt/linaro/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-’

更新环境

source ~/.bashrc

3.2 编译树莓派上的uboot

首先需要下载代码

git clone https://github.com/u-boot/u-boot.git

正常的下载完成图如下:

8a6f08cc-891f-11eb-8b86-12bb97331649.png

接着切换分支,然后开始编译。

cd u-boot git checkout v2020.04-rc3

在编译之前,首先需要安装编译必备的程序

sudo apt install u-boot-tools bison bc make flex libssl-dev ncurses-*

安装完成后,执行

crosscompiler

该命令为环境变量中定义的命令,可以设置环境变量。

make rpi_4_defconfig

直接采用默认的配置编译即可。

make -j $(nproc)

编译完成后的uboot.bin文件就是可以直接在树莓派4b上执行的程序。

8a9ab56c-891f-11eb-8b86-12bb97331649.png

3.3 将u-boot放到树莓派上运行

到这一步就可以将编译好的u-boot程序放到树莓派4b上运行了。

将树莓派的SD卡插到电脑上,通过将SD卡中的config.txt重新命令为config.txt.bak。并且新建config.txt。

arm_control=0x200 kernel=u-boot.bin dtoverlay=disable-bt

这三行的意思是

arm_control=0x200 #因为树莓派4b支持的是64位的架构,这里用来表示运行64位程序

使用uboot

kernel=u-boot.bin # kernel表示运行的固件

使能串口

dtoverlay=disable-bt #树莓派4设计的时候,如果打开了串口调试,则蓝牙无法使用

将SD卡插入电脑,可以看到uboot正常的启动。

8ac53710-891f-11eb-8b86-12bb97331649.png

4.树莓派4b上的Linux编译和下载

4.1 编译树莓派Linux源代码

目前已经完成了树莓派4b的uboot功能,接下来开始编译树莓派的Linux kernel了。

树莓派单独有维护Linux的代码分支,可以通过下面的命令进行下载。

git clone --branch rpi-5.6.y https://github.com/raspberrypi/linux

进入Linux的目录

创建一个新的目录存放编译好的固件

mkdir rpi_hw

开始编译

make O=rpi_hw bcm2711_defconfig

去掉MMC/SD/SDIO驱动

make O=rpi_hw menuconfig

进入Device Driver选择去掉MMC/SD/SDIO card support。

保存配置后,就可以编译了。

make O=rpi_hw -j $(nproc)

为什么要去掉MMC/SD/SDIO驱动?

这是因为需要编译从网络启动的驱动,所以不需要在树莓派的SD卡里面进行操作。

编译完成后,可以在rpi_hw/arch/arm64/boot中找到编译好的文件。

8b0195ca-891f-11eb-8b86-12bb97331649.png

将编译完成的Linux内核文件放到

sudo cp rpi_hw/arch/arm64/boot/Image /srv/tftp/

4.2 将编译好的Linux固件运行

在将编译好的固件通过uboot加载到RAM中运行的期间,首先需要明白树莓派4b内存的分布情况。

通过uboot中的bdinfo命令,可以看到树莓派4b上有两块bank,第一块bank在0x00000000,第二块在0x40000000。

而树莓派4b,当从SD卡中加载Image文件时,加载到DRAM的0x8000的地址处开始运行。

当然,地址也可以在uboot中设置,Linux会重新将代码重定位。

此时,需要在uboot中设置启动信息了。

首先设置uboot的静态ip地址

setenv ipaddr 10.1.1.100 #设置开发板的静态地址(自定义) setenv serverip 10.1.1.160 #设置服务器的地址 setenv netmask 255.255.255.0 saveenv reset

上述操作设置了ip地址接下来设置启动

setenv kernel_addr_r 0x8000 setenv kernel Image setenv netboot ‘tftp ${kernel_addr_r} ${kernel} && booti ${kernel_addr_r} - ${fdtcontroladdr}’ setenv bootcmd ‘run netboot’ setenv bootargs ‘console=ttyAMA0’ saveenv reset

可以显示如下:

最后启动后报错

这个很正常,目前没有rootfs。但是现在Linux的内核可以正常的加载和调试了。

下面来挂在rootfs。

5.根文件使用

关于通用根文件系统的制作过程,这篇文章就不提了,现在主要描述如何使用。

5.1 uboot中设置启动项

首先在uboot中设置路径。

setenv nfsroot /opt/nfs/

设置启动参数

setenv bootargs “console=ttyAMA0,115200 root=/dev/nfs rw nfsroot=${serverip}:${nfsroot},v3,tcp ip=$ipaddr:$serverip::$netmask:off”

保存配置

saveenv

5.2 插入SD卡挂在到虚拟机上

首先将U盘挂载到虚拟机上

可以看到出现两个磁盘

其中:

rootfs为Linux根文件系统

boot为可以在windows上访问的ext32文件

可以将rootfs里的文件全部拷贝到/opt/nfs/

sudo cp * /opt/nfs/ -R

在/opt/nfs目录下,新建一个file的文件夹,把boot里面的文件全部拷贝进去即可

sudo mkdir -p /opt/nfs/file sudo cp * /opt/nfs/file/

5.3 修改文件脚本

需要修改

sudo vim etc/fstab

新增如下文件

10.1.1.160:/opt/nfs/file /boot nfs defaults,vers=4.1,proto=tcp 0 0

8c03e464-891f-11eb-8b86-12bb97331649.png

其目的是将默认的两个项列表屏蔽掉,只需要挂载nfs里面的文件系统即可。

改完后,插上SD卡,就可以正常从tftp中获取Linux的内核固件,并且能够从nfs文件系统中挂载根文件系统了。

8c24e6be-891f-11eb-8b86-12bb97331649.png

如果发现需要密码,或者密码忘记了,可以进入

cd /opt/nfs/ sudo vim /etc/passwd

将中间的x删掉。

8c82e5b6-891f-11eb-8b86-12bb97331649.png

在Linux中,默认x表示需要密码进入。

6.小结

本文从树莓派整个Linux系统的环境搭建和树莓派的启动进行一定的分析。对树莓派的boot、u-boot加载Linux的kernel,以及挂载nfs文件系统做了一些实验。

最后的自己制作根文件系统的部分,采用了树莓派默认的根文件系统,如果需要自己裁剪制作,可以进行定制操作。

整个嵌入式Linux开发和环境搭建过程都可以在树莓派4b上很好的进行测试,万变不离其宗,掌握了嵌入式开发的流程和工具,做应用和做驱动开发都十分的方便和高效。

由于时间关系,当前还有一些实验没有完成,比如Linux上的应用开发,还有驱动开发等等,还有jlink调试等等。

树莓派4b上学习Linux的使用和启动非常的方便,价格也非常的合理,是一块不错的开发平台。

原文标题:树莓派4 嵌入式Linux开发过程详解

文章出处:【微信公众号:嵌入式IoT】欢迎添加关注!文章转载请注明出处。

责任编辑:haq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Linux
    +关注

    关注

    88

    文章

    11631

    浏览量

    218027
  • 树莓派
    +关注

    关注

    122

    文章

    2070

    浏览量

    109776

原文标题:树莓派4 嵌入式Linux开发过程详解

文章出处:【微信号:Embeded_IoT,微信公众号:嵌入式IoT】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    使用xmake+zig更优雅的进行嵌入式系统开发

    引言在嵌入式系统开发领域,构建工具的稳定性与可维护性对项目长期发展至关重要。嵌入式项目通常需要针对不同硬件平台进行交叉编译,每个平台都需要依赖特定的构建工具链,环境搭建复杂。随着LLV
    的头像 发表于 11-30 10:04 3607次阅读
    使用xmake+zig更优雅的<b class='flag-5'>进行</b><b class='flag-5'>嵌入式</b><b class='flag-5'>系统开发</b>

    AMD 2025.1版嵌入式软件和工具的新增功能

    AMD 2025.1 版嵌入式软件和工具是面向新一代嵌入式系统开发而打造的综合平台,全面加速概念构想到部署落地。
    的头像 发表于 08-15 15:32 1047次阅读

    入行嵌入式应该怎么准备?

    知识: 一、C/C++编程C/C++是嵌入式系统开发中最常用的编程语言。熟练掌握C/C++语言将使你能够理解和编写底层驱动程序、操作系统以及与硬件交互的代码。对于嵌入式
    发表于 08-06 10:34

    【「Yocto项目实战教程:高效定制嵌入式Linux系统」阅读体验】+基础概念学习理解

    。为了对珠峰更了解些,开始接触 Linux 系统开发,并逐渐认识到 Yocto 项目在定制嵌入式 Linux 系统方面的重要性。所以很想拜读
    发表于 08-04 22:29

    明远智睿SSD2351:开启嵌入式系统开发新时代

    在当今科技飞速发展的时代,嵌入式系统已经广泛应用于各个领域,从智能家居到工业自动化,从智能交通到医疗设备,嵌入式系统无处不在。而开发板作为
    的头像 发表于 07-15 15:47 411次阅读

    明远智睿SSD2351:嵌入式系统开发的卓越之选

    嵌入式系统开发这一充满挑战与机遇的领域,一款出色的开发板就如同开发者手中的利器,能助力他们披荆斩棘,创造出令人惊叹的成果。明远智睿SSD2351便是这样一款集性能、功能与易用性于一身
    的头像 发表于 07-15 15:46 455次阅读

    Linux嵌入式和单片机嵌入式的区别?

    区别 单片机嵌入式系统Linux嵌入式系统是两种不同的嵌入式
    发表于 06-20 09:46

    泰克MSO2024B混合信号示波器在嵌入式系统开发中的应用

    MSO2024B混合信号示波器以其高性能参数、灵活的触发机制和全面的协议解码能力,成为嵌入式系统开发中的理想选择。本文将深入探讨其在嵌入式系统开发中的具体应用及优势。   一、泰克MS
    的头像 发表于 06-16 15:40 588次阅读
    泰克MSO2024B混合信号示波器在<b class='flag-5'>嵌入式</b><b class='flag-5'>系统开发</b>中的应用

    嵌入式开发入门指南:从零开始学习嵌入式

    特定功能的计算机系统,广泛应用于智能家居、工业控制、医疗设备、车载系统等领域。 2. 学习嵌入式开发的前置知识熟悉C语言编程掌握基本的数据结构与算法了解数字电路与微控制器原理熟悉Linux
    发表于 05-15 09:29

    硬核升级!华清远见STM32MP157驱动开发课程助力嵌入式Linux底层开发入门进阶

    嵌入式Linux系统开发中,驱动程序开发是一项关键技术,它作为硬件与软件之间的桥梁,实现了操作系统对硬件设备的控制。相较于
    的头像 发表于 04-03 16:40 718次阅读
    硬核升级!华清远见STM32MP157驱动<b class='flag-5'>开发</b>课程助力<b class='flag-5'>嵌入式</b><b class='flag-5'>Linux</b>底层<b class='flag-5'>开发</b>入门进阶

    STM32开发入门进阶必备!《STM32嵌入式系统开发—基于STM32CubeMX和HAL库》新书发布!

    近日,由华清远见教育科技集团精心编撰的教育部高等学校电子信息类专业教学指导委员会规划教材、普通高等教育电子信息类专业系列教材——《STM32嵌入式系统开发—基于STM32CubeMX和HAL库》重磅
    的头像 发表于 04-03 14:54 1372次阅读
    STM32<b class='flag-5'>开发</b>入门进阶必备!《STM32<b class='flag-5'>嵌入式</b><b class='flag-5'>系统开发</b>—基于STM32CubeMX和HAL库》新书发布!

    嵌入式系统开发圣经【干货】

    内容包括:嵌入式系统的介绍、嵌入式SoC硬件系统概论、嵌入式系统软件开发。适用于产品主管、
    发表于 03-12 13:58

    如何成为嵌入式开发工程师?

    和使用方法。- 掌握接口标准和总线协议,如UART、SPI、I2C、CAN等。 3. 编程能力:- 精通至少一种编程语言,尤其是C/C++,因为它们是嵌入式系统开发中最常用的。- 了解汇编语言的基础知识
    发表于 02-19 10:39

    嵌入式开发必备-RK3562演示Linux常用系统查询命令(上)触觉智能出品

    实用干货!嵌入式开发学习必备-RK3562演示Linux常用系统查询命令(上)关注触觉智能持续为大家带来更多嵌入式开发内容
    的头像 发表于 12-31 10:51 117次阅读
    <b class='flag-5'>嵌入式开发</b>必备-RK3562演示<b class='flag-5'>Linux</b>常用<b class='flag-5'>系统</b>查询命令(上)触觉智能出品

    如何使用 RISC-V 进行嵌入式开发

    RISC-V是一种开源的指令集架构(ISA),它允许任何人设计、制造和销售基于RISC-V的处理器,这为嵌入式开发提供了极大的灵活性和创新空间。以下是使用RISC-V进行嵌入式开发的基本步骤: 一
    的头像 发表于 12-11 17:32 2763次阅读