Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support creating MBR extended partitions #240

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,67 @@ mbr mbr-a {
}
```

### Extended partitions

MBR supports more than 4 partitions by using a special extended partition type.
Normally if you need more than 4 partitions, you'd want to switch to GPT, but
your setup may make this more trouble than it's worth. At a high level, to use
the extended partition feature, you need to mark partition 3 as the extended
partition. Then you can specified partitions 4 and higher. Each of these
partitions will have a 512-byte [Extended Boot
Record](https://en.wikipedia.org/wiki/Extended_boot_record) or EBR. Fwup stores
all EBRs at the beginning of the extended partition, so if you have partitions
4, 5, and 6, that will require 3 EBRs or 1536 bytes. Partition 4 would start at
a block after that. Note that there's flexibility in where EBRs are written so
you'll see other programs that make different decisions, but it all works so
long as the EBRs are inside of the extended partition and don't overlap with any
other partition.

Here's an example of an extended partition:

```conf
mbr mbr-a {
partition 0 {
block-offset = \${AUTOBOOT_PART_OFFSET}
block-count = \${AUTOBOOT_PART_COUNT}
type = 0x6 # FAT12
boot = true
}
partition 1 {
block-offset = \${BOOT_A_PART_OFFSET}
block-count = \${BOOT_A_PART_COUNT}
type = 0xc # FAT32
}
partition 2 {
block-offset = \${BOOT_B_PART_OFFSET}
block-count = \${BOOT_B_PART_COUNT}
type = 0xc # FAT32
}
partition 3 {
type = 0xf # Extended partition
block-offset = \${EXTENDED_PART_OFFSET}
}
partition 4 {
block-offset = \${ROOTFS_A_PART_OFFSET}
block-count = \${ROOTFS_A_PART_COUNT}
type = 0x83 # Linux
}
partition 5 {
block-offset = \${ROOTFS_B_PART_OFFSET}
block-count = \${ROOTFS_B_PART_COUNT}
type = 0x83 # Linux
}
partition 6 {
block-offset = \${APP_PART_OFFSET}
block-count = \${APP_PART_COUNT}
type = 0x83 # Linux
}
}
```

Fwup calculates the extended partition's size based on the partitions after it,
so you only need to specify the starting block offset.

## gpt

A `gpt` section specifies the contents of a [GUID Partition
Expand Down
11 changes: 7 additions & 4 deletions src/functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -851,11 +851,14 @@ int mbr_write_run(struct fun_context *fctx)
cfg_t *mbrsec = cfg_gettsec(fctx->cfg, "mbr", mbr_name);
uint32_t num_blocks = fctx->output->end_offset / FWUP_BLOCK_SIZE; // end_offset can be 0 for unknown

uint8_t buffer[FWUP_BLOCK_SIZE];
OK_OR_RETURN(mbr_create_cfg(mbrsec, num_blocks, buffer));
struct mbr_raw_partition raw[MBR_MAX_OUTPUT_BLOCKS];
uint32_t raw_count = 0;
OK_OR_RETURN(mbr_create_cfg(mbrsec, num_blocks, raw, &raw_count));

OK_OR_RETURN_MSG(block_cache_pwrite(fctx->output, buffer, FWUP_BLOCK_SIZE, 0, false),
"unexpected error writing mbr: %s", strerror(errno));
for (uint32_t i = 0; i < raw_count; i++) {
OK_OR_RETURN_MSG(block_cache_pwrite(fctx->output, raw[i].data, FWUP_BLOCK_SIZE, raw[i].block_offset * FWUP_BLOCK_SIZE, false),
"unexpected error writing mbr: %s", strerror(errno));
}

progress_report(fctx->progress, FWUP_BLOCK_SIZE);
return 0;
Expand Down
Loading