采用 UBIFS 制作 Android 的文件系统
2013-07-08 16:12
381 查看
采用 UBIFS 制作 Android 的文件系统
2011-11-10 20:41:08
分类: 嵌入式
采用
UBIFS 制作 Android 的文件系统
Andriod 默认使用的是 YAFFS2 文件系统。相对于 YAFFS2 文件系统,UBIFS 是新一代的 Flash 文件系统,其设计以及性能都优越于 YAFFS2,特别是工作在大页 MLC NAND FLASH 上面时,读写速度比 YAFFS2 高出很多,同时 UBIFS 支持压缩,系统的高压缩率也为生产安装提高效率,如采用 YAFFS2 生成的 system.img 有120M,当采用 UBIFS 后镜像只有70~80M。可以使用下面的命令简单测试一下
UBIFS 的读写速度,Android 提供的 Toolbox 不支持下面的命令,你可以把 Busybox 装上再测试。
time
dd
if=/dev/zero
of=/data/test.img
bs=1M
count=100;
time
sync
time
cp /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 文件系统的编译规则。
# build/core/config.mk
# ---------------------------------------------------------------
# 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)
# build/core/Makefile
# #################################################################
# Targets for user images
# #################################################################
......
ifeq ($(strip $(TARGET_USERIMAGES_USE_UBIFS)),true)
INTERNAL_FLASH_PAGESIZE
:=
$(shell
echo
$$(($(BOARD_KERNEL_PAGESIZE))))
INTERNAL_FLASH_PEBSIZE :=
$(shell
echo
$$(($(BOARD_FLASH_BLOCK_SIZE))))
INTERNAL_FLASH_LEBSIZE :=
$(shell
echo
\
$$(($(INTERNAL_FLASH_PEBSIZE)
- 2 *
$(INTERNAL_FLASH_PAGESIZE))))
INTERNAL_SYSTEM_PARTITION_LEBCOUNT :=
$(shell
echo
\
$$(($(BOARD_SYSTEMIMAGE_PARTITION_SIZE)
/
$(INTERNAL_FLASH_PEBSIZE))))
INTERNAL_SYSTEM_PARTITION_SIZE :=
$(shell
echo
\
$$(($(INTERNAL_FLASH_LEBSIZE)
*
$(INTERNAL_SYSTEM_PARTITION_LEBCOUNT))))
INTERNAL_USERDATA_PARTITION_LEBCOUNT :=
$(shell
echo
\
$$(($(BOARD_USERDATAIMAGE_PARTITION_SIZE)
/
$(INTERNAL_FLASH_PEBSIZE))))
INTERNAL_USERDATA_PARTITION_SIZE :=
$(shell
echo
\
$$(($(INTERNAL_FLASH_LEBSIZE)
*
$(INTERNAL_USERDATA_PARTITION_LEBCOUNT))))
INTERNAL_PERSIST_PARTITION_LEBCOUNT :=
$(shell
echo
\
$$(($(BOARD_PERSISTIMAGE_PARTITION_SIZE)
/
$(INTERNAL_FLASH_PEBSIZE))))
INTERNAL_PERSIST_PARTITION_SIZE :=
$(shell
echo
\
$$(($(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 控制器驱动添加页面对齐处理。
Device Drivers --->
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
TARGET_USERIMAGES_USE_UBIFS
:=
true
ifeq ($(strip $(TARGET_USERIMAGES_USE_UBIFS)),true)
BOARD_KERNEL_CMDLINE +=
androidboot.ubifs=true
endif
五、修改 init 的初始化脚本 system/core/rootdir/init.rc,添加挂载 ubifs 文件系统的动作
on ubi-fs
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 文件系统的动作
/* system/core/init/init.c */
static
unsigned
ubifs_enabled
=
0;
static
void
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
{
......
}
}
static
int
set_init_properties_action(int
nargs,
char
**args)
{
......
property_set("ro.emmc",emmc_boot
?
"1"
:
"0");
property_set("ro.ubifs",ubifs_enabled
?
"1"
:
"0");
return
0;
}
int
main(int
argc,
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 文件系统的挂载
/* system/core/init/builtins.c */
int
do_mount(int
nargs,
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;
}
return
0;
}
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;
}
return
0;
}
else
if (!strncmp(source,
"loop@",
5))
{
int
mode,
loop,
fd;
struct
loop_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);
return
0;
}
}
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;
}
return
0;
}
}
/* system/core/init/util.h */
int
ubi_attach_mtd(const
char
*name);
int
ubi_detach_dev(int
dev);
/* system/core/init/util.c */
#define UBI_CTRL_DEV "/dev/ubi_ctrl"
#define UBI_SYS_PATH "/sys/class/ubi"
static
int
ubi_dev_read_int(int
dev,
const
char
*file,
int
def)
{
int
fd,
val
=
def;
char
path[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)
{
return
val;
}
if (read(fd,
buf,
64)
>
0)
{
val
=
atoi(buf);
}
close(fd);
return
val;
}
int
ubi_attach_mtd(const
char
*name)
{
int
ret;
int
mtd_num,
ubi_num;
int
ubi_ctrl,
ubi_dev;
int
vols,
avail_lebs,
leb_size;
char
path[128];
struct
ubi_attach_req
attach_req;
struct
ubi_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(struct
ubi_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);
return
ubi_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(struct
ubi_mkvol_req));
mkvol_req.vol_id
=
UBI_VOL_NUM_AUTO;
mkvol_req.alignment
=
1;
mkvol_req.bytes
= (long
long)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);
return
ubi_num;
}
int
ubi_detach_dev(int
dev)
{
int
ret,
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);
return
ret;
}
2011-11-10 20:41:08
分类: 嵌入式
采用
UBIFS 制作 Android 的文件系统
Andriod 默认使用的是 YAFFS2 文件系统。相对于 YAFFS2 文件系统,UBIFS 是新一代的 Flash 文件系统,其设计以及性能都优越于 YAFFS2,特别是工作在大页 MLC NAND FLASH 上面时,读写速度比 YAFFS2 高出很多,同时 UBIFS 支持压缩,系统的高压缩率也为生产安装提高效率,如采用 YAFFS2 生成的 system.img 有120M,当采用 UBIFS 后镜像只有70~80M。可以使用下面的命令简单测试一下
UBIFS 的读写速度,Android 提供的 Toolbox 不支持下面的命令,你可以把 Busybox 装上再测试。
time
dd
if=/dev/zero
of=/data/test.img
bs=1M
count=100;
time
sync
time
cp /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 文件系统的编译规则。
# build/core/config.mk
# ---------------------------------------------------------------
# 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)
# build/core/Makefile
# #################################################################
# Targets for user images
# #################################################################
......
ifeq ($(strip $(TARGET_USERIMAGES_USE_UBIFS)),true)
INTERNAL_FLASH_PAGESIZE
:=
$(shell
echo
$$(($(BOARD_KERNEL_PAGESIZE))))
INTERNAL_FLASH_PEBSIZE :=
$(shell
echo
$$(($(BOARD_FLASH_BLOCK_SIZE))))
INTERNAL_FLASH_LEBSIZE :=
$(shell
echo
\
$$(($(INTERNAL_FLASH_PEBSIZE)
- 2 *
$(INTERNAL_FLASH_PAGESIZE))))
INTERNAL_SYSTEM_PARTITION_LEBCOUNT :=
$(shell
echo
\
$$(($(BOARD_SYSTEMIMAGE_PARTITION_SIZE)
/
$(INTERNAL_FLASH_PEBSIZE))))
INTERNAL_SYSTEM_PARTITION_SIZE :=
$(shell
echo
\
$$(($(INTERNAL_FLASH_LEBSIZE)
*
$(INTERNAL_SYSTEM_PARTITION_LEBCOUNT))))
INTERNAL_USERDATA_PARTITION_LEBCOUNT :=
$(shell
echo
\
$$(($(BOARD_USERDATAIMAGE_PARTITION_SIZE)
/
$(INTERNAL_FLASH_PEBSIZE))))
INTERNAL_USERDATA_PARTITION_SIZE :=
$(shell
echo
\
$$(($(INTERNAL_FLASH_LEBSIZE)
*
$(INTERNAL_USERDATA_PARTITION_LEBCOUNT))))
INTERNAL_PERSIST_PARTITION_LEBCOUNT :=
$(shell
echo
\
$$(($(BOARD_PERSISTIMAGE_PARTITION_SIZE)
/
$(INTERNAL_FLASH_PEBSIZE))))
INTERNAL_PERSIST_PARTITION_SIZE :=
$(shell
echo
\
$$(($(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 控制器驱动添加页面对齐处理。
Device Drivers --->
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
TARGET_USERIMAGES_USE_UBIFS
:=
true
ifeq ($(strip $(TARGET_USERIMAGES_USE_UBIFS)),true)
BOARD_KERNEL_CMDLINE +=
androidboot.ubifs=true
endif
五、修改 init 的初始化脚本 system/core/rootdir/init.rc,添加挂载 ubifs 文件系统的动作
on ubi-fs
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 文件系统的动作
/* system/core/init/init.c */
static
unsigned
ubifs_enabled
=
0;
static
void
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
{
......
}
}
static
int
set_init_properties_action(int
nargs,
char
**args)
{
......
property_set("ro.emmc",emmc_boot
?
"1"
:
"0");
property_set("ro.ubifs",ubifs_enabled
?
"1"
:
"0");
return
0;
}
int
main(int
argc,
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 文件系统的挂载
/* system/core/init/builtins.c */
int
do_mount(int
nargs,
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;
}
return
0;
}
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;
}
return
0;
}
else
if (!strncmp(source,
"loop@",
5))
{
int
mode,
loop,
fd;
struct
loop_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);
return
0;
}
}
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;
}
return
0;
}
}
/* system/core/init/util.h */
int
ubi_attach_mtd(const
char
*name);
int
ubi_detach_dev(int
dev);
/* system/core/init/util.c */
#define UBI_CTRL_DEV "/dev/ubi_ctrl"
#define UBI_SYS_PATH "/sys/class/ubi"
static
int
ubi_dev_read_int(int
dev,
const
char
*file,
int
def)
{
int
fd,
val
=
def;
char
path[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)
{
return
val;
}
if (read(fd,
buf,
64)
>
0)
{
val
=
atoi(buf);
}
close(fd);
return
val;
}
int
ubi_attach_mtd(const
char
*name)
{
int
ret;
int
mtd_num,
ubi_num;
int
ubi_ctrl,
ubi_dev;
int
vols,
avail_lebs,
leb_size;
char
path[128];
struct
ubi_attach_req
attach_req;
struct
ubi_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(struct
ubi_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);
return
ubi_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(struct
ubi_mkvol_req));
mkvol_req.vol_id
=
UBI_VOL_NUM_AUTO;
mkvol_req.alignment
=
1;
mkvol_req.bytes
= (long
long)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);
return
ubi_num;
}
int
ubi_detach_dev(int
dev)
{
int
ret,
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);
return
ret;
}
相关文章推荐
- 采用 UBIFS 制作 Android 的文件系统 (2011-11-10 20:41)
- ubifs文件系统制作与移植
- 根文件系统制作之ubifs
- UBIFS文件系统简介 与 利用mkfs.ubifs和ubinize两个工具制作UBI镜像
- ubifs文件系统的制作过程&&遇到的问题及解决方案总结---之三“UBIFS镜像的制作&&烧写”
- 为AM335X 制作ubifs文件系统
- Ubifs 文件系统的制作和启动
- uboot UBIFS移植及android UBIFS文件系统烧写 .
- imx515 uboot UBIFS移植及android UBIFS文件系统烧写
- imx515 uboot UBIFS移植及android UBIFS文件系统烧写
- Android&nbsp;源码编译&nbsp;文件系统制作
- UBIFS文件系统简介 与 利用mkfs.ubifs和ubinize两个工具制作UBI镜像
- Android&nbsp;源码编译&nbsp;文件系统制作
- ubifs文件系统的制作过程&&遇到的问题及解决方案总结---之二“Linux内核中添加对UBIFS文件系统的支持”
- ubifs文件系统制作
- 制作ubifs文件系统
- android文件系统及其制作
- android文件系统制作教程(4) —- makefile脚本,制作各种单独的分区文件ramdisk.img,system.img,boot.img
- Android文件系统的制作
- imx515 uboot UBIFS移植及android UBIFS文件系统烧写