提交 5fb29f3c 编写于 作者: T Tom Rini

Merge branch 'ext4'

Update Makefile change for LIBS -> LIBS-y change.

Conflicts:
	Makefile
Signed-off-by: NTom Rini <trini@ti.com>
......@@ -242,9 +242,15 @@ LIBS-y += arch/arm/cpu/ixp/npe/libnpe.o
endif
LIBS-$(CONFIG_OF_EMBED) += dts/libdts.o
LIBS-y += arch/$(ARCH)/lib/lib$(ARCH).o
LIBS-y += fs/cramfs/libcramfs.o fs/fat/libfat.o fs/fdos/libfdos.o fs/jffs2/libjffs2.o \
fs/reiserfs/libreiserfs.o fs/ext2/libext2fs.o fs/yaffs2/libyaffs2.o \
fs/ubifs/libubifs.o fs/zfs/libzfs.o
LIBS-y += fs/cramfs/libcramfs.o \
fs/ext4/libext4fs.o \
fs/fat/libfat.o \
fs/fdos/libfdos.o \
fs/jffs2/libjffs2.o \
fs/reiserfs/libreiserfs.o \
fs/ubifs/libubifs.o \
fs/yaffs2/libyaffs2.o \
fs/zfs/libzfs.o
LIBS-y += net/libnet.o
LIBS-y += disk/libdisk.o
LIBS-y += drivers/bios_emulator/libatibiosemu.o
......
......@@ -86,7 +86,13 @@ COBJS-$(CONFIG_ENV_IS_IN_EEPROM) += cmd_eeprom.o
COBJS-$(CONFIG_CMD_EEPROM) += cmd_eeprom.o
COBJS-$(CONFIG_CMD_ELF) += cmd_elf.o
COBJS-$(CONFIG_SYS_HUSH_PARSER) += cmd_exit.o
COBJS-$(CONFIG_CMD_EXT4) += cmd_ext4.o
COBJS-$(CONFIG_CMD_EXT2) += cmd_ext2.o
ifdef CONFIG_CMD_EXT4
COBJS-y += cmd_ext_common.o
else
COBJS-$(CONFIG_CMD_EXT2) += cmd_ext_common.o
endif
COBJS-$(CONFIG_CMD_FAT) += cmd_fat.o
COBJS-$(CONFIG_CMD_FDC)$(CONFIG_CMD_FDOS) += cmd_fdc.o
COBJS-$(CONFIG_OF_LIBFDT) += cmd_fdt.o fdt_support.o
......
/*
* (C) Copyright 2011 - 2012 Samsung Electronics
* EXT4 filesystem implementation in Uboot by
* Uma Shankar <uma.shankar@samsung.com>
* Manjunatha C Achar <a.manjunatha@samsung.com>
* (C) Copyright 2004
* esd gmbh <www.esd-electronics.com>
* Reinhard Arlt <reinhard.arlt@esd-electronics.com>
......@@ -33,224 +38,34 @@
* Ext2fs support
*/
#include <common.h>
#include <part.h>
#include <config.h>
#include <command.h>
#include <image.h>
#include <linux/ctype.h>
#include <asm/byteorder.h>
#include <ext2fs.h>
#if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE)
#include <usb.h>
#endif
#if !defined(CONFIG_DOS_PARTITION) && !defined(CONFIG_EFI_PARTITION)
#error DOS or EFI partition support must be selected
#endif
/* #define EXT2_DEBUG */
#ifdef EXT2_DEBUG
#define PRINTF(fmt,args...) printf (fmt ,##args)
#else
#define PRINTF(fmt,args...)
#endif
#include <ext_common.h>
int do_ext2ls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
char *filename = "/";
int dev=0;
int part=1;
char *ep;
block_dev_desc_t *dev_desc=NULL;
int part_length;
if (argc < 3)
return CMD_RET_USAGE;
dev = (int)simple_strtoul (argv[2], &ep, 16);
dev_desc = get_dev(argv[1],dev);
if (dev_desc == NULL) {
printf ("\n** Block device %s %d not supported\n", argv[1], dev);
return 1;
}
if (*ep) {
if (*ep != ':') {
puts ("\n** Invalid boot device, use `dev[:part]' **\n");
return 1;
}
part = (int)simple_strtoul(++ep, NULL, 16);
}
if (argc == 4)
filename = argv[3];
PRINTF("Using device %s %d:%d, directory: %s\n", argv[1], dev, part, filename);
if ((part_length = ext2fs_set_blk_dev(dev_desc, part)) == 0) {
printf ("** Bad partition - %s %d:%d **\n", argv[1], dev, part);
ext2fs_close();
return 1;
}
if (!ext2fs_mount(part_length)) {
printf ("** Bad ext2 partition or disk - %s %d:%d **\n", argv[1], dev, part);
ext2fs_close();
return 1;
}
if (ext2fs_ls (filename)) {
printf ("** Error ext2fs_ls() **\n");
ext2fs_close();
return 1;
};
ext2fs_close();
if (do_ext_ls(cmdtp, flag, argc, argv))
return -1;
return 0;
}
U_BOOT_CMD(
ext2ls, 4, 1, do_ext2ls,
"list files in a directory (default /)",
"<interface> <dev[:part]> [directory]\n"
" - list files from 'dev' on 'interface' in a 'directory'"
);
/******************************************************************************
* Ext2fs boot command intepreter. Derived from diskboot
*/
int do_ext2load (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
char *filename = NULL;
char *ep;
int dev, part = 1;
ulong addr = 0, part_length;
int filelen;
disk_partition_t info;
block_dev_desc_t *dev_desc = NULL;
char buf [12];
unsigned long count;
char *addr_str;
switch (argc) {
case 3:
addr_str = getenv("loadaddr");
if (addr_str != NULL)
addr = simple_strtoul (addr_str, NULL, 16);
else
addr = CONFIG_SYS_LOAD_ADDR;
filename = getenv ("bootfile");
count = 0;
break;
case 4:
addr = simple_strtoul (argv[3], NULL, 16);
filename = getenv ("bootfile");
count = 0;
break;
case 5:
addr = simple_strtoul (argv[3], NULL, 16);
filename = argv[4];
count = 0;
break;
case 6:
addr = simple_strtoul (argv[3], NULL, 16);
filename = argv[4];
count = simple_strtoul (argv[5], NULL, 16);
break;
default:
return CMD_RET_USAGE;
}
if (!filename) {
puts ("** No boot file defined **\n");
return 1;
}
dev = (int)simple_strtoul (argv[2], &ep, 16);
dev_desc = get_dev(argv[1],dev);
if (dev_desc==NULL) {
printf ("** Block device %s %d not supported\n", argv[1], dev);
return 1;
}
if (*ep) {
if (*ep != ':') {
puts ("** Invalid boot device, use `dev[:part]' **\n");
return 1;
}
part = (int)simple_strtoul(++ep, NULL, 16);
}
PRINTF("Using device %s%d, partition %d\n", argv[1], dev, part);
if (part != 0) {
if (get_partition_info (dev_desc, part, &info)) {
printf ("** Bad partition %d **\n", part);
return 1;
}
if (strncmp((char *)info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) {
printf ("** Invalid partition type \"%.32s\""
" (expect \"" BOOT_PART_TYPE "\")\n",
info.type);
return 1;
}
printf ("Loading file \"%s\" "
"from %s device %d:%d (%.32s)\n",
filename,
argv[1], dev, part, info.name);
} else {
printf ("Loading file \"%s\" from %s device %d\n",
filename, argv[1], dev);
}
if ((part_length = ext2fs_set_blk_dev(dev_desc, part)) == 0) {
printf ("** Bad partition - %s %d:%d **\n", argv[1], dev, part);
ext2fs_close();
return 1;
}
if (!ext2fs_mount(part_length)) {
printf ("** Bad ext2 partition or disk - %s %d:%d **\n",
argv[1], dev, part);
ext2fs_close();
return 1;
}
filelen = ext2fs_open(filename);
if (filelen < 0) {
printf("** File not found %s\n", filename);
ext2fs_close();
return 1;
}
if ((count < filelen) && (count != 0)) {
filelen = count;
}
if (ext2fs_read((char *)addr, filelen) != filelen) {
printf("** Unable to read \"%s\" from %s %d:%d **\n",
filename, argv[1], dev, part);
ext2fs_close();
return 1;
}
ext2fs_close();
/* Loading ok, update default load address */
load_addr = addr;
printf ("%d bytes read\n", filelen);
sprintf(buf, "%X", filelen);
setenv("filesize", buf);
if (do_ext_load(cmdtp, flag, argc, argv))
return -1;
return 0;
}
U_BOOT_CMD(
ext2ls, 4, 1, do_ext2ls,
"list files in a directory (default /)",
"<interface> <dev[:part]> [directory]\n"
" - list files from 'dev' on 'interface' in a 'directory'"
);
U_BOOT_CMD(
ext2load, 6, 0, do_ext2load,
"load binary file from a Ext2 filesystem",
......
/*
* (C) Copyright 2011 - 2012 Samsung Electronics
* EXT4 filesystem implementation in Uboot by
* Uma Shankar <uma.shankar@samsung.com>
* Manjunatha C Achar <a.manjunatha@samsung.com>
*
* Ext4fs support
* made from existing cmd_ext2.c file of Uboot
*
* (C) Copyright 2004
* esd gmbh <www.esd-electronics.com>
* Reinhard Arlt <reinhard.arlt@esd-electronics.com>
*
* made from cmd_reiserfs by
*
* (C) Copyright 2003 - 2004
* Sysgo Real-Time Solutions, AG <www.elinos.com>
* Pavel Bartusek <pba@sysgo.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*/
/*
* Changelog:
* 0.1 - Newly created file for ext4fs support. Taken from cmd_ext2.c
* file in uboot. Added ext4fs ls load and write support.
*/
#include <common.h>
#include <part.h>
#include <config.h>
#include <command.h>
#include <image.h>
#include <linux/ctype.h>
#include <asm/byteorder.h>
#include <ext_common.h>
#include <ext4fs.h>
#include <linux/stat.h>
#include <malloc.h>
#if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE)
#include <usb.h>
#endif
#if !defined(CONFIG_DOS_PARTITION) && !defined(CONFIG_EFI_PARTITION)
#error DOS or EFI partition support must be selected
#endif
uint64_t total_sector;
uint64_t part_offset;
#if defined(CONFIG_CMD_EXT4_WRITE)
static uint64_t part_size;
static uint16_t cur_part = 1;
#endif
#define DOS_PART_MAGIC_OFFSET 0x1fe
#define DOS_FS_TYPE_OFFSET 0x36
#define DOS_FS32_TYPE_OFFSET 0x52
int do_ext4_load(cmd_tbl_t *cmdtp, int flag, int argc,
char *const argv[])
{
if (do_ext_load(cmdtp, flag, argc, argv))
return -1;
return 0;
}
int do_ext4_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
if (do_ext_ls(cmdtp, flag, argc, argv))
return -1;
return 0;
}
#if defined(CONFIG_CMD_EXT4_WRITE)
static int ext4_register_device(block_dev_desc_t *dev_desc, int part_no)
{
unsigned char buffer[SECTOR_SIZE];
disk_partition_t info;
if (!dev_desc->block_read)
return -1;
/* check if we have a MBR (on floppies we have only a PBR) */
if (dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *) buffer) != 1) {
printf("** Can't read from device %d **\n", dev_desc->dev);
return -1;
}
if (buffer[DOS_PART_MAGIC_OFFSET] != 0x55 ||
buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) {
/* no signature found */
return -1;
}
/* First we assume there is a MBR */
if (!get_partition_info(dev_desc, part_no, &info)) {
part_offset = info.start;
cur_part = part_no;
part_size = info.size;
} else if ((strncmp((char *)&buffer[DOS_FS_TYPE_OFFSET],
"FAT", 3) == 0) || (strncmp((char *)&buffer
[DOS_FS32_TYPE_OFFSET],
"FAT32", 5) == 0)) {
/* ok, we assume we are on a PBR only */
cur_part = 1;
part_offset = 0;
} else {
printf("** Partition %d not valid on device %d **\n",
part_no, dev_desc->dev);
return -1;
}
return 0;
}
int do_ext4_write(cmd_tbl_t *cmdtp, int flag, int argc,
char *const argv[])
{
const char *filename = "/";
int part_length;
unsigned long part = 1;
int dev;
char *ep;
unsigned long ram_address;
unsigned long file_size;
disk_partition_t info;
struct ext_filesystem *fs;
if (argc < 6)
return cmd_usage(cmdtp);
dev = (int)simple_strtoul(argv[2], &ep, 16);
ext4_dev_desc = get_dev(argv[1], dev);
if (ext4_dev_desc == NULL) {
printf("Block device %s %d not supported\n", argv[1], dev);
return 1;
}
if (init_fs(ext4_dev_desc))
return 1;
fs = get_fs();
if (*ep) {
if (*ep != ':') {
puts("Invalid boot device, use `dev[:part]'\n");
goto fail;
}
part = simple_strtoul(++ep, NULL, 16);
}
/* get the filename */
filename = argv[3];
/* get the address in hexadecimal format (string to int) */
ram_address = simple_strtoul(argv[4], NULL, 16);
/* get the filesize in base 10 format */
file_size = simple_strtoul(argv[5], NULL, 10);
/* set the device as block device */
part_length = ext4fs_set_blk_dev(fs->dev_desc, part);
if (part_length == 0) {
printf("Bad partition - %s %d:%lu\n", argv[1], dev, part);
goto fail;
}
/* register the device and partition */
if (ext4_register_device(fs->dev_desc, part) != 0) {
printf("Unable to use %s %d:%lu for fattable\n",
argv[1], dev, part);
goto fail;
}
/* get the partition information */
if (!get_partition_info(fs->dev_desc, part, &info)) {
total_sector = (info.size * info.blksz) / SECTOR_SIZE;
fs->total_sect = total_sector;
} else {
printf("error : get partition info\n");
goto fail;
}
/* mount the filesystem */
if (!ext4fs_mount(part_length)) {
printf("Bad ext4 partition %s %d:%lu\n", argv[1], dev, part);
goto fail;
}
/* start write */
if (ext4fs_write(filename, (unsigned char *)ram_address, file_size)) {
printf("** Error ext4fs_write() **\n");
goto fail;
}
ext4fs_close();
deinit_fs(fs->dev_desc);
return 0;
fail:
ext4fs_close();
deinit_fs(fs->dev_desc);
return 1;
}
U_BOOT_CMD(ext4write, 6, 1, do_ext4_write,
"create a file in the root directory",
"<interface> <dev[:part]> [Absolute filename path] [Address] [sizebytes]\n"
" - create a file in / directory");
#endif
U_BOOT_CMD(ext4ls, 4, 1, do_ext4_ls,
"list files in a directory (default /)",
"<interface> <dev[:part]> [directory]\n"
" - list files from 'dev' on 'interface' in a 'directory'");
U_BOOT_CMD(ext4load, 6, 0, do_ext4_load,
"load binary file from a Ext4 filesystem",
"<interface> <dev[:part]> [addr] [filename] [bytes]\n"
" - load binary file 'filename' from 'dev' on 'interface'\n"
" to address 'addr' from ext4 filesystem");
/*
* (C) Copyright 2011 - 2012 Samsung Electronics
* EXT2/4 filesystem implementation in Uboot by
* Uma Shankar <uma.shankar@samsung.com>
* Manjunatha C Achar <a.manjunatha@samsung.com>
*
* Ext4fs support
* made from existing cmd_ext2.c file of Uboot
*
* (C) Copyright 2004
* esd gmbh <www.esd-electronics.com>
* Reinhard Arlt <reinhard.arlt@esd-electronics.com>
*
* made from cmd_reiserfs by
*
* (C) Copyright 2003 - 2004
* Sysgo Real-Time Solutions, AG <www.elinos.com>
* Pavel Bartusek <pba@sysgo.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*/
/*
* Changelog:
* 0.1 - Newly created file for ext4fs support. Taken from cmd_ext2.c
* file in uboot. Added ext4fs ls load and write support.
*/
#include <common.h>
#include <part.h>
#include <config.h>
#include <command.h>
#include <image.h>
#include <linux/ctype.h>
#include <asm/byteorder.h>
#include <ext_common.h>
#include <ext4fs.h>
#include <linux/stat.h>
#include <malloc.h>
#if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE)
#include <usb.h>
#endif
#if !defined(CONFIG_DOS_PARTITION) && !defined(CONFIG_EFI_PARTITION)
#error DOS or EFI partition support must be selected
#endif
#define DOS_PART_MAGIC_OFFSET 0x1fe
#define DOS_FS_TYPE_OFFSET 0x36
#define DOS_FS32_TYPE_OFFSET 0x52
int do_ext_load(cmd_tbl_t *cmdtp, int flag, int argc,
char *const argv[])
{
char *filename = NULL;
char *ep;
int dev;
unsigned long part = 1;
ulong addr = 0;
ulong part_length;
int filelen;
disk_partition_t info;
struct ext_filesystem *fs;
char buf[12];
unsigned long count;
const char *addr_str;
count = 0;
addr = simple_strtoul(argv[3], NULL, 16);
filename = getenv("bootfile");
switch (argc) {
case 3:
addr_str = getenv("loadaddr");
if (addr_str != NULL)
addr = simple_strtoul(addr_str, NULL, 16);
else
addr = CONFIG_SYS_LOAD_ADDR;
break;
case 4:
break;
case 5:
filename = argv[4];
break;
case 6:
filename = argv[4];
count = simple_strtoul(argv[5], NULL, 16);
break;
default:
return cmd_usage(cmdtp);
}
if (!filename) {
puts("** No boot file defined **\n");
return 1;
}
dev = (int)simple_strtoul(argv[2], &ep, 16);
ext4_dev_desc = get_dev(argv[1], dev);
if (ext4_dev_desc == NULL) {
printf("** Block device %s %d not supported\n", argv[1], dev);
return 1;
}
if (init_fs(ext4_dev_desc))
return 1;
fs = get_fs();
if (*ep) {
if (*ep != ':') {
puts("** Invalid boot device, use `dev[:part]' **\n");
goto fail;
}
part = simple_strtoul(++ep, NULL, 16);
}
if (part != 0) {
if (get_partition_info(fs->dev_desc, part, &info)) {
printf("** Bad partition %lu **\n", part);
goto fail;
}
if (strncmp((char *)info.type, BOOT_PART_TYPE,
strlen(BOOT_PART_TYPE)) != 0) {
printf("** Invalid partition type \"%s\""
" (expect \"" BOOT_PART_TYPE "\")\n", info.type);
goto fail;
}
printf("Loading file \"%s\" "
"from %s device %d:%lu %s\n",
filename, argv[1], dev, part, info.name);
} else {
printf("Loading file \"%s\" from %s device %d\n",
filename, argv[1], dev);
}
part_length = ext4fs_set_blk_dev(fs->dev_desc, part);
if (part_length == 0) {
printf("**Bad partition - %s %d:%lu **\n", argv[1], dev, part);
ext4fs_close();
goto fail;
}
if (!ext4fs_mount(part_length)) {
printf("** Bad ext2 partition or disk - %s %d:%lu **\n",
argv[1], dev, part);
ext4fs_close();
goto fail;
}
filelen = ext4fs_open(filename);
if (filelen < 0) {
printf("** File not found %s\n", filename);
ext4fs_close();
goto fail;
}
if ((count < filelen) && (count != 0))
filelen = count;
if (ext4fs_read((char *)addr, filelen) != filelen) {
printf("** Unable to read \"%s\" from %s %d:%lu **\n",
filename, argv[1], dev, part);
ext4fs_close();
goto fail;
}
ext4fs_close();
deinit_fs(fs->dev_desc);
/* Loading ok, update default load address */
load_addr = addr;
printf("%d bytes read\n", filelen);
sprintf(buf, "%X", filelen);
setenv("filesize", buf);
return 0;
fail:
deinit_fs(fs->dev_desc);
return 1;
}
int do_ext_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
const char *filename = "/";
int dev;
unsigned long part = 1;
char *ep;
struct ext_filesystem *fs;
int part_length;
if (argc < 3)
return cmd_usage(cmdtp);
dev = (int)simple_strtoul(argv[2], &ep, 16);
ext4_dev_desc = get_dev(argv[1], dev);
if (ext4_dev_desc == NULL) {
printf("\n** Block device %s %d not supported\n", argv[1], dev);
return 1;
}
if (init_fs(ext4_dev_desc))
return 1;
fs = get_fs();
if (*ep) {
if (*ep != ':') {
puts("\n** Invalid boot device, use `dev[:part]' **\n");
goto fail;
}
part = simple_strtoul(++ep, NULL, 16);
}
if (argc == 4)
filename = argv[3];
part_length = ext4fs_set_blk_dev(fs->dev_desc, part);
if (part_length == 0) {
printf("** Bad partition - %s %d:%lu **\n", argv[1], dev, part);
ext4fs_close();
goto fail;
}
if (!ext4fs_mount(part_length)) {
printf("** Bad ext2 partition or disk - %s %d:%lu **\n",
argv[1], dev, part);
ext4fs_close();
goto fail;
}
if (ext4fs_ls(filename)) {
printf("** Error extfs_ls() **\n");
ext4fs_close();
goto fail;
};
ext4fs_close();
deinit_fs(fs->dev_desc);
return 0;
fail:
deinit_fs(fs->dev_desc);
return 1;
}
This patch series adds support for ext4 ls,load and write features in uboot
Journaling is supported for write feature.
To Enable ext2 ls and load commands, modify the board specific config file with
#define CONFIG_CMD_EXT2
To Enable ext4 ls and load commands, modify the board specific config file with
#define CONFIG_CMD_EXT4
To enable ext4 write command, modify the board specific config file with
#define CONFIG_CMD_EXT4
#define CONFIG_CMD_EXT4_WRITE
Steps to test:
1. After applying the patch, ext4 specific commands can be seen
in the boot loader prompt using
UBOOT #help
ext4load- load binary file from a Ext4 file system
ext4ls - list files in a directory (default /)
ext4write- create a file in ext4 formatted partition
2. To list the files in ext4 formatted partition, execute
ext4ls <interface> <dev[:part]> [directory]
For example:
UBOOT #ext4ls mmc 0:5 /usr/lib
3. To read and load a file from an ext4 formatted partition to RAM, execute
ext4load <interface> <dev[:part]> [addr] [filename] [bytes]
For example:
UBOOT #ext4load mmc 2:2 0x30007fc0 uImage
4. To write a file to a ext4 formatted partition.
a) First load a file to RAM at a particular address for example 0x30007fc0.
Now execute ext4write command
ext4write <interface> <dev[:part]> [filename] [Address] [sizebytes]
For example:
UBOOT #ext4write mmc 2:2 /boot/uImage 0x30007fc0 6183120
(here 6183120 is the size of the file to be written)
Note: Absolute path is required for the file to be written
References :
-- ext4 implementation in Linux Kernel
-- Uboot existing ext2 load and ls implementation
-- Journaling block device JBD2 implementation in linux Kernel
......@@ -23,7 +23,10 @@
#
subdirs-$(CONFIG_CMD_CRAMFS) := cramfs
subdirs-$(CONFIG_CMD_EXT2) += ext2
subdirs-$(CONFIG_CMD_EXT4) += ext4
ifndef CONFIG_CMD_EXT4
subdirs-$(CONFIG_CMD_EXT2) += ext4
endif
subdirs-$(CONFIG_CMD_FAT) += fat
subdirs-$(CONFIG_CMD_FDOS) += fdos
subdirs-$(CONFIG_CMD_JFFS2) += jffs2
......
/*
* (C) Copyright 2004
* esd gmbh <www.esd-electronics.com>
* Reinhard Arlt <reinhard.arlt@esd-electronics.com>
*
* based on code of fs/reiserfs/dev.c by
*
* (C) Copyright 2003 - 2004
* Sysgo AG, <www.elinos.com>, Pavel Bartusek <pba@sysgo.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <common.h>
#include <config.h>
#include <ext2fs.h>
static block_dev_desc_t *ext2fs_block_dev_desc;
static disk_partition_t part_info;
int ext2fs_set_blk_dev(block_dev_desc_t *rbdd, int part)
{
ext2fs_block_dev_desc = rbdd;
if (part == 0) {
/* disk doesn't use partition table */
part_info.start = 0;
part_info.size = rbdd->lba;
part_info.blksz = rbdd->blksz;
} else {
if (get_partition_info
(ext2fs_block_dev_desc, part, &part_info)) {
return 0;
}
}
return part_info.size;
}
int ext2fs_devread(int sector, int byte_offset, int byte_len, char *buf)
{
ALLOC_CACHE_ALIGN_BUFFER(char, sec_buf, SECTOR_SIZE);
unsigned sectors;
/*
* Check partition boundaries
*/
if ((sector < 0) ||
((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS)) >=
part_info.size)) {
/* errnum = ERR_OUTSIDE_PART; */
printf(" ** %s read outside partition sector %d\n",
__func__,
sector);
return 0;
}
/*
* Get the read to the beginning of a partition.
*/
sector += byte_offset >> SECTOR_BITS;
byte_offset &= SECTOR_SIZE - 1;
debug(" <%d, %d, %d>\n", sector, byte_offset, byte_len);
if (ext2fs_block_dev_desc == NULL) {
printf(" ** %s Invalid Block Device Descriptor (NULL)\n",
__func__);
return 0;
}
if (byte_offset != 0) {
/* read first part which isn't aligned with start of sector */
if (ext2fs_block_dev_desc->
block_read(ext2fs_block_dev_desc->dev,
part_info.start + sector, 1,
(unsigned long *) sec_buf) != 1) {
printf(" ** %s read error **\n", __func__);
return 0;
}
memcpy(buf, sec_buf + byte_offset,
min(SECTOR_SIZE - byte_offset, byte_len));
buf += min(SECTOR_SIZE - byte_offset, byte_len);
byte_len -= min(SECTOR_SIZE - byte_offset, byte_len);
sector++;
}
/* read sector aligned part */
sectors = byte_len / SECTOR_SIZE;
if (sectors > 0) {
if (ext2fs_block_dev_desc->block_read(
ext2fs_block_dev_desc->dev,
part_info.start + sector,
sectors,
(unsigned long *) buf) != sectors) {
printf(" ** %s read error - block\n", __func__);
return 0;
}
buf += sectors * SECTOR_SIZE;
byte_len -= sectors * SECTOR_SIZE;
sector += sectors;
}
if (byte_len != 0) {
/* read rest of data which are not in whole sector */
if (ext2fs_block_dev_desc->
block_read(ext2fs_block_dev_desc->dev,
part_info.start + sector, 1,
(unsigned long *) sec_buf) != 1) {
printf(" ** %s read error - last part\n", __func__);
return 0;
}
memcpy(buf, sec_buf, byte_len);
}
return 1;
}
此差异已折叠。
......@@ -27,15 +27,18 @@
include $(TOPDIR)/config.mk
LIB = $(obj)libext2fs.o
LIB = $(obj)libext4fs.o
AOBJS =
COBJS-$(CONFIG_CMD_EXT2) := ext2fs.o dev.o
COBJS-$(CONFIG_CMD_EXT4) := ext4fs.o ext4_common.o dev.o
ifndef CONFIG_CMD_EXT4
COBJS-$(CONFIG_CMD_EXT2) := ext4fs.o ext4_common.o dev.o
endif
COBJS-$(CONFIG_CMD_EXT4_WRITE) += ext4_journal.o crc16.o
SRCS := $(AOBJS:.o=.S) $(COBJS-y:.o=.c)
OBJS := $(addprefix $(obj),$(AOBJS) $(COBJS-y))
#CPPFLAGS +=
all: $(LIB) $(AOBJS)
......
/*
* crc16.c
*
* This source code is licensed under the GNU General Public License,
* Version 2. See the file COPYING for more details.
*/
#include <common.h>
#include <asm/byteorder.h>
#include <linux/stat.h>
#include "crc16.h"
/** CRC table for the CRC-16. The poly is 0x8005 (x16 + x15 + x2 + 1) */
static __u16 const crc16_table[256] = {
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
};
/**
* Compute the CRC-16 for the data buffer
*/
unsigned int ext2fs_crc16(unsigned int crc,
const void *buffer, unsigned int len)
{
const unsigned char *cp = buffer;
while (len--)
crc = (((crc >> 8) & 0xffU) ^
crc16_table[(crc ^ *cp++) & 0xffU]) & 0x0000ffffU;
return crc;
}
/*
* crc16.h - CRC-16 routine
* Implements the standard CRC-16:
* Width 16
* Poly 0x8005 (x16 + x15 + x2 + 1)
* Init 0
*
* Copyright (c) 2005 Ben Gardner <bgardner@wabtec.com>
* This source code is licensed under the GNU General Public License,
* Version 2. See the file COPYING for more details.
*/
#ifndef __CRC16_H
#define __CRC16_H
extern unsigned int ext2fs_crc16(unsigned int crc,
const void *buffer, unsigned int len);
#endif
/*
* (C) Copyright 2011 - 2012 Samsung Electronics
* EXT4 filesystem implementation in Uboot by
* Uma Shankar <uma.shankar@samsung.com>
* Manjunatha C Achar <a.manjunatha@samsung.com>
*
* made from existing ext2/dev.c file of Uboot
* (C) Copyright 2004
* esd gmbh <www.esd-electronics.com>
* Reinhard Arlt <reinhard.arlt@esd-electronics.com>
*
* based on code of fs/reiserfs/dev.c by
*
* (C) Copyright 2003 - 2004
* Sysgo AG, <www.elinos.com>, Pavel Bartusek <pba@sysgo.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
/*
* Changelog:
* 0.1 - Newly created file for ext4fs support. Taken from
* fs/ext2/dev.c file in uboot.
*/
#include <common.h>
#include <config.h>
#include <ext_common.h>
static block_dev_desc_t *ext4fs_block_dev_desc;
static disk_partition_t part_info;
int ext4fs_set_blk_dev(block_dev_desc_t *rbdd, int part)
{
ext4fs_block_dev_desc = rbdd;
if (part == 0) {
/* disk doesn't use partition table */
part_info.start = 0;
part_info.size = rbdd->lba;
part_info.blksz = rbdd->blksz;
} else {
if (get_partition_info(ext4fs_block_dev_desc,
part, &part_info))
return 0;
}
return part_info.size;
}
int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf)
{
ALLOC_CACHE_ALIGN_BUFFER(char, sec_buf, SECTOR_SIZE);
unsigned block_len;
/* Check partition boundaries */
if ((sector < 0)
|| ((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS)) >=
part_info.size)) {
printf("%s read outside partition %d\n", __func__, sector);
return 0;
}
/* Get the read to the beginning of a partition */
sector += byte_offset >> SECTOR_BITS;
byte_offset &= SECTOR_SIZE - 1;
debug(" <%d, %d, %d>\n", sector, byte_offset, byte_len);
if (ext4fs_block_dev_desc == NULL) {
printf("** Invalid Block Device Descriptor (NULL)\n");
return 0;
}
if (byte_offset != 0) {
/* read first part which isn't aligned with start of sector */
if (ext4fs_block_dev_desc->
block_read(ext4fs_block_dev_desc->dev,
part_info.start + sector, 1,
(unsigned long *) sec_buf) != 1) {
printf(" ** ext2fs_devread() read error **\n");
return 0;
}
memcpy(buf, sec_buf + byte_offset,
min(SECTOR_SIZE - byte_offset, byte_len));
buf += min(SECTOR_SIZE - byte_offset, byte_len);
byte_len -= min(SECTOR_SIZE - byte_offset, byte_len);
sector++;
}
if (byte_len == 0)
return 1;
/* read sector aligned part */
block_len = byte_len & ~(SECTOR_SIZE - 1);
if (block_len == 0) {
ALLOC_CACHE_ALIGN_BUFFER(u8, p, SECTOR_SIZE);
block_len = SECTOR_SIZE;
ext4fs_block_dev_desc->block_read(ext4fs_block_dev_desc->dev,
part_info.start + sector,
1, (unsigned long *)p);
memcpy(buf, p, byte_len);
return 1;
}
if (ext4fs_block_dev_desc->block_read(ext4fs_block_dev_desc->dev,
part_info.start + sector,
block_len / SECTOR_SIZE,
(unsigned long *) buf) !=
block_len / SECTOR_SIZE) {
printf(" ** %s read error - block\n", __func__);
return 0;
}
block_len = byte_len & ~(SECTOR_SIZE - 1);
buf += block_len;
byte_len -= block_len;
sector += block_len / SECTOR_SIZE;
if (byte_len != 0) {
/* read rest of data which are not in whole sector */
if (ext4fs_block_dev_desc->
block_read(ext4fs_block_dev_desc->dev,
part_info.start + sector, 1,
(unsigned long *) sec_buf) != 1) {
printf("* %s read error - last part\n", __func__);
return 0;
}
memcpy(buf, sec_buf, byte_len);
}
return 1;
}
此差异已折叠。
/*
* (C) Copyright 2011 - 2012 Samsung Electronics
* EXT4 filesystem implementation in Uboot by
* Uma Shankar <uma.shankar@samsung.com>
* Manjunatha C Achar <a.manjunatha@samsung.com>
*
* ext4ls and ext4load : based on ext2 ls load support in Uboot.
*
* (C) Copyright 2004
* esd gmbh <www.esd-electronics.com>
* Reinhard Arlt <reinhard.arlt@esd-electronics.com>
*
* based on code from grub2 fs/ext2.c and fs/fshelp.c by
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
*
* ext4write : Based on generic ext4 protocol.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __EXT4_COMMON__
#define __EXT4_COMMON__
#include <ext_common.h>
#include <ext4fs.h>
#include <malloc.h>
#include <asm/errno.h>
#if defined(CONFIG_CMD_EXT4_WRITE)
#include "ext4_journal.h"
#include "crc16.h"
#endif
#define YES 1
#define NO 0
#define TRUE 1
#define FALSE 0
#define RECOVER 1
#define SCAN 0
#define S_IFLNK 0120000 /* symbolic link */
#define BLOCK_NO_ONE 1
#define SUPERBLOCK_SECTOR 2
#define SUPERBLOCK_SIZE 1024
#define F_FILE 1
static inline void *zalloc(size_t size)
{
void *p = memalign(ARCH_DMA_MINALIGN, size);
memset(p, 0, size);
return p;
}
extern unsigned long part_offset;
int ext4fs_read_inode(struct ext2_data *data, int ino,
struct ext2_inode *inode);
int ext4fs_read_file(struct ext2fs_node *node, int pos,
unsigned int len, char *buf);
int ext4fs_find_file(const char *path, struct ext2fs_node *rootnode,
struct ext2fs_node **foundnode, int expecttype);
int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name,
struct ext2fs_node **fnode, int *ftype);
#if defined(CONFIG_CMD_EXT4_WRITE)
uint32_t ext4fs_div_roundup(uint32_t size, uint32_t n);
int ext4fs_checksum_update(unsigned int i);
int ext4fs_get_parent_inode_num(const char *dirname, char *dname, int flags);
void ext4fs_update_parent_dentry(char *filename, int *p_ino, int file_type);
long int ext4fs_get_new_blk_no(void);
int ext4fs_get_new_inode_no(void);
void ext4fs_reset_block_bmap(long int blockno, unsigned char *buffer,
int index);
int ext4fs_set_block_bmap(long int blockno, unsigned char *buffer, int index);
int ext4fs_set_inode_bmap(int inode_no, unsigned char *buffer, int index);
void ext4fs_reset_inode_bmap(int inode_no, unsigned char *buffer, int index);
int ext4fs_iget(int inode_no, struct ext2_inode *inode);
void ext4fs_allocate_blocks(struct ext2_inode *file_inode,
unsigned int total_remaining_blocks,
unsigned int *total_no_of_block);
void put_ext4(uint64_t off, void *buf, uint32_t size);
#endif
#endif
此差异已折叠。
/*
* (C) Copyright 2011 - 2012 Samsung Electronics
* EXT4 filesystem implementation in Uboot by
* Uma Shankar <uma.shankar@samsung.com>
* Manjunatha C Achar <a.manjunatha@samsung.com>
*
* Journal data structures and headers for Journaling feature of ext4
* have been referred from JBD2 (Journaling Block device 2)
* implementation in Linux Kernel.
*
* Written by Stephen C. Tweedie <sct@redhat.com>
*
* Copyright 1998-2000 Red Hat, Inc --- All Rights Reserved
* This file is part of the Linux kernel and is made available under
* the terms of the GNU General Public License, version 2, or at your
* option, any later version, incorporated herein by reference.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __EXT4_JRNL__
#define __EXT4_JRNL__
#define EXT2_JOURNAL_INO 8 /* Journal inode */
#define EXT2_JOURNAL_SUPERBLOCK 0 /* Journal Superblock number */
#define JBD2_FEATURE_COMPAT_CHECKSUM 0x00000001
#define EXT3_JOURNAL_MAGIC_NUMBER 0xc03b3998U
#define TRANSACTION_RUNNING 1
#define TRANSACTION_COMPLETE 0
#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */
#define EXT3_JOURNAL_DESCRIPTOR_BLOCK 1
#define EXT3_JOURNAL_COMMIT_BLOCK 2
#define EXT3_JOURNAL_SUPERBLOCK_V1 3
#define EXT3_JOURNAL_SUPERBLOCK_V2 4
#define EXT3_JOURNAL_REVOKE_BLOCK 5
#define EXT3_JOURNAL_FLAG_ESCAPE 1
#define EXT3_JOURNAL_FLAG_SAME_UUID 2
#define EXT3_JOURNAL_FLAG_DELETED 4
#define EXT3_JOURNAL_FLAG_LAST_TAG 8
/* Maximum entries in 1 journal transaction */
#define MAX_JOURNAL_ENTRIES 100
struct journal_log {
char *buf;
int blknr;
};
struct dirty_blocks {
char *buf;
int blknr;
};
/* Standard header for all descriptor blocks: */
struct journal_header_t {
__u32 h_magic;
__u32 h_blocktype;
__u32 h_sequence;
};
/* The journal superblock. All fields are in big-endian byte order. */
struct journal_superblock_t {
/* 0x0000 */
struct journal_header_t s_header;
/* Static information describing the journal */
__u32 s_blocksize; /* journal device blocksize */
__u32 s_maxlen; /* total blocks in journal file */
__u32 s_first; /* first block of log information */
/* Dynamic information describing the current state of the log */
__u32 s_sequence; /* first commit ID expected in log */
__u32 s_start; /* blocknr of start of log */
/* Error value, as set by journal_abort(). */
__s32 s_errno;
/* Remaining fields are only valid in a version-2 superblock */
__u32 s_feature_compat; /* compatible feature set */
__u32 s_feature_incompat; /* incompatible feature set */
__u32 s_feature_ro_compat; /* readonly-compatible feature set */
/* 0x0030 */
__u8 s_uuid[16]; /* 128-bit uuid for journal */
/* 0x0040 */
__u32 s_nr_users; /* Nr of filesystems sharing log */
__u32 s_dynsuper; /* Blocknr of dynamic superblock copy */
/* 0x0048 */
__u32 s_max_transaction; /* Limit of journal blocks per trans. */
__u32 s_max_trans_data; /* Limit of data blocks per trans. */
/* 0x0050 */
__u32 s_padding[44];
/* 0x0100 */
__u8 s_users[16 * 48]; /* ids of all fs'es sharing the log */
/* 0x0400 */
} ;
struct ext3_journal_block_tag {
uint32_t block;
uint32_t flags;
};
struct journal_revoke_header_t {
struct journal_header_t r_header;
int r_count; /* Count of bytes used in the block */
};
struct revoke_blk_list {
char *content; /* revoke block itself */
struct revoke_blk_list *next;
};
extern struct ext2_data *ext4fs_root;
int ext4fs_init_journal(void);
int ext4fs_log_gdt(char *gd_table);
int ext4fs_check_journal_state(int recovery_flag);
int ext4fs_log_journal(char *journal_buffer, long int blknr);
int ext4fs_put_metadata(char *metadata_buffer, long int blknr);
void ext4fs_update_journal(void);
void ext4fs_dump_metadata(void);
void ext4fs_push_revoke_blk(char *buffer);
void ext4fs_free_journal(void);
void ext4fs_free_revoke_blks(void);
#endif
此差异已折叠。
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
*
* (C) Copyright 2003 Sysgo Real-Time Solutions, AG <www.elinos.com>
* Pavel Bartusek <pba@sysgo.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* An implementation for the Ext2FS filesystem ported from GRUB.
* Some parts of this code (mainly the structures and defines) are
* from the original ext2 fs code, as found in the linux kernel.
*/
#define SECTOR_SIZE 0x200
#define SECTOR_BITS 9
/* Error codes */
typedef enum
{
ERR_NONE = 0,
ERR_BAD_FILENAME,
ERR_BAD_FILETYPE,
ERR_BAD_GZIP_DATA,
ERR_BAD_GZIP_HEADER,
ERR_BAD_PART_TABLE,
ERR_BAD_VERSION,
ERR_BELOW_1MB,
ERR_BOOT_COMMAND,
ERR_BOOT_FAILURE,
ERR_BOOT_FEATURES,
ERR_DEV_FORMAT,
ERR_DEV_VALUES,
ERR_EXEC_FORMAT,
ERR_FILELENGTH,
ERR_FILE_NOT_FOUND,
ERR_FSYS_CORRUPT,
ERR_FSYS_MOUNT,
ERR_GEOM,
ERR_NEED_LX_KERNEL,
ERR_NEED_MB_KERNEL,
ERR_NO_DISK,
ERR_NO_PART,
ERR_NUMBER_PARSING,
ERR_OUTSIDE_PART,
ERR_READ,
ERR_SYMLINK_LOOP,
ERR_UNRECOGNIZED,
ERR_WONT_FIT,
ERR_WRITE,
ERR_BAD_ARGUMENT,
ERR_UNALIGNED,
ERR_PRIVILEGED,
ERR_DEV_NEED_INIT,
ERR_NO_DISK_SPACE,
ERR_NUMBER_OVERFLOW,
MAX_ERR_NUM
} ext2fs_error_t;
extern int ext2fs_set_blk_dev(block_dev_desc_t *rbdd, int part);
extern int ext2fs_ls (const char *dirname);
extern int ext2fs_open (const char *filename);
extern int ext2fs_read (char *buf, unsigned len);
extern int ext2fs_mount (unsigned part_length);
extern int ext2fs_close(void);
/*
* (C) Copyright 2011 - 2012 Samsung Electronics
* EXT4 filesystem implementation in Uboot by
* Uma Shankar <uma.shankar@samsung.com>
* Manjunatha C Achar <a.manjunatha@samsung.com>
*
* Ext4 Extent data structures are taken from original ext4 fs code
* as found in the linux kernel.
*
* Copyright (c) 2003-2006, Cluster File Systems, Inc, info@clusterfs.com
* Written by Alex Tomas <alex@clusterfs.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __EXT4__
#define __EXT4__
#include <ext_common.h>
#define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */
#define EXT4_EXT_MAGIC 0xf30a
#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010
#define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040
#define EXT4_INDIRECT_BLOCKS 12
#define EXT4_BG_INODE_UNINIT 0x0001
#define EXT4_BG_BLOCK_UNINIT 0x0002
#define EXT4_BG_INODE_ZEROED 0x0004
/*
* ext4_inode has i_block array (60 bytes total).
* The first 12 bytes store ext4_extent_header;
* the remainder stores an array of ext4_extent.
*/
/*
* This is the extent on-disk structure.
* It's used at the bottom of the tree.
*/
struct ext4_extent {
__le32 ee_block; /* first logical block extent covers */
__le16 ee_len; /* number of blocks covered by extent */
__le16 ee_start_hi; /* high 16 bits of physical block */
__le32 ee_start_lo; /* low 32 bits of physical block */
};
/*
* This is index on-disk structure.
* It's used at all the levels except the bottom.
*/
struct ext4_extent_idx {
__le32 ei_block; /* index covers logical blocks from 'block' */
__le32 ei_leaf_lo; /* pointer to the physical block of the next *
* level. leaf or next index could be there */
__le16 ei_leaf_hi; /* high 16 bits of physical block */
__u16 ei_unused;
};
/* Each block (leaves and indexes), even inode-stored has header. */
struct ext4_extent_header {
__le16 eh_magic; /* probably will support different formats */
__le16 eh_entries; /* number of valid entries */
__le16 eh_max; /* capacity of store in entries */
__le16 eh_depth; /* has tree real underlying blocks? */
__le32 eh_generation; /* generation of the tree */
};
struct ext_filesystem {
/* Total Sector of partition */
uint64_t total_sect;
/* Block size of partition */
uint32_t blksz;
/* Inode size of partition */
uint32_t inodesz;
/* Sectors per Block */
uint32_t sect_perblk;
/* Group Descriptor Block Number */
uint32_t gdtable_blkno;
/* Total block groups of partition */
uint32_t no_blkgrp;
/* No of blocks required for bgdtable */
uint32_t no_blk_pergdt;
/* Superblock */
struct ext2_sblock *sb;
/* Block group descritpor table */
struct ext2_block_group *gd;
char *gdtable;
/* Block Bitmap Related */
unsigned char **blk_bmaps;
long int curr_blkno;
uint16_t first_pass_bbmap;
/* Inode Bitmap Related */
unsigned char **inode_bmaps;
int curr_inode_no;
uint16_t first_pass_ibmap;
/* Journal Related */
/* Block Device Descriptor */
block_dev_desc_t *dev_desc;
};
extern block_dev_desc_t *ext4_dev_desc;
extern struct ext2_data *ext4fs_root;
extern struct ext2fs_node *ext4fs_file;
#if defined(CONFIG_CMD_EXT4_WRITE)
extern struct ext2_inode *g_parent_inode;
extern int gd_index;
extern int gindex;
int ext4fs_init(void);
void ext4fs_deinit(void);
int ext4fs_filename_check(char *filename);
int ext4fs_write(const char *fname, unsigned char *buffer,
unsigned long sizebytes);
#endif
struct ext_filesystem *get_fs(void);
int init_fs(block_dev_desc_t *dev_desc);
void deinit_fs(block_dev_desc_t *dev_desc);
int ext4fs_open(const char *filename);
int ext4fs_read(char *buf, unsigned len);
int ext4fs_mount(unsigned part_length);
void ext4fs_close(void);
int ext4fs_ls(const char *dirname);
void ext4fs_free_node(struct ext2fs_node *node, struct ext2fs_node *currroot);
int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf);
int ext4fs_set_blk_dev(block_dev_desc_t *rbdd, int part);
long int read_allocated_block(struct ext2_inode *inode, int fileblock);
#endif
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册