背景:
u-boot-2009.08版本不支持ext4文件系统,现在需要对ext4支持
目的:
在u-boot-2009.08版本上添加ext4文件系统支持
方法:
将高版本中的ext4相关代码移植到u-boot-2009.08
代码:
低版本uboot代码:u-boot-2009.08
高版本uboot代码:u-boot-2013.10(下载地址:ftp://ftp.denx.de/pub/u-boot/)
步骤:
1:在头文件中定义宏开关
在include/configs/xxxxxxx.h中添加下面红色部分
#ifdef CONFIG_CMD_MMC
#define CONFIG_MMC
#define CONFIG_GENERIC_MMC
#define CONFIG_IMX_MMC
#define CONFIG_SYS_FSL_USDHC_NUM 4
#define CONFIG_SYS_FSL_ESDHC_ADDR 0
#define CONFIG_SYS_MMC_ENV_DEV 2
#define CONFIG_DOS_PARTITION 1
#define CONFIG_CMD_FAT 1
#define CONFIG_CMD_EXT2 1
#define CONFIG_CMD_EXT4 1 //对ext4文件格式支持的配置
#define CONFIG_CMD_EXT4_WRITE 1 //对ext4write命令的支持
/* detect whether SD1, 2, 3, or 4 is boot device */
#define CONFIG_DYNAMIC_MMC_DEVNO
/* SD3 and SD4 are 8 bit */
#define CONFIG_MMC_8BIT_PORTS 0xC
/* Setup target delay in DDR mode for each SD port */
#define CONFIG_GET_DDR_TARGET_DELAY
#endif
#if (defined(CONFIG_CMD_EXT4) ||defined(CONFIG_CMD_EXT2))&& \
!defined(CONFIG_FS_EXT4)
#define CONFIG_FS_EXT4 //新版本中uboot/fs/ext4/Makefile中编译选项的配置
#endif
#if defined(CONFIG_CMD_EXT4_WRITE)&&!defined(CONFIG_EXT4_WRITE)
#define CONFIG_EXT4_WRITE //新版本中uboot/fs/ext4/Makefile中编译选项的配置
#endif
2:添加ext4文件系统代码
A:将u-boot-2013.10/fs/ext4文件夹拷贝到u-boot-2009.08/fs/下
B:将u-boot-2013.10/include/下的fs.h,ext4fs.h, ext_common.h, sandboxfs.h文件
拷贝到u-boot-2009.08/include/下
C:将u-boot-2013.10/fs/fs.c文件拷贝到u-boot-2009.08/fs/ext4/下
D:在u-boot-2009.08/fs/ext4/ext4_journal.c中添加下面红色部分
#include "ext4_common.h"
#define false 0
#define true 1
E:修改u-boot-2009.08/fs/ext4/Makefile
将
LIB =$(obj)libext4fs.o
修改成
LIB =$(obj)libext4fs.a
将
$(LIB): $(obj).depend $(OBJS)
$(call cmd_link_o_target, $(OBJS))
修改成
$(LIB): $(obj).depend $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
将
COBJS-$(CONFIG_FS_EXT4) := ext4fs.oext4_common.o dev.o
修改成
COBJS-$(CONFIG_FS_EXT4) :=fs.oext4fs.o ext4_common.odev.o
F:修改u-boot-2009.08/fs/Makefile,添加下面红色部分
subdirs-$(CONFIG_CMD_EXT2) += ext2
subdirs-$(CONFIG_CMD_EXT4) += ext4
3:添加ext4相关命令
A:将u-boot-2013.10/common/cmd_ext4.c文件夹拷贝到u-boot-2009.08/common/下
B:修改u-boot-2009.08/common/Makefile,添加下面红色部分
COBJS-$(CONFIG_CMD_EXT2) += cmd_ext2.o
COBJS-$(CONFIG_CMD_EXT4) += cmd_ext4.o
4:修改u-boot-2009.08/Makefile,添加下面红色部分
LIBS+= fs/cramfs/libcramfs.a fs/fat/libfat.afs/fdos/libfdos.afs/jffs2/libjffs2.a \
fs/reiserfs/libreiserfs.afs/ext2/libext2fs.afs/yaffs2/libyaffs2.a \
fs/ubifs/libubifs.a fs/ext4/libext4fs.a
主要步骤完成,下面是编译时需要的一些东西,旧版本没有,需要从新版本中拷贝,
可以在编译时报错时临时修改拷贝,这里给出参考
6:修改u-boot-2009.08/common/cmd_nvedit.c
拷贝u-boot-2013.10/common/cmd_nvedit.c中的函数setenv_hex
到u-boot-2009.08/common/cmd_nvedit.c
7:修改u-boot-2009.08/disk/part.c
在u-boot-2009.08/disk/part.c中添加头文件#include<malloc.h>
在u-boot-2009.08/disk/part.c末尾添加get_device和get_device_and_partition这两个函数
8:修改u-boot-2009.08/include/asm-arm/cache.h,添加下面红色部分
void l2_cache_enable(void);
void l2_cache_disable(void);
#ifdef CONFIG_SYS_CACHELINE_SIZE
#defineARCH_DMA_MINALIGN CONFIG_SYS_CACHELINE_SIZE
#else
#define ARCH_DMA_MINALIGN 64
#endif
#endif
9:修改u-boot-2009.08/include/command.h,添加下面红色部分
#endif /* CONFIG_SYS_LONGHELP */
enum command_ret_t {
CMD_RET_SUCCESS, /* 0 = Success */
CMD_RET_FAILURE, /* 1 = Failure */
CMD_RET_USAGE = -1, /* Failure, please report'usage' error */
};
#endif /* __COMMAND_H */
10:修改u-boot-2009.08/include/common.h,添加下面红色部分到文件末尾
int setenv_hex(const char *varname, ulongvalue);
static inline int setenv_addr(const char*varname, const void*addr)
{
return setenv_hex(varname, (ulong)addr);
}
# ifndef CONFIG_ARCH_MAP_SYSMEM
static inline void *map_sysmem(phys_addr_tpaddr, unsigned longlen)
{
return (void *)(uintptr_t)paddr;
}
static inline void unmap_sysmem(const void*vaddr)
{
}
static inline phys_addr_t map_to_sysmem(void*ptr)
{
return (phys_addr_t)(uintptr_t)ptr;
}
#endif
#ifndef __ASSEMBLY__
#include <asm/cache.h>
#endif
#define PAD_COUNT(s, pad) (((s) - 1) / (pad) +1)
#define PAD_SIZE(s, pad) (PAD_COUNT(s, pad) *pad)
#define ALLOC_ALIGN_BUFFER_PAD(type, name,size, align, pad) \
char __##name[ROUND(PAD_SIZE((size) *sizeof(type), pad),align) \
+ (align - 1)]; \
\
type *name = (type *)ALIGN((uintptr_t)__##name, align)
#define ALLOC_ALIGN_BUFFER(type, name, size,align) \
ALLOC_ALIGN_BUFFER_PAD(type, name, size,align, 1)
#define ALLOC_CACHE_ALIGN_BUFFER_PAD(type,name, size, pad) \
ALLOC_ALIGN_BUFFER_PAD(type, name, size,ARCH_DMA_MINALIGN,pad)
#define ALLOC_CACHE_ALIGN_BUFFER(type, name,size) \
ALLOC_ALIGN_BUFFER(type, name, size,ARCH_DMA_MINALIGN)
#define DEFINE_ALIGN_BUFFER(type, name, size,align) \
static char __##name[roundup(size *sizeof(type), align)] \
__aligned(align); \
\
static type *name = (type *)__##name
#define DEFINE_CACHE_ALIGN_BUFFER(type, name,size) \
DEFINE_ALIGN_BUFFER(type, name, size,ARCH_DMA_MINALIGN)
/* Pull in stuff for the build system */
#ifdef DO_DEPS_ONLY
# include <environment.h>
#endif
11:修改u-boot-2009.08/include/ide.h,添加下面红色部分
#ifdef CONFIG_SYS_64BIT_LBA
typedef uint64_t lbaint_t;
#define LBAF "%llx"
#define LBAFU "%llu"
#else
typedef ulong lbaint_t;
#define LBAF "%lx"
#define LBAFU "%lu"
#endif
12:修改u-boot-2009.08/include/part.h,添加下面红色部分
typedefstruct block_dev_desc {
.......
unsignedlong blksz; /* block size */
int log2blksz; /*for convenience: log2(blksz) */
char vendor[40+1]; /* IDE model, SCSI Vendor */
.......
}block_dev_desc_t;
#defineBLOCK_CNT(size, block_dev_desc)(PAD_COUNT(size,block_dev_desc->blksz))
#definePAD_TO_BLOCKSIZE(size, block_dev_desc) \
(PAD_SIZE(size,block_dev_desc->blksz))
#defineLOG2(x) (((x & 0xaaaaaaaa) ? 1 : 0) + ((x &0xcccccccc) ? 2 :0) + \
((x & 0xf0f0f0f0) ? 4 : 0) + ((x & 0xff00ff00) ? 8 :0) + \
((x & 0xffff0000) ? 16 : 0))
#defineLOG2_INVALID(type) ((type)((sizeof(type)<<3)-1))
/*Interface types: */
#defineIF_TYPE_UNKNOWN 0
#defineIF_TYPE_IDE 1
.......
typedefstruct disk_partition {
ulong start; /*# of first block in partition */
ulong size; /*number of blocks in partition */
ulong blksz; /*block size in bytes */
uchar name[32]; /*partition name */
uchar type[32]; /*string type description */
int bootable; /*Active/Bootable flag is set */
}disk_partition_t;
/*disk/part.c */
......
voiddev_print(block_dev_desc_t *dev_desc);
intget_device(const char *ifname, const char *dev_str,
block_dev_desc_t **dev_desc);
intget_device_and_partition(const char *ifname, constchar*dev_part_str,
block_dev_desc_t **dev_desc,
disk_partition_t *info, int allow_whole_dev);
#else
.......
staticinline void dev_print(block_dev_desc_t *dev_desc) {}
staticinline int get_device(const char *ifname, const char*dev_str,
block_dev_desc_t **dev_desc)
{return -1; }
staticinline int get_device_and_partition(const char *ifname,
const char *dev_part_str,
block_dev_desc_t **dev_desc,
disk_partition_t *info,
int allow_whole_dev)
{*dev_desc = NULL; return -1; }
#endif
测试:
现在应该可以编译通过,测试ext4文件系统是否支持
将编译后生成的u-boot.bin烧写到sd卡中
启动后help下,会看到ext4ls,ext4load,ext4write命令
验证:
mmc
我的SD卡是emmc中管理,用的是SD3,所以是第二个设备(01 2 3)
mmc dev 2
切换挂载设备到sd卡
mmcinfo
查看下sd卡的信息
然后验证,意思为查看SD卡的第6个分区的文件
ext4ls mmc 2:6