From eeab840c13613fd6b3f053962939977d559f8224 Mon Sep 17 00:00:00 2001 From: UD2 Date: Sat, 13 Jul 2024 19:15:57 -0700 Subject: [PATCH] use proper FAT_END constant, add kernel update support --- isd.cpp | 68 ++++++++++++++++++++++++++++++++++++++++++++++++---- piecefat.cpp | 6 ++--- piecefat.h | 1 + 3 files changed, 68 insertions(+), 7 deletions(-) diff --git a/isd.cpp b/isd.cpp index 15099df..79c0d27 100644 --- a/isd.cpp +++ b/isd.cpp @@ -18,6 +18,7 @@ static void usage( std::FILE *out ) std::fputs("isd -R filename -- run srf file\n",out); std::fputs("isd -r filename -- download file\n",out); std::fputs("isd -s filename -- upload file\n",out); + std::fputs("isd -k all.img@updater.srf -- update kernel\n",out); std::fputs("isd -v -- show version\n",out); } @@ -90,6 +91,62 @@ static int run_srf_file( n::piece::Device &d, char *fname ) return 0; } +static int update_kernel( n::piece::Device &d, char *arg ) +{ + char *ampersand = strchr(arg, '@'); + if ( ampersand == NULL ){ + return 1; + } + + *ampersand = '\0'; + + const char *ku_path = ampersand + 1; + + char buf[512*1024]; + + FILE *fp = fopen( arg, "rb" ); + + if ( fp == NULL ){ + std::perror("fopen"); + return 1; + } + + struct stat stat_buf; + if ( stat( arg, &stat_buf ) < 0 ) { + std::perror("stat"); + fclose( fp ); + return 1; + } + + size_t len = stat_buf.st_size; + if ( len >= sizeof(buf) ) { + std::fprintf( stderr, "kernel image too large\n" ); + fclose( fp ); + return 1; + } + + if ( fread( buf, 1, len, fp ) != len ) { + std::perror("fread"); + fclose( fp ); + return 1; + } + + fclose( fp ); + + fp = fopen( ku_path, "rb" ); + if ( fp == NULL ){ + std::perror("fopen"); + return 1; + } + + d.setAppStat( n::piece::Device::APP_STOP ); + d.writeMem( 0x102c00, buf, len ); + d.uploadSrf( fp ); + d.setAppStat( n::piece::Device::APP_RUN ); + fclose( fp ); + return 0; +} + static int fs_status( n::piece::Device &d, n::piece::Fs &fs ) { size_t size = fs.getFreeBlockCount(); @@ -100,12 +157,12 @@ static int fs_status( n::piece::Device &d, n::piece::Fs &fs ) int main( int argc, char **argv ) { try { - + n::piece::Device d; n::piece::Fs fs( d ); while ( 1 ) { - int c = getopt( argc, argv, "lr:d:c?hs:fFvR:" ); - + int c = getopt( argc, argv, "lr:d:c?hs:fFvR:k:" ); + switch ( c ) { case 'l': fs.dumpDir(); @@ -143,12 +200,15 @@ int main( int argc, char **argv ) case 'R': return run_srf_file( d, optarg ); + case 'k': + return update_kernel( d, optarg ); + default: usage( stderr ); return 1; } } - + } catch ( const char *err ) { std::fprintf( stderr, "%s\n", err ); return 1; diff --git a/piecefat.cpp b/piecefat.cpp index 0bac608..8dc64c9 100644 --- a/piecefat.cpp +++ b/piecefat.cpp @@ -10,7 +10,7 @@ namespace { void fileNotFound( const char *fname ) { static char tmp[64]; - sprintf( tmp, "%s: file not found", fname ); + snprintf( tmp, sizeof(tmp), "%s: file not found", fname ); throw tmp; } @@ -123,7 +123,7 @@ void Fs::makeChain( uint16_t *pchain, int blkcnt, int next ) uint16_t *fat = master_block_.fat_chain; if ( blkcnt <= 0 ) { - *pchain = MAXFAT+1; + *pchain = FAT_END; return; } @@ -291,7 +291,7 @@ void Fs::format() memset( m->directory, 0, sizeof(m->directory) ); memset( m->fat_chain, 0xff, sizeof(m->fat_chain) ); - m->fat_chain[0] = MAXFAT+1; + m->fat_chain[0] = FAT_END; update(); } diff --git a/piecefat.h b/piecefat.h index 5aa9eeb..2c4c3f8 100644 --- a/piecefat.h +++ b/piecefat.h @@ -16,6 +16,7 @@ class Fs static const int MAXDIR=96; static const int MAXFAT=496; static const uint16_t FAT_FREE=0xffff; + static const uint16_t FAT_END=0xeeee; static const size_t FNAME_LEN=23; struct Directory {