From cc291568f5afe61b266022475b1476a030c9bc88 Mon Sep 17 00:00:00 2001 From: kamkow1 Date: Sat, 21 Mar 2026 15:16:03 +0100 Subject: [PATCH] sdutil Initialize CHS too (some BIOSes dont like it), libfat Add update callback function --- libfat/_fatctx.h | 3 +++ libfat/libfat.c | 19 ++++++++++------ sdutil/Makefile | 1 + sdutil/sdutil.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 70 insertions(+), 9 deletions(-) diff --git a/libfat/_fatctx.h b/libfat/_fatctx.h index 0033340..72f9b30 100644 --- a/libfat/_fatctx.h +++ b/libfat/_fatctx.h @@ -1,6 +1,8 @@ #ifndef _KERNEL_FS_FATFS_CTX_H #define _KERNEL_FS_FATFS_CTX_H +#include + struct fatfs_ctx { FL_FILE _files[FATFS_MAX_OPEN_FILES]; int _filelib_init; @@ -9,6 +11,7 @@ struct fatfs_ctx { struct fat_list _open_file_list; struct fat_list _free_file_list; char device_name[0x100]; + void (*update_cb) (size_t sector, size_t sector_count); }; #endif // _KERNEL_FS_FATFS_CTX_H diff --git a/libfat/libfat.c b/libfat/libfat.c index 0f3656b..0c4fde9 100644 --- a/libfat/libfat.c +++ b/libfat/libfat.c @@ -41,6 +41,9 @@ static int fat_diskio_read (struct fatfs_ctx* ctx, uint32_t sector, uint8_t* buf NULL)) < 0) return 0; + if (ctx->update_cb != NULL) + ctx->update_cb (phys_sector, phys_sector_count); + return 1; } @@ -65,18 +68,20 @@ static int fat_diskio_write (struct fatfs_ctx* ctx, uint32_t sector, uint8_t* bu NULL)) < 0) return 0; + if (ctx->update_cb != NULL) + ctx->update_cb (phys_sector, phys_sector_count); + return 1; } int fat_format_drive (struct fatfs_ctx* ctx, const char* device_key, int fs_type) { - memset (ctx, 0, sizeof (*ctx)); - memcpy (ctx->device_name, device_key, min (sizeof (ctx->device_name) - 1, strlen (device_key))); + memcpy (ctx->device_name, device_key, strlen (device_key)); + + int r = -1; size_t total_size = 0; - device_do (device_key, XDRV_GET_SIZE, &total_size, NULL, NULL, NULL); - - if (total_size == 0) - return -ST_NOT_FOUND; + if ((r = device_do (device_key, XDRV_GET_SIZE, &total_size, NULL, NULL, NULL)) < 0) + return r; size_t sectors = ((total_size + FAT_SECTOR_SIZE) / FAT_SECTOR_SIZE); @@ -84,7 +89,7 @@ int fat_format_drive (struct fatfs_ctx* ctx, const char* device_key, int fs_type ctx->_fs.disk_io.read_media = &fat_diskio_read; ctx->_fs.disk_io.write_media = &fat_diskio_write; - int r = -1; + r = -1; switch (fs_type) { case FS_FAT16: diff --git a/sdutil/Makefile b/sdutil/Makefile index 8306802..23c4adf 100644 --- a/sdutil/Makefile +++ b/sdutil/Makefile @@ -8,6 +8,7 @@ $(eval $(call add_lib,libdebugconsole)) $(eval $(call add_lib,libmalloc)) $(eval $(call add_lib,libinput)) $(eval $(call add_lib,libfat)) +$(eval $(call add_include,libterminal)) cflags += -DPRINTF_INCLUDE_CONFIG_H=1 diff --git a/sdutil/sdutil.c b/sdutil/sdutil.c index 94d0fb0..b2045d3 100644 --- a/sdutil/sdutil.c +++ b/sdutil/sdutil.c @@ -9,6 +9,8 @@ #include #include #include +#include +#include struct dos_pte { uint8_t drive_attrs; @@ -27,6 +29,25 @@ struct dos_mbr { uint8_t valid_sign[2]; } __attribute__ ((packed)); +static void lba_to_chs (uint32_t lba, uint8_t chs[3]) { + uint32_t sectors_per_track = 63; + uint32_t heads = 255; + + uint32_t cylinder = lba / (heads * sectors_per_track); + uint32_t head = (lba / sectors_per_track) % heads; + uint32_t sector = (lba % sectors_per_track) + 1; + + if (cylinder > 1023) { + chs[0] = 254; + chs[1] = 0xFF; + chs[2] = 0xFF; + } else { + chs[0] = (uint8_t)head; + chs[1] = (uint8_t)((sector & 0x3F) | ((cylinder >> 2) & 0xC0)); + chs[2] = (uint8_t)(cylinder & 0xFF); + } +} + static void start_part_dos (void) { char dev_name[64]; memset (dev_name, 0, sizeof (dev_name)); @@ -54,12 +75,23 @@ static void start_part_dos (void) { mbr.ptes[0].start_lba = p0_start_lba; mbr.ptes[0].sector_count = p0_sector_count; + lba_to_chs (p0_start_lba, mbr.ptes[0].chs_start_addr); + lba_to_chs (p0_start_lba + p0_sector_count - 1, mbr.ptes[0].chs_last_sect_addr); + mbr.ptes[1].start_lba = p1_start_lba; mbr.ptes[1].sector_count = p1_sector_count; + lba_to_chs (p1_start_lba, mbr.ptes[1].chs_start_addr); + lba_to_chs (p1_start_lba + p1_sector_count - 1, mbr.ptes[1].chs_last_sect_addr); + mbr.ptes[2].start_lba = p2_start_lba; mbr.ptes[2].sector_count = p2_sector_count; + lba_to_chs (p2_start_lba, mbr.ptes[2].chs_start_addr); + lba_to_chs (p2_start_lba + p2_sector_count - 1, mbr.ptes[2].chs_last_sect_addr); + mbr.ptes[3].start_lba = p3_start_lba; mbr.ptes[3].sector_count = p3_sector_count; + lba_to_chs (p3_start_lba, mbr.ptes[3].chs_start_addr); + lba_to_chs (p3_start_lba + p3_sector_count - 1, mbr.ptes[3].chs_last_sect_addr); mbr.valid_sign[0] = 0x55; mbr.valid_sign[1] = 0xAA; @@ -122,8 +154,24 @@ static void list_part_dos (const char* dev_name) { /* clang-format on */ } +static const char* spinner = "-\\|/"; +static size_t spinner_state = 0; +static size_t sectors_done = 0; + +static void format_update (size_t sector, size_t sector_count) { + (void)sector; + + char spinner_char = spinner[(spinner_state++) % (sizeof (spinner) - 1)]; + mprintf (ANSIQ_CUR_SET_COL (0) ANSIQ_SCR_CLR2LEND "%c %zu", spinner_char, sectors_done); + sectors_done += sector_count; +} + static void format_fat32 (const char* dev_name) { + mprintf ("Formatting device %s!\n", dev_name); + struct fatfs_ctx ctx; + memset (&ctx, 0, sizeof (ctx)); + ctx.update_cb = &format_update; int r = fat_format_drive (&ctx, dev_name, FS_FAT32); @@ -131,7 +179,11 @@ static void format_fat32 (const char* dev_name) { } static void format_fat16 (const char* dev_name) { + mprintf ("Formatting device %s!\n", dev_name); + struct fatfs_ctx ctx; + memset (&ctx, 0, sizeof (ctx)); + ctx.update_cb = &format_update; int r = fat_format_drive (&ctx, dev_name, FS_FAT16); @@ -142,9 +194,9 @@ void app_main (void) { libprocess_self_init (); char commandbuf[32]; - commandbuf[0] = '\0'; + memset (commandbuf, 0, sizeof (commandbuf)); char devnamebuf[64]; - devnamebuf[0] = '\0'; + memset (devnamebuf, 0, sizeof (devnamebuf)); if (env_get (process_get_pgid (), "C", (void*)commandbuf, sizeof (commandbuf)) != ST_OK) { mprintf ("ERROR C=???. No command provided\n");