sdutil Write DOS Master Boot Record
All checks were successful
Build documentation / build-and-deploy (push) Successful in 3m7s

This commit is contained in:
2026-03-20 21:20:30 +01:00
parent fd800f6210
commit 46710bb2dc
4 changed files with 114 additions and 2 deletions

View File

@@ -1,3 +1,5 @@
c += string.c
c += string.c \
strconv.c
o += string.o
o += string.o \
strconv.o

15
libstring/strconv.c Normal file
View File

@@ -0,0 +1,15 @@
#include <stdint.h>
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;
}

12
libstring/strconv.h Normal file
View File

@@ -0,0 +1,12 @@
#ifndef _LIBSTRING_STRCONV_H
#define _LIBSTRING_STRCONV_H
#include <stdint.h>
#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

View File

@@ -1,16 +1,99 @@
#include <devices.h>
#include <in_input.h>
#include <mprintf.h>
#include <process_self.h>
#include <status.h>
#include <str_status.h>
#include <strconv.h>
#include <string.h>
#include <system.h>
#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, &sector, &sector_count, &mbr, NULL);
mprintf ("Finished writing. Result: %s (%d)\n", str_status[r < 0 ? -r : r], r);
}
}
void app_main (void) {