9
0
Fork 0

svn_rev_270

WIP FS support
This commit is contained in:
Sascha Hauer 2007-07-05 18:01:38 +02:00 committed by Sascha Hauer
parent 4e7505eb8d
commit 112ada667b
13 changed files with 358 additions and 195 deletions

View File

@ -64,7 +64,7 @@ device_initcall(scb9328_devices_init);
static int scb9328_init_env(void)
{
add_env_spec(env_spec);
add_env_spec(env_spec);
return 0;
}

View File

@ -169,11 +169,11 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
return 1;
}
if (spec_str_to_info(argv[1], &mem)) {
printf("-ENOPARSE\n");
return -1;
}
// if (spec_str_to_info(argv[1], &mem)) {
// printf("-ENOPARSE\n");
// return -1;
// }
#warning: FIXME: bootm is broken
addr = mem.start + mem.device->map_base;
SHOW_BOOT_PROGRESS (1);

View File

@ -36,7 +36,7 @@ int do_flerase (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
printf ("Usage:\n%s\n", cmdtp->usage);
return 1;
}
# if 0
if (spec_str_to_info(argv[1], &mem)) {
printf("-ENOPARSE\n");
return 1;
@ -52,7 +52,8 @@ int do_flerase (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
}
dev_erase(mem.device, mem.size, mem.start);
#endif
#warning: do_flerase is broken
return 0;
}
@ -75,12 +76,12 @@ int do_protect (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
printf ("Usage:\n%s\n", cmdtp->usage);
return 1;
}
#if 0
if (spec_str_to_info(argv[2], &mem_info)) {
printf ("-EPARSE\n");
return 1;
}
#endif
// rcode = flash_sect_protect (p, addr_first, addr_last);

View File

@ -34,6 +34,8 @@
#include <malloc.h>
#include <errno.h>
#include <asm-generic/errno.h>
#include <fs.h>
#include <fcntl.h>
#ifdef CMD_MEM_DEBUG
#define PRINTF(fmt,args...) printf (fmt ,##args)
@ -103,53 +105,49 @@ int memory_display(char *addr, ulong offs, ulong nbytes, int size)
int do_mem_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
ulong offs, now;
ulong nbytes = 0x100;
struct memarea_info mem;
int size, r;
ulong start;
int size, r, now;
int ret = 0;
int fd;
if (argc < 2) {
printf ("Usage:\n%s\n", cmdtp->usage);
return 1;
}
if (spec_str_to_info(argv[1], &mem)) {
printf("-ENOPARSE\n");
return -ENODEV;
}
fd = open("/dev/mem", O_RDONLY);
if (fd < 0) {
perror("open");
return 1;
}
if (mem.flags & MEMAREA_SIZE_SPECIFIED)
nbytes = mem.size;
else
nbytes = min((ulong)0x100, mem.size);
if ((size = cmd_get_data_size(argv[0], 4)) < 0)
return -EINVAL;
offs = mem.start;
parse_area_spec(argv[1], &start, &size);
if (size == ~0)
size = 0x100;
do {
now = min(RW_BUF_SIZE, nbytes);
r = dev_read(mem.device, rw_buf, now, offs, RW_SIZE(size));
if (r <= 0) {
now = min(size, RW_BUF_SIZE);
r = read(fd, rw_buf, now);
if (r < 0) {
perror("read");
return r;
}
if (!r)
goto out;
if ((ret = memory_display(rw_buf, offs, r, size)))
return ret;
if ((ret = memory_display(rw_buf, start, r, 1)))
goto out;
if (r < now)
return 0;
nbytes -= now;
offs += now;
} while (nbytes > 0);
start += r;
size -= r;
} while (size);
out:
close(fd);
printf("closed\n");
return 0;
}
#if 0
int do_mem_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
ulong addr, writeval, count;
@ -192,6 +190,14 @@ int do_mem_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
return 0;
}
U_BOOT_CMD(
mw, 4, 0, do_mem_mw,
"mw - memory write (fill)\n",
"[.b, .w, .l] address value [count]\n - write memory\n"
);
#endif
int do_mem_cmp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
ulong addr1, addr2, count, ngood;
@ -260,7 +266,7 @@ int do_mem_cmp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
ngood == 1 ? "" : "s");
return rcode;
}
#if 0
int do_mem_cp ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
ulong count, offset, now;
@ -316,6 +322,63 @@ int do_mem_cp ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
return 0;
}
U_BOOT_CMD(
cp, 4, 0, do_mem_cp,
"cp - memory copy\n",
"[.b, .w, .l] source target count\n - copy memory\n"
);
#endif
int do_cp ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
int r, w, ret = 1;
int src, dst;
src = open(argv[1], O_RDONLY);
if (src < 0) {
perror("open");
return 1;
}
if(creat(argv[2], 0)) {
perror("create");
return 1;
}
dst = open(argv[2], O_WRONLY | O_CREAT);
if ( dst < 0) {
perror("open");
close(src);
return 1;
}
while(1) {
r = read(src, rw_buf, RW_BUF_SIZE);
if (read < 0) {
perror("read");
goto out;
}
if (!r)
break;
w = write(dst, rw_buf, r);
if (w < 0) {
perror("write");
goto out;
}
}
ret = 0;
out:
close(src);
close(dst);
return ret;
}
U_BOOT_CMD(
cp, 4, 0, do_cp,
"cp - memory copy\n",
"[.b, .w, .l] source target count\n - copy memory\n"
);
#ifndef CONFIG_CRC32_VERIFY
int do_mem_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
@ -491,18 +554,6 @@ U_BOOT_CMD(
"[.b, .w, .l] address [# of objects]\n - memory display\n"
);
U_BOOT_CMD(
mw, 4, 0, do_mem_mw,
"mw - memory write (fill)\n",
"[.b, .w, .l] address value [count]\n - write memory\n"
);
U_BOOT_CMD(
cp, 4, 0, do_mem_cp,
"cp - memory copy\n",
"[.b, .w, .l] source target count\n - copy memory\n"
);
U_BOOT_CMD(
cmp, 4, 0, do_mem_cmp,
"cmp - memory compare\n",

View File

@ -29,6 +29,9 @@
#include <asm-generic/errno.h>
#include <driver.h>
#include <net.h>
#include <fs.h>
#include <fcntl.h>
#include <errno.h>
extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
@ -152,7 +155,7 @@ U_BOOT_CMD(
);
#endif /* CONFIG_NET_NFS */
struct memarea_info net_store_mem;
int net_store_fd;
static int
netboot_common (proto_t proto, cmd_tbl_t *cmdtp, int argc, char *argv[])
@ -165,9 +168,10 @@ netboot_common (proto_t proto, cmd_tbl_t *cmdtp, int argc, char *argv[])
return 1;
}
if (spec_str_to_info(argv[1], &net_store_mem)) {
printf("-ENOPARSE\n");
return -ENODEV;
net_store_fd = open(argv[1], O_WRONLY | O_CREAT);
if (net_store_fd < 0) {
perror("open");
return 1;
}
copy_filename (BootFile, argv[2], sizeof(BootFile));

View File

@ -3088,7 +3088,9 @@ void mapset(const unsigned char *set, int code)
void update_ifs_map(void)
{
/* char *ifs and char map[256] are both globals. */
ifs = (uchar *)getenv("IFS");
#warning IFS is broken
// ifs = (uchar *)getenv("IFS");
ifs = NULL;
if (ifs == NULL) ifs=(uchar *)" \t\n";
/* Precompute a list of 'flow through' behavior so it can be treated
* quickly up front. Computation is necessary because of IFS.

View File

@ -294,7 +294,7 @@ static int cramfs_open(struct device_d *_dev, FILE *file, const char *filename)
return -ENOENT;
file->pos = 0;
file->inode = (struct cramfs_inode *)(dev->map_base + offset);
file->inode = dev->map_base + offset;
return 0;
}

101
fs/fs.c
View File

@ -102,10 +102,10 @@ FILE *get_file(void)
int i;
for (i = 3; i < MAX_FILES; i++) {
if (!files[i].used) {
files[i].used = 1;
files[i].no = i;
if (!files[i].in_use) {
memset(&files[i], 0, sizeof(FILE));
files[i].in_use = 1;
files[i].no = i;
return &files[i];
}
}
@ -114,7 +114,47 @@ FILE *get_file(void)
void put_file(FILE *f)
{
files[f->no].used = 0;
files[f->no].in_use = 0;
}
static FILE* get_file_by_pathname(const char *pathname)
{
FILE *f;
f = get_file();
if (!f) {
errno = -EMFILE;
return NULL;
}
if (!strncmp(pathname, "/dev/", 5)) {
f->dev = get_device_by_id(pathname + 5);
}
return f;
}
int creat(const char *pathname, mode_t mode)
{
struct mtab_entry *e;
struct device_d *dev;
struct fs_driver_d *fsdrv;
e = get_mtab_entry_by_path(pathname);
if (!e) {
errno = -ENOENT;
return errno;
}
if (e != mtab)
pathname += strlen(e->path);
dev = e->dev;
fsdrv = (struct fs_driver_d *)dev->driver->type_data;
errno = fsdrv->create(dev, pathname, mode);
return errno;
}
int open(const char *pathname, int flags)
@ -125,16 +165,9 @@ int open(const char *pathname, int flags)
FILE *f;
int ret;
f = get_file();
if (!f) {
errno = -EMFILE;
return errno;
}
f = get_file_by_pathname(pathname);
if (!strncmp(pathname, "/dev/", 5)) {
dev = get_device_by_id(pathname + 5);
f->dev = dev;
} else {
if (!f->dev) {
e = get_mtab_entry_by_path(pathname);
if (!e) {
errno = -ENOENT;
@ -155,7 +188,7 @@ int open(const char *pathname, int flags)
goto out;
}
}
printf("open: %d\n",f->no);
return f->no;
out:
@ -170,21 +203,35 @@ int read(int fd, void *buf, size_t count)
FILE *f = &files[fd];
dev = f->dev;
printf("READ: dev: %p\n",dev);
if (dev->type == DEVICE_TYPE_FS) {
fsdrv = (struct fs_driver_d *)dev->driver->type_data;
errno = fsdrv->read(dev, f, buf, count);
return errno;
} else {
errno = dev->driver->read(dev, buf, count, f->pos, 0); /* FIXME: flags */
if (errno > 0)
f->pos += errno;
return errno;
}
if (errno > 0)
f->pos += errno;
return errno;
}
ssize_t write(int fd, const void *buf, size_t count)
{
return -EROFS;
struct device_d *dev;
struct fs_driver_d *fsdrv;
FILE *f = &files[fd];
dev = f->dev;
printf("WRITE: dev: %p\n",dev);
if (dev->type == DEVICE_TYPE_FS) {
fsdrv = (struct fs_driver_d *)dev->driver->type_data;
errno = fsdrv->write(dev, f, buf, count);
} else {
errno = dev->driver->write(dev, buf, count, f->pos, 0); /* FIXME: flags */
}
if (errno > 0)
f->pos += errno;
return errno;
}
int close(int fd)
@ -194,10 +241,14 @@ int close(int fd)
FILE *f = &files[fd];
dev = f->dev;
fsdrv = (struct fs_driver_d *)dev->driver->type_data;
if (dev->type == DEVICE_TYPE_FS) {
fsdrv = (struct fs_driver_d *)dev->driver->type_data;
errno = fsdrv->close(dev, f);
}
put_file(f);
return fsdrv->close(dev, f);
return errno;
}
int mount (struct device_d *dev, char *fsname, char *path)
@ -368,7 +419,8 @@ int stat(const char *filename, struct stat *s)
struct device_d *dev;
struct fs_driver_d *fsdrv;
struct mtab_entry *e;
char *f = strdup(filename);
char *buf = strdup(filename);
char *f = buf;
memset(s, 0, sizeof(struct stat));
@ -386,9 +438,12 @@ int stat(const char *filename, struct stat *s)
fsdrv = (struct fs_driver_d *)dev->driver->type_data;
if (*f == 0)
f = "/";
errno = fsdrv->stat(dev, f, s);
out:
free(f);
free(buf);
return errno;
}

View File

@ -8,33 +8,38 @@
#include <asm-generic/errno.h>
#include <linux/stat.h>
#define CHUNK_SIZE 512
struct data_d {
char *data;
ulong size;
struct data_d *next;
};
struct node_d {
struct ramfs_inode {
char *name;
struct node_d *next;
struct node_d *child;
struct ramfs_inode *next;
struct ramfs_inode *child;
ulong mode;
struct handle_d *handle;
ulong size;
struct data_d *data;
};
struct ramfs_priv {
struct node_d root;
struct ramfs_inode root;
};
/* ---------------------------------------------------------------*/
struct node_d * __lookup(struct node_d *node, const char *name)
struct ramfs_inode * __lookup(struct ramfs_inode *node, const char *name)
{
// printf("__lookup: %s in %p\n",name, node);
if(node->mode != S_IFDIR)
return NULL;
node = node->child;
if (!node || node->mode != S_IFDIR)
if (!node)
return NULL;
while (node) {
@ -45,7 +50,7 @@ struct node_d * __lookup(struct node_d *node, const char *name)
return NULL;
}
struct node_d* rlookup(struct node_d *node, const char *path)
struct ramfs_inode* rlookup(struct ramfs_inode *node, const char *path)
{
static char *buf;
char *part;
@ -68,14 +73,14 @@ out:
return node;
}
int node_add_child(struct node_d *node, const char *filename, ulong mode)
int node_add_child(struct ramfs_inode *node, const char *filename, ulong mode)
{
struct node_d *new_node = malloc(sizeof(struct node_d));
memset(new_node, 0, sizeof(struct node_d));
struct ramfs_inode *new_node = malloc(sizeof(struct ramfs_inode));
memset(new_node, 0, sizeof(struct ramfs_inode));
new_node->name = strdup(filename);
new_node->mode = mode;
// printf("node_add_child: %p -> %p\n", node, new_node);
printf("node_add_child: %p -> %p\n", node, new_node);
if (!node->child) {
node->child = new_node;
return 0;
@ -92,18 +97,18 @@ int node_add_child(struct node_d *node, const char *filename, ulong mode)
/* ---------------------------------------------------------------*/
int ramfs_create(struct device_d *dev, const char *pathname, ulong mode)
int ramfs_create(struct device_d *dev, const char *pathname, mode_t mode)
{
struct ramfs_priv *priv = dev->priv;
char *path = strdup(pathname);
char *file;
struct node_d *node;
struct ramfs_inode *node;
normalise_path(path);
if (*path == '/')
path++;
// printf("after normalise: %s\n",path);
printf("ramfs create: %s\n",path);
if ((file = strrchr(path, '/'))) {
*file = 0;
@ -118,7 +123,7 @@ int ramfs_create(struct device_d *dev, const char *pathname, ulong mode)
if(__lookup(node, file))
return -EEXIST;
printf("CREATE\n");
return node_add_child(node, file, mode);
}
@ -139,20 +144,87 @@ int ramfs_probe(struct device_d *dev)
priv->root.name = "/";
priv->root.mode = S_IFDIR;
printf("root node: %p\n",&priv->root);
return 0;
}
static int ramfs_open(struct device_d *_dev, FILE *file, const char *filename)
static int ramfs_open(struct device_d *dev, FILE *file, const char *filename)
{
return -ENOENT;
struct ramfs_priv *priv = dev->priv;
struct ramfs_inode *node = rlookup(&priv->root, filename);
if (!node)
return -ENOENT;
file->pos = 0;
file->inode = node;
return 0;
}
static int ramfs_close(struct device_d *dev, FILE *f)
{
return 0;
}
static int ramfs_read(struct device_d *_dev, FILE *f, void *buf, size_t size)
{
return 0;
}
struct data_d *ramfs_get_chunk(void)
{
struct data_d *data = malloc(sizeof(struct data_d));
data->data = malloc(CHUNK_SIZE);
data->next = NULL;
return data;
}
static int ramfs_write(struct device_d *_dev, FILE *f, const void *buf, size_t size)
{
struct ramfs_inode *node = (struct ramfs_inode *)f->inode;
int chunk;
struct data_d *data = node->data;
int ofs;
int outsize = 0;
int now;
chunk = f->pos / CHUNK_SIZE;
printf("%s: wrinting to chunk %d\n", __FUNCTION__, chunk);
if (!node->data)
node->data = ramfs_get_chunk();
while (chunk) {
data = data->next;
chunk--;
}
ofs = f->pos % CHUNK_SIZE;
while (size) {
if (ofs == CHUNK_SIZE) {
printf("get new chunk\n");
data->next = ramfs_get_chunk();
data = data->next;
}
now = min(size, CHUNK_SIZE - ofs);
printf("now: %d data->data: %p buf: %p\n", now, data->data, buf);
memcpy(data->data, buf, now);
size -= now;
buf += now;
ofs += now;
outsize += now;
}
return outsize;
}
struct dir* ramfs_opendir(struct device_d *dev, const char *pathname)
{
struct dir *dir;
struct ramfs_priv *priv = dev->priv;
struct node_d *node = rlookup(&priv->root, pathname);
struct ramfs_inode *node = rlookup(&priv->root, pathname);
printf("opendir: %s\n",pathname);
if (!node)
return NULL;
@ -163,16 +235,18 @@ struct dir* ramfs_opendir(struct device_d *dev, const char *pathname)
if (!dir)
return NULL;
dir->node = node->child;
dir->priv = node->child;
return dir;
}
struct dirent* ramfs_readdir(struct device_d *dev, struct dir *dir)
{
if (dir->node) {
strcpy(dir->d.name, dir->node->name);
dir->node = dir->node->next;
struct ramfs_inode *node = dir->priv;
if (node) {
strcpy(dir->d.name, node->name);
dir->priv = node->next;
return &dir->d;
}
return NULL;
@ -187,8 +261,8 @@ int ramfs_closedir(struct device_d *dev, struct dir *dir)
int ramfs_stat(struct device_d *dev, const char *filename, struct stat *s)
{
struct ramfs_priv *priv = dev->priv;
struct node_d *node = rlookup(&priv->root, filename);
struct ramfs_inode *node = rlookup(&priv->root, filename);
printf("%s: %s node: %p\n",__FUNCTION__, filename, node);
if (!node) {
errno = -ENOENT;
return -ENOENT;
@ -203,6 +277,10 @@ static struct fs_driver_d ramfs_driver = {
.type = FS_TYPE_RAMFS,
.create = ramfs_create,
.open = ramfs_open,
.close = ramfs_close,
.read = ramfs_read,
.write = ramfs_write,
.mkdir = ramfs_mkdir,

View File

@ -10,7 +10,7 @@
#define DEVICE_TYPE_ETHER 1
#define DEVICE_TYPE_STDIO 2
#define DEVICE_TYPE_DRAM 3
#define DEVICE_TYPE_FS 3
#define DEVICE_TYPE_FS 4
#define MAX_DEVICE_TYPE 4
#include <param.h>
@ -50,7 +50,7 @@ struct driver_d {
int (*probe) (struct device_d *);
int (*remove)(struct device_d *);
ssize_t (*read) (struct device_d*, void* buf, size_t count, ulong offset, ulong flags);
ssize_t (*write) (struct device_d*, void* buf, size_t count, ulong offset, ulong flags);
ssize_t (*write) (struct device_d*, const void* buf, size_t count, ulong offset, ulong flags);
ssize_t (*erase) (struct device_d*, size_t count, unsigned long offset);
void (*info) (struct device_d *);

View File

@ -25,11 +25,14 @@ struct dir {
};
typedef struct filep {
struct device_d *dev;
ulong pos;
char used;
struct device_d *dev; /* The device this FILE belongs to */
ulong pos; /* current position in stream */
void *inode; /* private to the filesystem driver */
/* private fields. Mapping between FILE and filedescriptor number */
int no;
void *inode; /* private to the filesystem driver */
char in_use;
} FILE;
#define FS_DRIVER_NO_DEV 1
@ -38,13 +41,13 @@ struct fs_driver_d {
ulong type;
char *name;
int (*probe) (struct device_d *dev);
int (*create)(struct device_d *dev, const char *pathname, ulong type);
int (*mkdir)(struct device_d *dev, const char *pathname);
int (*open)(struct device_d *dev, FILE *f, const char *pathname);
int (*create)(struct device_d *dev, const char *pathname, mode_t mode);
int (*close)(struct device_d *dev, FILE *f);
int (*read)(struct device_d *dev, FILE *f, void *buf, size_t size);
int (*write)(struct device_d *dev, FILE *f, void *buf, size_t size);
int (*write)(struct device_d *dev, FILE *f, const void *buf, size_t size);
struct dir* (*opendir)(struct device_d *dev, const char *pathname);
struct dirent* (*readdir)(struct device_d *dev, struct dir *dir);
@ -64,6 +67,7 @@ struct fs_device_d {
};
int open(const char *pathname, int flags);
int creat(const char *pathname, mode_t mode);
int close(int fd);
int read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);

View File

@ -7,6 +7,7 @@
#include <linux/ctype.h>
#include <errno.h>
#include <asm-generic/errno.h>
#include <fs.h>
int cmd_get_data_size(char* arg, int default_size)
{
@ -33,9 +34,14 @@ int cmd_get_data_size(char* arg, int default_size)
static struct device_d *first_device = NULL;
static struct driver_d *first_driver = NULL;
struct device_d *get_device_by_id(const char *id)
struct device_d *get_device_by_id(const char *_id)
{
struct device_d *d;
char *id, *colon;
id = strdup(_id);
if ((colon = strchr(id, ':')))
*colon = 0;
d = first_device;
@ -45,6 +51,7 @@ struct device_d *get_device_by_id(const char *id)
d = d->next;
}
free(id);
return d;
}
@ -169,7 +176,7 @@ int register_driver(struct driver_d *new_driver)
return 0;
}
static char devicename_from_spec_str_buf[MAX_DRIVER_NAME];
static char devicename_from_spec_str_buf[PATH_MAX];
char *deviceid_from_spec_str(const char *str, char **endp)
{
@ -263,99 +270,59 @@ unsigned long strtoul_suffix(const char *str, char **endp, int base)
return val;
}
/*
* Parse a string representing a memory area and fill in a struct memarea_info.
*/
int spec_str_to_info(const char *str, struct memarea_info *info)
int parse_area_spec(const char *str, ulong *start, ulong *size)
{
char *endp;
memset(info, 0, sizeof(struct memarea_info));
info->device = device_from_spec_str(str, &endp);
if (!info->device) {
printf("unknown device: %s\n", deviceid_from_spec_str(str, NULL));
return -ENODEV;
}
if (!info->device->driver) {
printf("no driver associated to device %s\n",deviceid_from_spec_str(str, NULL));
return -ENODEV;
if (*str == '+') {
/* no beginning given but size so start is 0 */
*start = 0;
*size = strtoul_suffix(str + 1, &endp, 0);
return 0;
}
str = endp;
if (*str == '-') {
/* no beginning given but end, so start is 0 */
*start = 0;
*size = strtoul_suffix(str + 1, &endp, 0) + 1;
return 0;
}
if (!*str) {
/* no area specification given, use whole device */
info->size = info->device->size;
info->end = info->size - 1;
goto out;
}
*start = strtoul_suffix(str, &endp, 0);
if (*str == '+') {
/* no beginning given but size so start is 0 */
info->size = strtoul_suffix(str + 1, &endp, 0);
info->end = info->size - 1;
info->flags = MEMAREA_SIZE_SPECIFIED;
goto out;
}
str = endp;
if (*str == '-') {
/* no beginning given but end, so start is 0 */
info->end = strtoul_suffix(str + 1, &endp, 0);
info->size = info->end + 1;
info->flags = MEMAREA_SIZE_SPECIFIED;
goto out;
}
str = endp;
info->start = strtoul_suffix(str, &endp, 0);
str = endp;
if (info->start >= info->device->size) {
printf("Start address is beyond device\n");
return -1;
}
if (!*str) {
/* beginning given, but no size, pad to the and of the device */
info->end = info->device->size - 1;
info->size = info->end - info->start + 1;
goto out;
}
if (!*str) {
/* beginning given, but no size, assume maximum size */
*size = ~0;
return 0;
}
if (*str == '-') {
/* beginning and end given */
info->end = strtoul_suffix(str + 1, NULL, 0);
info->size = info->end - info->start + 1;
if (info->end < info->start) {
printf("end < start\n");
return -1;
}
info->flags = MEMAREA_SIZE_SPECIFIED;
goto out;
*size = strtoul_suffix(str + 1, NULL, 0) + 1;
return 0;
}
if (*str == '+') {
/* beginning and size given */
info->size = strtoul_suffix(str + 1, NULL, 0);
info->end = info->start + info->size - 1;
info->flags = MEMAREA_SIZE_SPECIFIED;
goto out;
*size = strtoul_suffix(str + 1, NULL, 0);
return 0;
}
out:
/* check for device boundaries */
if (info->end > info->device->size) {
info->end = info->device->size - 1;
info->size = info->end - info->start + 1;
}
#if 0
printf("start: 0x%08x\n",info->start);
printf("size: 0x%08x\n",info->size);
printf("end: 0x%08x\n",info->end);
#endif
return 0;
return -1;
}
int spec_str_to_info(const char *str, struct memarea_info *info)
{
char *endp;
info->device = device_from_spec_str(str, &endp);
if (!info->device) {
printf("unknown device: %s\n", deviceid_from_spec_str(str, NULL));
return -ENODEV;
}
return parse_area_spec(endp, &info->start, &info->size);
}
ssize_t dev_read(struct device_d *dev, void *buf, size_t count, unsigned long offset, ulong flags)

View File

@ -9,6 +9,7 @@
#include <net.h>
#include <driver.h>
#include <clock.h>
#include <fs.h>
#include "tftp.h"
#include "bootp.h"
@ -57,7 +58,7 @@ static int TftpState;
static char default_filename[DEFAULT_NAME_LEN];
static char *tftp_filename;
extern struct memarea_info net_store_mem;
extern int net_store_fd;
static __inline__ void
store_block (unsigned block, uchar * src, unsigned len)
@ -65,7 +66,7 @@ store_block (unsigned block, uchar * src, unsigned len)
ulong offset = block * TFTP_BLOCK_SIZE + TftpBlockWrapOffset;
ulong newsize = offset + len;
dev_write(net_store_mem.device, src, len, net_store_mem.start + offset, 0);
write(net_store_fd, src, len);
if (NetBootFileXferSize < newsize)
NetBootFileXferSize = newsize;