From: Stefan E. <se...@us...> - 2002-05-02 15:22:39
|
Update of /cvsroot/blob/blob/include/blob In directory usw-pr-cvs1:/tmp/cvs-serv15918 Added Files: generic_io.h Log Message: - header file for generic io framework --- NEW FILE: generic_io.h --- /* generic_io.h - generic io interface * * Copyright (C) 2002, Stefan Eletzhofer <ste...@el...> * * 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 * * $Id: generic_io.h,v 1.1 2002/05/02 15:22:36 seletz Exp $ */ #ifndef BLOB_GENERIC_IO_H #define BLOB_GENERIC_IO_H 1 /* BLOB io abstraction module ~~~~~~~~~~~~~~~~~~~~~~~~~~ Why do I think that this is necessary? --------------------------------------- Please consider the following scenario: A ARM-Linux powered device gets developed, produced and delivered to many customers. As usual, system updates are necessary at some point in the future. System updates should be fool-proof and easy to perform, w/o JTAG cables, computers and so on. One possible solution: A CF card contains a filesystem on a partition. There are several files on this partition/filesystem: - blob - zImage - initrd.gz - cramfs.img This (special) CF card contains thus all necessary files for a complete system update (or recovery). The end-user of our new arm-powered linux device now only has to plug in the CF card, reset the device and blob does the rest: 1) detect a system update CF card (i.e. searches for a special file or a special magic number) 2) perhaps verifies somehow the contents (md5 sums etc.) 3) reflashes all images stored on the CF card to the internal flash 4) marks the CF card as "already used" somehow (by writing some file, deleting the images, etc. ) 5) reboots the system So, all in all what I want is: - have the internal flash memory partitionized. Each partition has a "sane" name, i.e. "blob", "kernel", "initrd" and so on. - I want to be able to reflash each partition using blob - I want to have several FS options to access my CF card, i.e. FAT fs (easy to use for customers), CRAMFS (code already there), raw TAR file access (uncompressed, code here. useful for updates per tftp and xmodem downloads). - I want to have access to CF cards, network devices (tftp) - I want to have the code modules nicely separated How do I want o archieve this? ------------------------------ For the above scenario to become reality one needs to: - supply several FS access modules (some people want to have a FAT filesystem on the update device, some like cramfs, and some raw TAR archives containing the update images). - provide several different "update devices" i.e. CF cards, memory (i.e. downloaded files), network interfaces (tftp). - provide access to the internal flash memory The code below tries to supply a abstraction layer such that for example the filesystem code does not need to know how to access the update device, the partition code does not need how to access the CF card or the internal flash memory. With this library it should be possible to implement the update scenario in a clean way. [CF Card]--ide cf access-->[Partition code]--partition access--+ | +------------------------------------------------------------+ | +->[FS code]--file access-->[Partition code]-->[flash code] [] are io "drivers". They know how to read/write on their abstraction levels, i.e. the partition "io driver" knows how to read partition data The io drivers are chained, from highest abstraction (file access) down to the lowest abstraction (raw flash read/write, CF IDE reads). */ #define IO_NAME_LEN 32 #define IO_MAX_DRIVER 16 struct _io_def; /* io_init_func - initialize private data * * This function configures the io driver * * driver: the driver struct * init_data: data the driver needs to init * */ typedef int (*io_configure_func)( struct _io_def *driver, void *init_data ); /* read_func - generic io function type * * This function reads data "out" of the driver * * dest: where to write the data to * src: where to read from * amount: how much to read * driver: the driver struct * */ typedef int (*io_read_func)( unsigned char *dest, unsigned char *src, size_t amount, struct _io_def *driver ); /* write_func - generic io function type * * This function writes data "into" the driver * * dest: where to write the data to * src: where to read from * amount: how much to read * driver: the driver struct * */ typedef int (*io_write_func)( unsigned char *dest, unsigned char *src, size_t amount, struct _io_def *driver ); typedef struct _io_def { /* driver subfunctions, see below */ io_configure_func conf; io_read_func read; io_write_func write; /* driver's private data */ void *private_data; /* io size in bytes */ size_t io_size; /* child io driver, if any */ struct _io_def *child_io; /* driver's name */ char name[IO_NAME_LEN]; } io_driver_t; void io_dbg_set( int lvl ); /* io_init - initialize generic io module */ void io_init( void ); /* io_register - register a new io. * * io: the io to register * name: the io's name */ int io_register( io_driver_t *io, char *name ); /* io_configure - configures io driver * * io: the io "driver" * conf_data: the configuration data */ int io_configure( io_driver_t *io, void *conf_data ); /* io_get_byname - get a io by its name * * name: the searched io's name */ io_driver_t *io_get_byname( char *name ); /* io_chain_driver - chain io drivers * * parent: parent driver * new_child: new child driver */ int io_chain_driver( char *parent, char *new_child ); /* io_read - read data using io rd * * dest: destination address * src: source address * amount: amount to read */ int io_read( unsigned char *dest, unsigned char *src, size_t amount, io_driver_t *rd ); /* io_write - write data using io rd * * dest: destination address * src: source address * amount: amount to read */ int io_write( unsigned char *dest, unsigned char *src, size_t amount, io_driver_t *rd ); /* io_copy - copy data * * Copy data from io driver "src" to io driver "dest". Copy * "amount" bytes of data. * * dest: destination io driver * src: source io driver * amount: amount to copy */ int io_copy( io_driver_t *dest, io_driver_t *src, size_t amount ); /* FIXME: static inline functions instead of macros */ #define io_get_name( io ) ((io)->name) #define io_get_size( io ) ((io)->io_size) #define io_get_child( io) ((io)->child_io) /********************************************************************** * RAM io driver */ typedef struct ram_io { u32 start; u32 len; u32 pos; } ram_io_t; int ram_io_init( io_driver_t *io, ram_io_t *ram ); int ram_io_conf( io_driver_t *io, void *conf ); #define BLOB_GENERIC_IO_H 1 #endif |