嵌入式Android开发 系统层 busybox 工具的导入使用 选配了 ntpd ftpd

本文介绍如何将busybox 工具导入嵌入式Android 系统使用。

  接触一个东西,首先得有个概念,那么什么是busybox呢? busybox是一个专门用于嵌入式开发的轻量级工具集,这么说很抽象,下面给个具体的描述。
  大家在用linux系统的时候,用各种命令是不是用得很爽? cd 、grep 、cp 、ps 、du 、df 、find 、mount 、rm 等等这些命令极大的方便了大家的操作,那么这些命令都是怎么来的?从天而降?这些都是源自伟大的开源先驱们,他们发明了shell,初学者读到这里,会有疑问?什么是shell?简单介绍 计算机原来是没有我们习以为常的屏幕画面 、UI操作的,Unix发明之后,相继出现的shell就是指用命令行与计算机交流,就是在一个黑框框里敲命令给计算机执行,计算机执行完会反馈结果展示在命令行里,这就是shell。
在这里插入图片描述
shell以命令行的形式将计算机组成展示给 人,那么这些命令敲进去之后是谁来负责执行呢?/system/bin/目录下有着大名鼎鼎的bash,经常写.sh脚本的同学肯定不会陌生,我们敲的大部分命令就是传给bash帮我们执行,bash在现代Linux系统中都有。
  讲了这么多,有人会问,这些和本文介绍的busybox有个毛毛的关系?bash命令很多,很全能,全能战士,但是bash占的空间太大了,嵌入式开发一般都是小设备 机顶盒、播放盒、智能门锁,空间都是很珍贵的,不可能把一整个bash移过来,浪费空间 拖垮性能,得不偿失,busybox理解为bash的骨架版本,最重要的功能都有,每个功能可能参数不全,但大抵能用了,占用空间小,专为嵌入式开发而生。
  好了,说了很多直接说怎么用:

第一步:下载busybox源码 编译自己想要的命令集。

电脑环境以ubantu20.04.6为例。
首先安装交叉编译器
想在ubantu环境下编译出能在Android上运行的二进制文件,需要使用交叉编译器。
安装命令:

sudo apt install gcc-aarch64-linux-gnu

下载
官网下载busybox最新版:https://www.busybox.net/
友情提示:这里下载慢,翻了也慢,只能慢慢等,保持耐心。
在这里插入图片描述
下载完成拷贝到ubantu服务器上进行解压 选配 编译,还没有毕业参加工作的同学可以使用VMware在自己的电脑上安装一个ubantu的虚拟机。
解压
解压命令:

tar -jxvf busybox-1.36.1.tar.bz2

解压完成,生成同名目录
在这里插入图片描述
进入这个目录执行命令:

make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig

命令执行进入选配界面
选配
在这里插入图片描述
在选配具体命令之前,有两点是必须先选择的:
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
下面就进入选配命令环节。
就我的项目来说需要选配ntpd ftpd ,进入Networking Utilities选配。
ftpd
在这里插入图片描述
ntpd
在这里插入图片描述
最后编译:

make -j16 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-

编译好的二进制可执行文件:
在这里插入图片描述
ubantu里直接执行busybox,你会发现,明明选配了ntpd ftpd,但是可支持的命令里却看不到他两的身影,这里你不要疑惑,因为你没错,这个是busybox自己的问题,ntpd ftpd在ubantu上是不显示的,你把busybox直接adb push 到Android系统上,adb shell 之后,命令行直接运行busybox就可以看到ntpd ftpd 了,如下图所示:
在这里插入图片描述
最后把busybox放到要添加的安卓系统源码目录。
这里选择将它放到 vendor/芯片厂商/common/品牌方/ftpd/arm64/ 目录下。

第二步:将编译好的busybox通过Android.mk 编译进Android系统使用

在arm64目录同级下新增Android.mk和ftpd.mk
在这里插入图片描述
Android.mk

LOCAL_PATH := $(call my-dir)  

include $(CLEAR_VARS) 
#从这里开始往下开始编译

LOCAL_MODULE := busybox
#编译模块的名字

LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
#指定本模块的依赖

LOCAL_MODULE_TAGS := optional
#原生Android系统 source——>lunch——>make ,在lunch的时候会去选择编译的类型。
#user: 指该模块只在user版本下才编译
#eng: 指该模块只在eng版本下才编译
#tests: 指该模块只在tests版本下才编译
#optional:指该模块在所有版本下都编译

LOCAL_MODULE_CLASS := EXECUTABLES
#标识所编译模块最后放置的位置。常用的值如下
#ETC 表示放于system/etc目录
#EXECUTABLES 放于/system/bin,表示可执行文件。
#SHARED_LIBRARIES 放在/system/lib下
  
LOCAL_MODULE_STEM := $(LOCAL_MODULE)
#所以LOCAL_MODULE_STEM可以用于指定最终目标文件, LOCAL_MODULE可以指定out输出路径。
#如果没有LOCAL_MODULE_STEM, 输出路径和最终目标文件都是以LOCAL_MODULE为准。

LOCAL_SRC_FILES := $(TARGET_ARCH)/$(LOCAL_MODULE)
//编译所需的源文件 arm64/busybox

include $(BUILD_PREBUILT)
#结束编译。 BUILD_PREBUILT 是 Android 开源项目 (AOSP) 中的一个模块编译指令。它用于在 Android 编译系统中将预编译好的文件添加到系统中。
#预编译文件可以是任何类型的文件,例如二进制可执行文件、共享库、静态库、内核镜像、固件等。通常,这些文件是由外部工具或第三方提供,并且在编
#译 Android 系统时作为一个整体添加到系统映像中,而不是在 Android 源代码树中编译生成。

OUR_TOOLS := \
       ntpd \
			 ftpd 
#这里定义了一个工具集,包括三个工具,这些工具将被构建和安装到嵌入式系统中。

SYMLINKS := $(addprefix $(TARGET_OUT)/bin/,$(OUR_TOOLS))
#这一行通过 addprefix 函数将 OUR_TOOLS 中的每个工具名前面加上 $(TARGET_OUT)/bin/,然后存储到 SYMLINKS 变量中。这将创建一个包含目标路径的符号链接列表。

$(SYMLINKS): BUSYBOX_BINARY := $(LOCAL_MODULE)
#为之前定义的符号链接列表 SYMLINKS 中的每个符号链接,指定要链接的二级制可执行文件名,BUSYBOX_CLT_BINARY 值为busybox。

$(SYMLINKS): $(LOCAL_INSTALLED_MODULE) $(LOCAL_PATH)/Android.mk
#链接依赖 LOCAL_INSTALLED_MODULE (LOCAL_PATH)/Android.mk
#当在 Android 的 Android.mk 或 Android.bp 构建脚本中定义一个模块时,可以通过设置 LOCAL_MODULE_PATH 变量来指定模块的安装路径。而 LOCAL_INSTALLED_MODULE 变量则用于保存模块在系统中的完整安装路径,它是由 LOCAL_MODULE_PATH 和 LOCAL_MODULE(模块名称)两个变量
#组合而成的。就当前这个mk文件来说,LOCAL_INSTALLED_MODULE 的值为 /system/bin/busybox

	echo "Symlink: $@ -> $(BUSYBOX_BINARY)"
#echo "Symlink: $@ -> $(BUSYBOX_BINARY)": 这一行会在执行规则之前输出一条消息,显示正在创建符号链接。
	mkdir -p $(dir $@)
#考虑一个例子,如果$@的值是out/target/bin/myapp,那么$(dir $@)将返回out/target/bin/。
#在上述代码段中,mkdir -p $(dir $@) 将会创建一个目录,确保目标符号链接文件所在的目录存在,这样后续的ln -sf命令就可以在正确的目录下创
#建符号链接。mkdir -p 目录不存在就创建。$(dir $@) 的值为 /system/bin/
	rm -rf $@
#这一行先删除之前可能存在的同名符号链接(如果有的话)。
	ln -sf $(BUSYBOX_BINARY) $@
# -s 软链接 -f 强制执行,具体到这里的意思就是创建$@ 指向$(BUSYBOX_BINARY) 的软链接,$@的值有两个#/system/bin/ntpd、/system/bin/ftpd  BUSYBOX_BINARY的值为busybox

ALL_DEFAULT_INSTALLED_MODULES += $(SYMLINKS)
#这一行将之前定义的符号链接列表 SYMLINKS 添加到 #ALL_DEFAULT_INSTALLED_MODULES 变量中,该变量包含了所有默认安装的模块列表

# We need this so that the installed files could be picked up based on the
# local module name
ALL_MODULES.$(LOCAL_MODULE).INSTALLED := \
    $(ALL_MODULES.$(LOCAL_MODULE).INSTALLED) $(SYMLINKS)
#ALL_MODULES.$(LOCAL_MODULE).INSTALLED 所有模块的各自安装路径
#例如:手机中模块路径为system/bin/recovery,那么ALL_MODULES.recovery.INSTALLED的值为源码编译出的路#径out/target/product/find5/system/bin/
# 这一行将符号链接列表 SYMLINKS 添加到名为 ALL_MODULES 的字典变量中,其中键是 LOCAL_MODULE 的值。这样做是为了确保在安装过程中包含
# 了这些符号链接文件。

下面附上没有注释的纯净版本:
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := busybox
LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := EXECUTABLES
LOCAL_MODULE_STEM := $(LOCAL_MODULE)
LOCAL_SRC_FILES := $(TARGET_ARCH)/$(LOCAL_MODULE)
include $(BUILD_PREBUILT)

OUR_TOOLS := \
       ntpd \
			 ftpd 
SYMLINKS := $(addprefix $(TARGET_OUT)/bin/,$(OUR_TOOLS))
$(SYMLINKS): BUSYBOX_BINARY := $(LOCAL_MODULE)
$(SYMLINKS): $(LOCAL_INSTALLED_MODULE) $(LOCAL_PATH)/Android.mk
	echo "Symlink: $@ -> $(BUSYBOX_BINARY)"
	mkdir -p $(dir $@)
	rm -rf $@
	ln -sf $(BUSYBOX_BINARY) $@
ALL_DEFAULT_INSTALLED_MODULES += $(SYMLINKS)
ALL_MODULES.$(LOCAL_MODULE).INSTALLED := \
    $(ALL_MODULES.$(LOCAL_MODULE).INSTALLED) $(SYMLINKS)

在说ftpd.mk之前,先补充一个知识点,在mk文件中不管你是定义了一个新模块,还是定义了一个符号链接,最后都要通过ALL_DEFAULT_INSTALLED_MODULES 或者 PRODUCT_PACKAGES告诉编译系统,最后生成的镜像中需要打包你定义的新模块,不然你会发现编译没有报错,但是自己定义的新模块,却没有出现在最后的刷机镜像中。上文我们通过ALL_DEFAULT_INSTALLED_MODULES += $(SYMLINKS) 把创建新链接加入到了镜像打包,但是busybox还没做,ftpd.mk就做了这件事。
ftpd.mk

PRODUCT_PACKAGES += \
	                busybox

这两个mk文件需要被上一级的mk文件包含:
在这里插入图片描述
在这里插入图片描述
这样操作下来,使用最后编译出来的系统刷机,在system/bin目录下就可以看到ftpd ntpd busybox了,ftpd,ntpd可以直接执行。
在这里插入图片描述
到这里busybox就成功导入嵌入式Android系统了。

后续如果还想再进一步,其实可以把 ntpd ftpd 添加到init.rc,搞成一个开机自启动服务,这块我搞了,selinux部分有点难搞,这里就先不写。

版本记录:
2023/7/29 第二步这里我还没有完全理解清楚,后面理解了会补全,先上传。
2023/8/10 今天开始补全文档。
2023/8/11 补全文档完成。
2023/8/18 之前的版本有遗漏,忘记添加交叉编译器部分。
2023/8/25 后面会补充一篇 busybox 编译过程中的 踩坑解决合集,希望可以帮到正在踩坑的人。

猜你喜欢

转载自blog.csdn.net/weixin_43522377/article/details/131994562