diff --git a/libstring/src.mk b/libstring/src.mk index a4a67c9..98fb67a 100644 --- a/libstring/src.mk +++ b/libstring/src.mk @@ -1,3 +1,5 @@ -c += string.c +c += string.c \ + strconv.c -o += string.o +o += string.o \ + strconv.o diff --git a/libstring/strconv.c b/libstring/strconv.c new file mode 100644 index 0000000..26f85f7 --- /dev/null +++ b/libstring/strconv.c @@ -0,0 +1,15 @@ +#include + +uint64_t str_to_uint64 (const char* s) { + uint64_t r = 0; + + if (!s) + return 0; + + while (*s >= '0' && *s <= '9') { + r = r * 10 + (*s - '0'); + s++; + } + + return r; +} diff --git a/libstring/strconv.h b/libstring/strconv.h new file mode 100644 index 0000000..fb9c911 --- /dev/null +++ b/libstring/strconv.h @@ -0,0 +1,12 @@ +#ifndef _LIBSTRING_STRCONV_H +#define _LIBSTRING_STRCONV_H + +#include + +#define str_to_uint32(s) ((uint32_t)str_to_uint64 ((s))) +#define str_to_uint16(s) ((uint16_t)str_to_uint64 ((s))) +#define str_to_uint8(s) ((uint8_t)str_to_uint64 ((s))) + +uint64_t str_to_uint64 (const char* s); + +#endif // _LIBSTRING_STRCONV_H diff --git a/sdutil/sdutil.c b/sdutil/sdutil.c index 49e61ec..434926d 100644 --- a/sdutil/sdutil.c +++ b/sdutil/sdutil.c @@ -1,16 +1,99 @@ +#include #include #include #include #include +#include +#include #include #include #define COMMAND_MAX 32 +struct dos_pte { + uint8_t drive_attrs; + uint8_t chs_start_addr[3]; + uint8_t part_type; + uint8_t chs_last_sect_addr[3]; + uint32_t start_lba; + uint32_t sector_count; +} __attribute__ ((packed)); + +struct dos_mbr { + uint8_t boot_code[440]; + uint8_t signature[4]; + uint8_t resv[2]; + struct dos_pte ptes[4]; + uint8_t valid_sign[2]; +} __attribute__ ((packed)); + static void start_part_dos (void) { char dev_name[64]; + struct dos_mbr mbr; + memset (&mbr, 0, sizeof (mbr)); + bool ok = false, write = false; + char confirm_buf[4]; in_stream_read_line ("Device name: ", dev_name, sizeof (dev_name)); + +#define prompt_partition(N) \ + char p##N##_start_lba_str[12], p##N##_sector_cout_str[12]; \ + uint32_t p##N##_start_lba, p##N##_sector_count; \ + mprintf ("\nConfigure parition %d:\n", N); \ + in_stream_read_line ("Start LBA: ", p##N##_start_lba_str, sizeof (p##N##_start_lba_str)); \ + in_stream_read_line ("Sector count: ", p##N##_sector_cout_str, sizeof (p##N##_sector_cout_str)); \ + p##N##_start_lba = str_to_uint32 (p##N##_start_lba_str); \ + p##N##_sector_count = str_to_uint32 (p##N##_sector_cout_str); + + prompt_partition (0); + prompt_partition (1); + prompt_partition (2); + prompt_partition (3); + + mbr.ptes[0].start_lba = p0_start_lba; + mbr.ptes[0].sector_count = p0_sector_count; + mbr.ptes[1].start_lba = p1_start_lba; + mbr.ptes[1].sector_count = p1_sector_count; + mbr.ptes[2].start_lba = p2_start_lba; + mbr.ptes[2].sector_count = p2_sector_count; + mbr.ptes[3].start_lba = p3_start_lba; + mbr.ptes[3].sector_count = p3_sector_count; + + mbr.valid_sign[0] = 0x55; + mbr.valid_sign[1] = 0xAA; + + /* clang-format off */ + mprintf ("\n\n-------------------------------------------------------\n"); + mprintf ("Current configuration (%s):\n", dev_name); + mprintf ("Partition 0: start LBA = %u, sector count = %zu\n",mbr.ptes[0].start_lba, mbr.ptes[0].sector_count); + mprintf ("Partition 1: start LBA = %u, sector count = %zu\n",mbr.ptes[1].start_lba, mbr.ptes[1].sector_count); + mprintf ("Partition 2: start LBA = %u, sector count = %zu\n",mbr.ptes[2].start_lba, mbr.ptes[2].sector_count); + mprintf ("Partition 3: start LBA = %u, sector count = %zu\n",mbr.ptes[3].start_lba, mbr.ptes[3].sector_count); + /* clang-format on */ + + in_stream_read_line ("\nDoes this look plausible? [yes/no]: ", confirm_buf, sizeof (confirm_buf)); + + if (strcmp (confirm_buf, "yes") == 0) { + in_stream_read_line ("\nWrite to device? There's no going back! [yes/no]: ", confirm_buf, + sizeof (confirm_buf)); + + ok = true; + + if (strcmp (confirm_buf, "yes") == 0) { + write = true; + } else { + mprintf ("OK. Canceling\n"); + } + } else { + mprintf ("OK. Canceling\n"); + } + + if (ok && write) { + size_t sector = 0; + size_t sector_count = 1; + int r = device_do (dev_name, XDRV_WRITE, §or, §or_count, &mbr, NULL); + mprintf ("Finished writing. Result: %s (%d)\n", str_status[r < 0 ? -r : r], r); + } } void app_main (void) {