diff --git a/src/core/main.c b/src/core/main.c index 08f6d6a5..260a44b8 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -162,6 +162,7 @@ void initialise ( void ) { MAIN - Kick off routine **************************************************************************/ int main ( void ) { + struct buffer buffer; int skip = 0; /* Print out configuration */ @@ -213,8 +214,15 @@ int main ( void ) { continue; } - /* Boot from the device */ - load ( &dev, load_block ); + /* Load boot file from the device */ + init_buffer ( &buffer, 0x7c00, 0x100 ); + if ( ! load ( &dev, &buffer ) ) { + /* Load (e.g. TFTP failed) */ + printf ( "...load failed\n" ); + continue; + } + + printf ( "Loaded file of size %d\n", buffer.fill ); } diff --git a/src/core/nic.c b/src/core/nic.c index fc8deebe..3909f548 100644 --- a/src/core/nic.c +++ b/src/core/nic.c @@ -282,14 +282,10 @@ static int nic_configure ( struct type_dev *type_dev ) { /* - * Download a file from the specified URL and process it with the - * specified function + * Download a file from the specified URL into the specified buffer * */ -int download_url ( char *url, - int ( * process ) ( unsigned char *data, - unsigned int blocknum, - unsigned int len, int eof ) ) { +int download_url ( char *url, struct buffer *buffer ) { struct protocol *proto; struct sockaddr_in server; char *filename; @@ -303,7 +299,7 @@ int download_url ( char *url, } /* Call protocol's method to download the file */ - return proto->load ( url, &server, filename, process ); + return proto->load ( url, &server, filename, buffer ); } @@ -312,10 +308,7 @@ int download_url ( char *url, /************************************************************************** LOAD - Try to get booted **************************************************************************/ -static int nic_load ( struct type_dev *type_dev, - int ( * process ) ( unsigned char *data, - unsigned int blocknum, - unsigned int size, int eof ) ) { +static int nic_load ( struct type_dev *type_dev, struct buffer *buffer ) { char *kernel; /* Now use TFTP to load file */ @@ -327,12 +320,10 @@ static int nic_load ( struct type_dev *type_dev, #endif : KERNEL_BUF; if ( kernel ) { - download_url(kernel,process); /* We don't return except on error */ - printf("Unable to load file.\n"); + return download_url ( kernel, buffer ); } else { printf("No filename\n"); } - interruptible_sleep(2); /* lay off the server for a while */ return 0; } diff --git a/src/include/dev.h b/src/include/dev.h index 8bf17355..0d0d4d8e 100644 --- a/src/include/dev.h +++ b/src/include/dev.h @@ -3,6 +3,7 @@ #include "stdint.h" #include "string.h" +#include "buffer.h" #include "dhcp.h" /* for dhcp_dev_id */ #include "tables.h" @@ -182,10 +183,7 @@ struct type_driver { struct type_dev *type_dev; /* single instance */ char * ( * describe_device ) ( struct type_dev *type_dev ); int ( * configure ) ( struct type_dev *type_dev ); - int ( * load ) ( struct type_dev *type_dev, - int ( * process ) ( unsigned char *data, - unsigned int blocknum, - unsigned int len, int eof ) ); + int ( * load ) ( struct type_dev *type_dev, struct buffer *buffer ); }; #define __type_driver __attribute__ (( used, __table_section(type_driver,01) )) @@ -277,11 +275,8 @@ static inline int configure ( struct dev *dev ) { return dev->type_driver->configure ( dev->type_dev ); } /* Boot from a device */ -static inline int load ( struct dev *dev, - int ( * process ) ( unsigned char *data, - unsigned int blocknum, - unsigned int len, int eof ) ) { - return dev->type_driver->load ( dev->type_dev, process ); +static inline int load ( struct dev *dev, struct buffer *buffer ) { + return dev->type_driver->load ( dev->type_dev, buffer ); } #endif /* DEV_H */ diff --git a/src/include/proto.h b/src/include/proto.h index 2c157ee4..fb4e4137 100644 --- a/src/include/proto.h +++ b/src/include/proto.h @@ -2,18 +2,14 @@ #define PROTO_H #include "tables.h" +#include "buffer.h" #include "in.h" struct protocol { char *name; in_port_t default_port; - int ( * load ) ( char *url, - struct sockaddr_in *server, - char *file, - int ( * process ) ( unsigned char *data, - unsigned int blocknum, - unsigned int len, - int eof ) ); + int ( * load ) ( char *url, struct sockaddr_in *server, char *file, + struct buffer *buffer ); }; /* diff --git a/src/include/tftp.h b/src/include/tftp.h index 5f129ead..70192067 100644 --- a/src/include/tftp.h +++ b/src/include/tftp.h @@ -2,6 +2,7 @@ #define TFTP_H #include "in.h" +#include "buffer.h" #include "nic.h" #define TFTP_PORT 69 @@ -83,11 +84,7 @@ struct tftpblk_info_t { */ extern int tftp_block ( struct tftpreq_info_t *request, struct tftpblk_info_t *block ); -extern int tftp ( char *url, - struct sockaddr_in *server, - char *file, - int ( * process ) ( unsigned char *data, - unsigned int blocknum, - unsigned int len, int eof ) ); +extern int tftp ( char *url, struct sockaddr_in *server, char *file, + struct buffer *buffer ); #endif /* TFTP_H */ diff --git a/src/proto/tftp.c b/src/proto/tftp.c index c59807d7..6d35e170 100644 --- a/src/proto/tftp.c +++ b/src/proto/tftp.c @@ -144,12 +144,8 @@ int tftp_block ( struct tftpreq_info_t *request, * Download a file via TFTP * */ -int tftp ( char *url __unused, - struct sockaddr_in *server, - char *file, - int ( * process ) ( unsigned char *data, - unsigned int blocknum, - unsigned int len, int eof ) ) { +int tftp ( char *url __unused, struct sockaddr_in *server, char *file, + struct buffer *buffer ) { struct tftpreq_info_t request_data = { .server = server, .name = file, @@ -157,14 +153,18 @@ int tftp ( char *url __unused, }; struct tftpreq_info_t *request = &request_data; struct tftpblk_info_t block; - int rc; + off_t offset = 0; - while ( tftp_block ( request, &block ) ) { + do { + if ( ! tftp_block ( request, &block ) ) + return 0; + if ( ! fill_buffer ( buffer, block.data, offset, block.len ) ) + return 0; + offset += block.len; request = NULL; /* Send request only once */ - rc = process ( block.data, block.block, block.len, block.eof ); - if ( rc <= 0 ) return ( rc ); - } - return 0; + } while ( ! block.eof ); + + return 1; } struct protocol tftp_protocol __default_protocol = {