采用 UBIFS 制作 Android 的文件系统
来源:互联网 发布:java配置伪静态 编辑:程序博客网 时间:2024/05/16 07:27
分类: 嵌入式
Andriod 默认使用的是 YAFFS2 文件系统。相对于 YAFFS2 文件系统,UBIFS 是新一代的 Flash 文件系统,其设计以及性能都优越于 YAFFS2,特别是工作在大页 MLC NAND FLASH 上面时,读写速度比 YAFFS2 高出很多,同时 UBIFS 支持压缩,系统的高压缩率也为生产安装提高效率,如采用 YAFFS2 生成的 system.img 有120M,当采用 UBIFS 后镜像只有70~80M。可以使用下面的命令简单测试一下 UBIFS 的读写速度,Android 提供的 Toolbox 不支持下面的命令,你可以把 Busybox 装上再测试。
timecp /data/test.img /dev/null; time sync
采用 UBIFS 制作 Android 的文件系统的详细步骤如下:
一、准备 mkfs.ubifs 和 ubinize 这两个工具。mkfs.ubifs 用于生成 UBIFS 镜像,ubinize 用于生成 UBI 镜像。这两个工具都包含于 mtd-utils 中,你可以在你的开发主机上把 mtd-utils 这个软件包装上,或者,你可以把 mtd-utils 的源码整合到 Android 的源码中一起编译。
二、修改 Android 的编译系统,添加生成 UBIFS 文件系统的编译规则。
# ---------------------------------------------------------------
# Generic tools.
......
MKYAFFS2 :=$(HOST_OUT_EXECUTABLES)/mkyaffs2image$(HOST_EXECUTABLE_SUFFIX)
MKUBIFS :=$(HOST_OUT_EXECUTABLES)/mkubifs$(HOST_EXECUTABLE_SUFFIX)
UBINIZE :=$(HOST_OUT_EXECUTABLES)/ubinize$(HOST_EXECUTABLE_SUFFIX)
# #################################################################
# Targets for user images
# #################################################################
......
ifeq ($(strip $(TARGET_USERIMAGES_USE_UBIFS)),true)
INTERNAL_FLASH_PAGESIZE:= $(shellecho $$(($(BOARD_KERNEL_PAGESIZE))))
INTERNAL_FLASH_PEBSIZE :=$(shellecho $$(($(BOARD_FLASH_BLOCK_SIZE))))
INTERNAL_FLASH_LEBSIZE :=$(shellecho \
$$(($(INTERNAL_FLASH_PEBSIZE)- 2 * $(INTERNAL_FLASH_PAGESIZE))))
INTERNAL_SYSTEM_PARTITION_LEBCOUNT :=$(shellecho \
$$(($(BOARD_SYSTEMIMAGE_PARTITION_SIZE)/ $(INTERNAL_FLASH_PEBSIZE))))
INTERNAL_SYSTEM_PARTITION_SIZE :=$(shellecho \
$$(($(INTERNAL_FLASH_LEBSIZE)* $(INTERNAL_SYSTEM_PARTITION_LEBCOUNT))))
INTERNAL_USERDATA_PARTITION_LEBCOUNT :=$(shellecho \
$$(($(BOARD_USERDATAIMAGE_PARTITION_SIZE)/ $(INTERNAL_FLASH_PEBSIZE))))
INTERNAL_USERDATA_PARTITION_SIZE :=$(shellecho \
$$(($(INTERNAL_FLASH_LEBSIZE)* $(INTERNAL_USERDATA_PARTITION_LEBCOUNT))))
INTERNAL_PERSIST_PARTITION_LEBCOUNT :=$(shellecho \
$$(($(BOARD_PERSISTIMAGE_PARTITION_SIZE)/ $(INTERNAL_FLASH_PEBSIZE))))
INTERNAL_PERSIST_PARTITION_SIZE :=$(shellecho \
$$(($(INTERNAL_FLASH_LEBSIZE)* $(INTERNAL_PERSIST_PARTITION_LEBCOUNT))))
# $(1): image file
# $(2): volume size
# $(3): volume name
# $(4): output file
define combine-ubinize-ini-file
@mkdir -p$(dir$(4))
$(hide)echo "[ubifs]" > $(4);\
echo"mode=ubi" >> $(4);\
echo"image=$(1)" >> $(4);\
echo"vol_id=0" >> $(4);\
echo"vol_size=$(2)" >> $(4);\
echo"vol_type=dynamic" >> $(4);\
echo"vol_name=$(3)" >> $(4);\
echo"vol_flags=autoresize" >> $(4);\
echo"vol_alignment=1" >> $(4);
endef
else
......
endif
......
# -----------------------------------------------------------------
# system image
#
systemimage_intermediates :=\
$(call intermediates-dir-for,PACKAGING,systemimage)
BUILT_SYSTEMIMAGE :=$(systemimage_intermediates)/system.img
INTERNAL_SYSTEMIMAGE_FILES :=$(filter$(TARGET_OUT)/%,\
$(ALL_PREBUILT)\
$(ALL_COPIED_HEADERS)\
$(ALL_GENERATED_SOURCES)\
$(ALL_DEFAULT_INSTALLED_MODULES))
ifeq ($(strip $(TARGET_USERIMAGES_USE_UBIFS)),true)
INTERNAL_SYSTEMUBIFS_ARGS :=\
-r$(TARGET_OUT)\
-m$(INTERNAL_FLASH_PAGESIZE)\
-e$(INTERNAL_FLASH_LEBSIZE)\
-c$(INTERNAL_SYSTEM_PARTITION_LEBCOUNT)
INTERNAL_SYSTEMUBI_ARGS :=\
-p$(INTERNAL_FLASH_PEBSIZE)\
-m$(INTERNAL_FLASH_PAGESIZE)
INTERNAL_SYSTEMUBIFS :=$(systemimage_intermediates)/system.ubifs
$(INTERNAL_SYSTEMUBIFS):$(INTERNAL_SYSTEMIMAGE_FILES)$(MKUBIFS)
@mkdir -p$(dir$@)
$(MKUBIFS)$(INTERNAL_SYSTEMUBIFS_ARGS)-o $@
INTERNAL_SYSTEMUBICFG :=$(systemimage_intermediates)/system.cfg
.PHONY:$(INTERNAL_SYSTEMUBICFG)
$(INTERNAL_SYSTEMUBICFG):
$(call combine-ubinize-ini-file,$(INTERNAL_SYSTEMUBIFS),\
$(INTERNAL_SYSTEM_PARTITION_SIZE),system,$@)
INTERNAL_USERIMAGES_DEPS :=$(UBINIZE)\
$(INTERNAL_SYSTEMUBIFS)\
$(INTERNAL_SYSTEMUBICFG)
## generate a ubifs image
# $(1): output file
define build-systemimage-target
@echo"Target system fs image: $(1)"
@mkdir -p$(dir$(1))
$(UBINIZE)-o $(1)$(INTERNAL_SYSTEMUBI_ARGS)$(INTERNAL_SYSTEMUBICFG)
$(hide)chmod a+r $(1)
endef
else # TARGET_USERIMAGES_USE_UBIFS != true
......
endif # TARGET_USERIMAGES_USE_UBIFS
$(BUILT_SYSTEMIMAGE):$(INTERNAL_SYSTEMIMAGE_FILES)$(INTERNAL_USERIMAGES_DEPS)
$(call build-systemimage-target,$@)
......
# -----------------------------------------------------------------
# data partition image
#
INTERNAL_USERDATAIMAGE_FILES :=\
$(filter$(TARGET_OUT_DATA)/%,$(ALL_DEFAULT_INSTALLED_MODULES))
ifeq ($(strip $(TARGET_USERIMAGES_USE_UBIFS)),true)
userdataimage_intermediates :=\
$(call intermediates-dir-for,PACKAGING,userdataimage)
INTERNAL_USERDATAUBIFS_ARGS :=\
-r$(TARGET_OUT_DATA)\
-m$(INTERNAL_FLASH_PAGESIZE)\
-e$(INTERNAL_FLASH_LEBSIZE)\
-c$(INTERNAL_USERDATA_PARTITION_LEBCOUNT)
INTERNAL_USERDATAUBI_ARGS :=\
-p$(INTERNAL_FLASH_PEBSIZE)\
-m$(INTERNAL_FLASH_PAGESIZE)
INTERNAL_USERDATAUBIFS :=$(userdataimage_intermediates)/userdata.ubifs
$(INTERNAL_USERDATAUBIFS):$(INTERNAL_USERDATAIMAGE_FILES)$(MKUBIFS)
@mkdir -p$(dir$@)
$(MKUBIFS)$(INTERNAL_USERDATAUBIFS_ARGS)-o $@
INTERNAL_USERDATAUBICFG :=$(userdataimage_intermediates)/userdata.cfg
.PHONY:$(INTERNAL_USERDATAUBICFG)
$(INTERNAL_USERDATAUBICFG):
$(call combine-ubinize-ini-file,$(INTERNAL_USERDATAUBIFS),\
$(INTERNAL_USERDATA_PARTITION_SIZE),userdata,$@)
INTERNAL_USERIMAGES_DEPS :=$(UBINIZE)\
$(INTERNAL_USERDATAUBIFS)\
$(INTERNAL_USERDATAUBICFG)
## Generate a ubifs image
define build-userdataimage-target
$(call pretty,"Target userdata fs image: $(INSTALLED_USERDATAIMAGE_TARGET)")
@mkdir -p$(TARGET_OUT_DATA)
$(UBINIZE)-o $(INSTALLED_USERDATAIMAGE_TARGET)\
$(INTERNAL_USERDATAUBI_ARGS)$(INTERNAL_USERDATAUBICFG)
$(hide)chmod a+r $(INSTALLED_USERDATAIMAGE_TARGET)
endef
else # TARGET_USERIMAGES_USE_UBIFS != true
......
endif # TARGET_USERIMAGES_USE_UBIFS
BUILT_USERDATAIMAGE_TARGET :=$(PRODUCT_OUT)/userdata.img
# We just build this directly to the install location.
INSTALLED_USERDATAIMAGE_TARGET :=$(BUILT_USERDATAIMAGE_TARGET)
$(INSTALLED_USERDATAIMAGE_TARGET):$(INTERNAL_USERIMAGES_DEPS)\
$(INTERNAL_USERDATAIMAGE_FILES)
$(build-userdataimage-target)
......
# -----------------------------------------------------------------
# persist partition image
#
INTERNAL_PERSISTIMAGE_FILES :=\
$(filter$(TARGET_OUT_PERSIST)/%,$(ALL_DEFAULT_INSTALLED_MODULES))
ifeq ($(strip $(TARGET_USERIMAGES_USE_UBIFS)),true)
persistimage_intermediates :=\
$(call intermediates-dir-for,PACKAGING,persistimage)
INTERNAL_PERSISTUBIFS_ARGS :=\
-r$(TARGET_OUT_PERSIST)\
-m$(INTERNAL_FLASH_PAGESIZE)\
-e$(INTERNAL_FLASH_LEBSIZE)\
-c$(INTERNAL_PERSIST_PARTITION_LEBCOUNT)
INTERNAL_PERSISTUBI_ARGS :=\
-p$(INTERNAL_FLASH_PEBSIZE)\
-m$(INTERNAL_FLASH_PAGESIZE)
INTERNAL_PERSISTUBIFS :=$(persistimage_intermediates)/persist.ubifs
$(INTERNAL_PERSISTUBIFS):$(INTERNAL_PERSISTIMAGE_FILES)$(MKUBIFS)
@mkdir -p$(dir$@)
$(MKUBIFS)$(INTERNAL_PERSISTUBIFS_ARGS)-o $@
INTERNAL_PERSISTUBICFG :=$(persistimage_intermediates)/persist.cfg
.PHONY:$(INTERNAL_PERSISTUBICFG)
$(INTERNAL_PERSISTUBICFG):
$(call combine-ubinize-ini-file,$(INTERNAL_PERSISTUBIFS),\
$(INTERNAL_PERSIST_PARTITION_SIZE),persist,$@)
INTERNAL_USERIMAGES_DEPS :=$(UBINIZE)\
$(INTERNAL_PERSISTUBIFS)\
$(INTERNAL_PERSISTUBICFG)
## Generate a ubifs image
define build-persistimage-target
$(call pretty,"Target persist fs image: $(INSTALLED_PERSISTIMAGE_TARGET)")
@mkdir -p$(TARGET_OUT_PERSIST)
$(UBINIZE)-o $(INSTALLED_PERSISTIMAGE_TARGET)\
$(INTERNAL_PERSISTUBI_ARGS)$(INTERNAL_PERSISTUBICFG)
$(hide)chmod a+r $(INSTALLED_PERSISTIMAGE_TARGET)
endef
else # TARGET_USERIMAGES_USE_UBIFS != true
......
endif # TARGET_USERIMAGES_USE_UBIFS
BUILT_PERSISTIMAGE_TARGET :=$(PRODUCT_OUT)/persist.img
# We just build this directly to the install location.
INSTALLED_PERSISTIMAGE_TARGET :=$(BUILT_PERSISTIMAGE_TARGET)
$(INSTALLED_PERSISTIMAGE_TARGET):$(INTERNAL_USERIMAGES_DEPS)\
$(INTERNAL_PERSISTIMAGE_FILES)
$(build-persistimage-target)
三、修改内核配置,打开 UBIFS 文件系统的支持。如果使用高通平台,需要修改 Nand 控制器的驱动。Nand Flash 是以页面为单位读写的,对 Nand Flash 读写数据之前要进行页面对齐处理,通常驱动会封装好的,但高通的 Nand 控制器驱动没有,所以为了使 UBI 能正常工作,需要修改高通的 Nand 控制器驱动添加页面对齐处理。
Memory Technology Device(MTD)support --->
<*> Enable UBI - Unsorted block images
File systems --->
Miscellaneous filesystems --->
<*> UBIFS file system support
四、修改设备的 AndroidBoard.mk 或 BoardConfig.mk,打开生成 UBIFS 格式的文件系统的编译开关,并在生成 boot.img 时添加内核命令行参数 androidboot.ubifs=true
ifeq ($(strip $(TARGET_USERIMAGES_USE_UBIFS)),true)
BOARD_KERNEL_CMDLINE +=androidboot.ubifs=true
endif
五、修改 init 的初始化脚本 system/core/rootdir/init.rc,添加挂载 ubifs 文件系统的动作
mount ubifs ubi@system /system
mount ubifs ubi@userdata /data nosuid nodev
mount ubifs ubi@persist /persist nosuid nodev
mount ubifs ubi@cache /cache nosuid nodev
六、当检测到内核命令行参数 androidboot.ubifs=true 时触发挂载 ubifs 文件系统的动作
staticunsigned ubifs_enabled = 0;
staticvoid import_kernel_nv(char*name,int in_qemu)
{
......
if (!in_qemu)
{
......
}else if (!strcmp(name,"androidboot.emmc")){
if (!strcmp(value,"true")){
emmc_boot= 1;
}
}else if (!strcmp(name,"androidboot.ubifs")){
if (!strcmp(value,"true")){
ubifs_enabled= 1;
}
}
}else {
......
}
}
staticint set_init_properties_action(intnargs,char **args)
{
......
property_set("ro.emmc",emmc_boot? "1" : "0");
property_set("ro.ubifs",ubifs_enabled? "1" : "0");
return0;
}
intmain(intargc,char **argv)
{
......
if(emmc_boot){
action_for_each_trigger("emmc-fs",action_add_queue_tail);
}else if(ubifs_enabled){
action_for_each_trigger("ubi-fs",action_add_queue_tail);
}else {
action_for_each_trigger("fs",action_add_queue_tail);
}
......
}
七、修改 init 的内置 mount 命令以支持 ubifs 文件系统的挂载
intdo_mount(intnargs,char **args)
{
......
if (!strncmp(source,"mtd@",4)) {
n = mtd_name_to_number(source+ 4);
if (n< 0) {
return-1;
}
sprintf(tmp,"/dev/block/mtdblock%d", n);
if (wait)
wait_for_file(tmp,COMMAND_RETRY_TIMEOUT);
if (mount(tmp,target,system,flags,options) < 0) {
return-1;
}
return0;
}else if (!strncmp(source,"ubi@",4)) {
n = ubi_attach_mtd(source+ 4);
if (n< 0) {
return-1;
}
sprintf(tmp,"/dev/ubi%d_0", n);
if (wait)
wait_for_file(tmp,COMMAND_RETRY_TIMEOUT);
if (mount(tmp,target,system,flags,options) < 0) {
ubi_detach_dev(n);
return-1;
}
return0;
}else if (!strncmp(source,"loop@",5)) {
intmode,loop,fd;
structloop_info info;
mode= (flags& MS_RDONLY) ? O_RDONLY : O_RDWR;
fd= open(source+ 5,mode);
if (fd< 0) {
return-1;
}
for (n= 0; ; n++){
sprintf(tmp,"/dev/block/loop%d", n);
loop= open(tmp,mode);
if (loop< 0) {
return-1;
}
/* if it is a blank loop device */
if (ioctl(loop,LOOP_GET_STATUS,&info)< 0 && errno == ENXIO) {
/* if it becomes our loop device */
if (ioctl(loop,LOOP_SET_FD,fd) >= 0) {
close(fd);
if (mount(tmp,target,system,flags,options) < 0) {
ioctl(loop,LOOP_CLR_FD,0);
close(loop);
return-1;
}
close(loop);
return0;
}
}
close(loop);
}
close(fd);
ERROR("out of loopback devices");
return-1;
}else {
if (wait)
wait_for_file(source,COMMAND_RETRY_TIMEOUT);
if (mount(source,target,system,flags,options) < 0) {
return-1;
}
return0;
}
}
intubi_attach_mtd(constchar *name);
intubi_detach_dev(intdev);
#define UBI_CTRL_DEV "/dev/ubi_ctrl"
#define UBI_SYS_PATH "/sys/class/ubi"
staticint ubi_dev_read_int(intdev,const char *file,int def)
{
intfd,val = def;
charpath[128],buf[64];
sprintf(path,UBI_SYS_PATH "/ubi%d/%s",dev,file);
wait_for_file(path,5);
fd= open(path,O_RDONLY);
if (fd== -1){
returnval;
}
if (read(fd,buf,64) > 0) {
val= atoi(buf);
}
close(fd);
returnval;
}
intubi_attach_mtd(constchar *name)
{
intret;
intmtd_num,ubi_num;
intubi_ctrl,ubi_dev;
intvols,avail_lebs,leb_size;
charpath[128];
structubi_attach_req attach_req;
structubi_mkvol_req mkvol_req;
mtd_num= mtd_name_to_number(name);
if (mtd_num== -1){
return-1;
}
ubi_ctrl= open(UBI_CTRL_DEV,O_RDONLY);
if (ubi_ctrl== -1){
return-1;
}
memset(&attach_req,0,sizeof(structubi_attach_req));
attach_req.ubi_num= UBI_DEV_NUM_AUTO;
attach_req.mtd_num= mtd_num;
ret= ioctl(ubi_ctrl,UBI_IOCATT,&attach_req);
if (ret== -1){
close(ubi_ctrl);
return-1;
}
ubi_num= attach_req.ubi_num;
vols= ubi_dev_read_int(ubi_num,"volumes_count",-1);
if (vols== 0) {
sprintf(path,"/dev/ubi%d",ubi_num);
ubi_dev= open(path,O_RDONLY);
if (ubi_dev== -1){
close(ubi_ctrl);
returnubi_num;
}
avail_lebs= ubi_dev_read_int(ubi_num,"avail_eraseblocks",0);
leb_size= ubi_dev_read_int(ubi_num,"eraseblock_size",0);
memset(&mkvol_req,0,sizeof(structubi_mkvol_req));
mkvol_req.vol_id= UBI_VOL_NUM_AUTO;
mkvol_req.alignment= 1;
mkvol_req.bytes= (longlong)avail_lebs* leb_size;
mkvol_req.vol_type= UBI_DYNAMIC_VOLUME;
ret= snprintf(mkvol_req.name,UBI_MAX_VOLUME_NAME + 1,"%s",name);
mkvol_req.name_len= ret;
ioctl(ubi_dev,UBI_IOCMKVOL,&mkvol_req);
close(ubi_dev);
}
close(ubi_ctrl);
returnubi_num;
}
intubi_detach_dev(intdev)
{
intret,ubi_ctrl;
ubi_ctrl= open(UBI_CTRL_DEV,O_RDONLY);
if (ubi_ctrl== -1){
return-1;
}
ret= ioctl(ubi_ctrl,UBI_IOCDET,&dev);
close(ubi_ctrl);
returnret;
}
- 采用 UBIFS 制作 Android 的文件系统
- 采用 UBIFS 制作 Android 的文件系统 (2011-11-10 20:41)
- ubifs文件系统的制作
- ubifs文件系统的制作
- ubifs文件系统的制作
- ubifs文件系统的制作以及移植
- Ubifs 文件系统的制作和启动
- 制作ubifs文件系统,所遇到的问题。
- Ubifs 文件系统的制作和启动
- 制作ubifs文件系统
- Ubifs制作文件系统
- 制作ubifs文件系统
- 制作ubifs文件系统
- ubifs文件系统制作
- ubifs文件系统制作
- ubifs文件系统制作
- 制作jffs2和ubifs文件系统时用到的mkfs.jffs2和mkfs.ubifs工具制作脚本
- ubifs文件系统制作与移植
- java练习题,每天一个java小程序-1…
- Linux 内核的队列实现--kfifo
- php 测试实验
- Jackson 框架 用例详解
- myeclipse配置hadoop开发环境
- 采用 UBIFS 制作 Android 的文件系统
- POJ 1961 Period
- 反走样
- VS2008 O/R designer 名称的复数形式 (Linq To sql 中文转英文报错)
- android busybox解决adbshell命令不全
- C++基础
- python game练习5.1
- 跨进程调用Service(AIDL服务)
- 数学之美系列二:谈谈中文分词