Skip to content

天楚锐齿

人工智能 云计算 大数据 物联网 IT 通信 嵌入式

天楚锐齿

  • 下载
  • 物联网
  • 云计算
  • 大数据
  • 人工智能
  • Linux&Android
  • 网络
  • 通信
  • 嵌入式
  • 杂七杂八

利用Bitbake、Poky、Yocto、OpenEmbedded编译生成车规AGL Linux

2018-11-21

作为车规级的嵌入式Linux,AGL Linux使用新的构建方式,不再使用GNU Make这一套,以前老的构建方式学习曲线比较陡峭,组件删减也不方便。

那么Bitbake、Poky、Yocto、OpenEmbedded分别是干啥的呢:

Bitbake:是一个通用任务执行引擎,允许shell和python任务在复杂的任务间依赖约束条件下高效并行运行,有点类似GNU Make。

OpenEmbedded:是一个采用MIT许可证的软件架构或标准,目标在于为嵌入式系统构建Linux发行版。

Poky:参考嵌入式操作系统实际上,是一个可行的构建示例,它使用包含的构建系统(BitBake构建引擎和OpenEmbedded-Core构建系统元数据)构建一个小型嵌入式操作系统。

Yocto:是一个开源协作项目,可帮助开发人员为嵌入式产品创建定制的基于Linux的系统,而不管硬件架构如何。 该项目提供了一套灵活的工具和一个空间,全世界的嵌入式开发人员可以共享可用于为嵌入式设备创建量身定制的Linux映像的技术,软件堆栈,配置和最佳实践。下图就是yocto开发流程:

从上面可以看出,其中最核心的就是bitbake,弄懂它其他就很容易明白了,下面以一个例子来看看bitbake使用。

Bitbake例子

Bitbake根据提供的构建任务的元数据执行任务。元数据存储在配方(.bb)和相关配方“append”(.bbappend)文件,配置(.conf)和底层包含(.inc)文件以及类(.bbclass)文件中。元数据为Bitbake提供了有关运行哪些任务以及这些任务之间的依赖说明。

Bitbake包含一个程序库用于从各种地方(如本地文件,源码管理系统或网站)获取源代码。

每个要构建的单元(例如一个软件)的指令被称为“配方”文件,并且包含关于该单元的所有信息(依赖性,源文件位置,校验和,描述等扥)。

Bitbake包含客户端/服务器抽象,可以通过命令行使用或者通过XML-RPC作为服务提供,并具有多个不同的用户界面。

CentOS7下安装和使用bitbake进行项目构建

先安装python3.x:

$ sudo yum install epel-release

$ sudo yum install https://centos7.iuscommunity.org/ius-release.rpm

$ wgethttp://mirror.centos.org/centos/7/os/x86_64/Packages/openssl-libs-1.0.2k-12.el7.x86_64.rpm

$ wgethttp://mirror.centos.org/centos/7/os/x86_64/Packages/openssl-1.0.2k-12.el7.x86_64.rpm

$ sudo yum localinstall openssl-1.0.2k-12.el7.x86_64.rpm openssl-libs-1.0.2k-12.el7.x86_64.rpm

$ sudo yum install python36u

$ sudo ln -s /bin/python3.6 /bin/python3

$ sudo yum install python36u-pip

$ sudo ln -s /bin/pip3.6 /bin/pip3

安装bitbake:

$ cd /data/

$ git clone git://git.openembedded.org/bitbake

$ vi ~/.bash_profile

PATH=$PATH:$HOME/.local/bin:$HOME/bin:/data/bitbake/bin

$ source ~/.bash_profile

$ bitbake -h

建立bitbake项目,编译前目录结构如下(其中bitbake.conf、base.bbclass直接从bitbake安装目录拷贝过来):

[coadmin@vm5 bitbake_test]$ tree

.

├── build

│   └── conf

│       ├── bblayers.conf

│       └── bitbake.conf

├── meta-printhello

│   ├── classes

│   │   ├── base.bbclass

│   │   └── global.bbclass

│   ├── conf

│   │   └── layer.conf

│   └── recipes

│       ├── printhello.bb

│       └── test.bb

└── meta-two

├── classes

│   └── two.bbclass

├── conf

│   └── layer.conf

└── recipes

├── two.bb

└── two.bbappend

各文件内容:

[coadmin@vm5 bitbake_test]$ cat build/conf/bblayers.conf

BBPATH := “${TOPDIR}”

BBFILES ?= “”

BBLAYERS = ” \

${TOPDIR}/../meta-printhello \

${TOPDIR}/../meta-two \

”

[coadmin@vm5 bitbake_test]$ cat meta-printhello/classes/global.bbclass

addtask build

python global_do_build () {

bb.plain(“********************”);

bb.plain(“*  global_do_build *”);

bb.plain(“********************”);

}

EXPORT_FUNCTIONS do_build

[coadmin@vm5 bitbake_test]$ cat meta-printhello/conf/layer.conf

BBPATH .= “:${LAYERDIR}”

BBFILES += “${LAYERDIR}/recipes/*.bb”

BBFILE_COLLECTIONS += “printhello”

BBFILE_PATTERN_printhello := “^${LAYERDIR_RE}/”

BBFILE_PRIORITY_printhello = “5”

[coadmin@vm5 bitbake_test]$ cat meta-printhello/recipes/printhello.bb

DESCRIPTION = “Prints Hello World”

PN = ‘printhello’

PV = ‘1’

PR = “r1”

inherit global

python do_fetch() {

bb.plain(“********************”);

bb.plain(“*                  *”);

bb.plain(“*  FETCH RESOURCE  *”);

bb.plain(“*                  *”);

bb.plain(“********************”);

}

def printdate1():

import time

print(time.strftime(‘%Y%m%d’, time.gmtime()))

python do_printdate() {

bb.plain(“********************”);

bb.plain(“*  PRINT DATE TIME *”);

printdate1();

bb.plain(“********************”);

}

addtask printdate after do_fetch before do_build

addtask fetch

[coadmin@vm5 bitbake_test]$ cat meta-printhello/recipes/test.bb

DESCRIPTION = “TEST”

PN = ‘test’

PV = ‘1’

PR = “r0”

python do_build() {

bb.plain(“********************”);

bb.plain(“*                  *”);

bb.plain(“*  test build      *”);

bb.plain(“*                  *”);

bb.plain(“********************”);

}

addtask build

[coadmin@vm5 bitbake_test]$ cat meta-two/classes/two.bbclass

inherit global

two_do_configure () {

echo “running configbuild_do_configure.”

}

addtask do_configure before do_build

EXPORT_FUNCTIONS do_configure

[coadmin@vm5 bitbake_test]$ cat meta-two/conf/layer.conf

BBPATH .= “:${LAYERDIR}”

BBFILES += “${LAYERDIR}/recipes*/*.bb \

${LAYERDIR}/recipes*/*.bbappend”

BBFILE_COLLECTIONS += “two”

BBFILE_PATTERN_two = “^${LAYERDIR}/”

BBFILE_PRIORITY_two = “5”

LAYERVERSION_two = “1”

[coadmin@vm5 bitbake_test]$ cat meta-two/recipes/two.bb

DESCRIPTION = “I am the two”

PN = “two”

PR = “r1”

inherit two

再看build之后的目录结构(整个tmp目录为生成的工作目录,重构前可删除):

[coadmin@vm5 bitbake_test]$ cd build/

[coadmin@vm5 build]$ bitbake printhello

[coadmin@vm5 build]$ bitbake two

所有的目标都执行:

[coadmin@vm5 build]$ bitbake world

…

[coadmin@vm5 build]$ tree ..

..

├── build

│   ├── bitbake-cookerdaemon.log

│   ├── conf

│   │   ├── bblayers.conf

│   │   └── bitbake.conf

│   └── tmp

│       ├── cache

│       │   ├── bb_codeparser.dat

│       │   ├── bb_persist_data.sqlite3

│       │   └── local_file_checksum_cache.dat

│       ├── stamps

│       │   ├── printhello-1-r1.do_fetch

│       │   ├── printhello-1-r1.do_printdate

│       │   ├── two-1.0-r1.do_configure

│       │   └── two-1.0-r1.do_patch

│       └── work

│           ├── printhello-1-r1

│           │   └── temp

│           │       ├── log.do_build -> log.do_build.4270

│           │       ├── log.do_build.4270

│           │       ├── log.do_fetch -> log.do_fetch.4263

│           │       ├── log.do_fetch.4263

│           │       ├── log.do_printdate -> log.do_printdate.4267

│           │       ├── log.do_printdate.4267

│           │       ├── log.task_order

│           │       ├── run.do_build -> run.do_build.4270

│           │       ├── run.do_build.4270

│           │       ├── run.do_fetch -> run.do_fetch.4263

│           │       ├── run.do_fetch.4263

│           │       ├── run.do_printdate -> run.do_printdate.4267

│           │       ├── run.do_printdate.4267

│           │       └── run.global_do_build.4270

│           ├── test-1-r0

│           │   └── temp

│           │       ├── log.do_build -> log.do_build.4268

│           │       ├── log.do_build.4268

│           │       ├── log.task_order

│           │       ├── run.do_build -> run.do_build.4268

│           │       └── run.do_build.4268

│           └── two-1.0-r1

│               └── temp

│                   ├── log.do_build -> log.do_build.4269

│                   ├── log.do_build.4269

│                   ├── log.do_configure -> log.do_configure.4265

│                   ├── log.do_configure.4265

│                   ├── log.do_patch -> log.do_patch.4264

│                   ├── log.do_patch.4264

│                   ├── log.task_order

│                   ├── run.do_build -> run.do_build.4269

│                   ├── run.do_build.4269

│                   ├── run.do_configure -> run.do_configure.4265

│                   ├── run.do_configure.4265

│                   ├── run.do_patch -> run.do_patch.4264

│                   ├── run.do_patch.4264

│                   └── run.global_do_build.4269

├── meta-printhello

│   ├── classes

│   │   ├── base.bbclass

│   │   └── global.bbclass

│   ├── conf

│   │   └── layer.conf

│   └── recipes

│       ├── printhello.bb

│       └── test.bb

└── meta-two

├── classes

│   └── two.bbclass

├── conf

│   └── layer.conf

└── recipes

├── two.bb

└── two.bbappend

最后,看看怎么编译AGL Linux

1. 准备环境,以CentOS为例:

# sudo yum install gawk make wget tar bzip2 gzip python unzip perl patch diffutils diffstat git cpp gcc gcc-c++ glibc-devel texinfo chrpath socat SDL-devel xterm curl

# export AGL_TOP=$HOME/workspace_agl

# mkdir -p $AGL_TOP

# mkdir -p ~/bin

# export PATH=~/bin:$PATH

# curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo

# chmod a+x ~/bin/repo

2. 下载源码:

# cd $AGL_TOP

# repo init -b eel -m eel_5.1.0.xml -u https://gerrit.automotivelinux.org/gerrit/AGL/AGL-repo

# repo sync

3. 编译(以目标为qemu为例),会生成各种可启动的img:

# cd $AGL_TOP

# source meta-agl/scripts/aglsetup.sh -f -m qemux86-64 agl-demo agl-devel

# bitbake agl-demo-platform

4. 运行(以VmWare Workstation为例):

# cd tmp/deploy/images/qemux86-64

# xz -d agl-demo-platform-qemux86-64.vmdk.xz

这样会得到一个vmdk格式的可启动硬盘镜像,在VmWare WorkStation建立一个虚机,选择该镜像作为挂载的硬盘,上电开机即可。

 

1,896次阅读

Post navigation

前一篇:

中国金融数据月度报表-2018年10月

后一篇:

中国金融数据月度报表-2018年11月

发表评论 取消回复

邮箱地址不会被公开。 必填项已用*标注

个人介绍

需要么,有事情这里找联系方式:关于天楚锐齿

=== 美女同欣赏,好酒共品尝 ===

微信扫描二维码赞赏该文章:

扫描二维码分享该文章:

分类目录

  • Linux&Android (79)
  • Uncategorized (1)
  • 下载 (28)
  • 云计算 (37)
  • 人工智能 (8)
  • 大数据 (24)
  • 嵌入式 (34)
  • 杂七杂八 (34)
  • 物联网 (59)
  • 网络 (23)
  • 通信 (21)

文章归档

近期文章

  • 使用Python渲染OpenGL的.obj和.mtl文件
  • 用LVGL图形库绘制二维码
  • Android使用Messenger和SharedMemory实现跨app的海量数据传输
  • CAN信号的c语言解析代码
  • QT qml下DBus的使用例子

近期评论

  • 硕发表在《使用Android的HIDL+AIDL方式编写从HAL层到APP层的程序》
  • maxshu发表在《使用Android的HIDL+AIDL方式编写从HAL层到APP层的程序》
  • Ambition发表在《使用Android的HIDL+AIDL方式编写从HAL层到APP层的程序》
  • Ambition发表在《使用Android的HIDL+AIDL方式编写从HAL层到APP层的程序》
  • maxshu发表在《Android9下用ethernet 的Tether模式来做路由器功能》

阅读量

  • 使用Android的HIDL+AIDL方式编写从HAL层到APP层的程序 - 16,808次阅读
  • 卸载深信服Ingress、SecurityDesktop客户端 - 12,079次阅读
  • 车机技术之Android Automotive - 6,661次阅读
  • 车机技术之车规级Linux-Automotive Grade Linux(AGL) - 5,866次阅读
  • Linux策略路由及iptables mangle、ip rule、ip route关系及一种Network is unreachable错误 - 5,711次阅读
  • 在Android9下用ndk编译vSomeIP和CommonAPI以及使用例子 - 5,658次阅读
  • linux下的unbound DNS服务器设置详解 - 5,601次阅读
  • linux的tee命令导致ssh客户端下的shell卡住不动 - 4,998次阅读
  • 车机技术之360°全景影像(环视)系统 - 4,897次阅读
  • libwebp(处理webp图像)的安装和使用 - 4,749次阅读

功能

  • 文章RSS
  • 评论RSS

联系方式

地址
深圳市科技园

时间
周一至周五:  9:00~12:00,14:00~18:00
周六和周日:10:00~12:00

标签

android AT命令 centos Hadoop hdfs ip ipv6 kickstart linux mapreduce mini6410 modem OAuth openstack os python socket ssh uboot 内核 协议 安装 嵌入式 性能 报表 授权 操作系统 数据 数据库 月报 模型 汽车 测试 深信服 深度学习 源代码 神经网络 统计 编译 网络 脚本 虚拟机 调制解调器 车机 金融
© 2023 天楚锐齿