#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]; memset (dev_name, 0, sizeof (dev_name)); struct dos_mbr mbr; memset (&mbr, 0, sizeof (mbr)); char confirm_buf[4]; memset (confirm_buf, 0, sizeof (confirm_buf)); bool ok = false, write = false; 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) { libprocess_self_init (); char commandbuf[COMMAND_MAX]; commandbuf[0] = '\0'; if (env_get (process_get_pgid (), "C", (void*)commandbuf, sizeof (commandbuf)) != ST_OK) { mprintf ("ERROR C=???. No command provided\n"); return; } if (strcmp (commandbuf, "part_dos") == 0) { start_part_dos (); } }