Newer
Older
vvd / src / fs / mbr.c
@dd86k dd86k on 16 Aug 2020 2 KB Interface changes
#include <stdio.h>
#include <stdint.h>
#include "mbr.h"
#include <assert.h>

//
// mbr_lba
//

uint32_t mbr_lba(CHS *chs) {
	// LBA = (C * HPC + H) * SPT + (S − 1)
	// HPC	Max heads per cylinders, typically 16 (28-bit LBA)
	// SPT	Max sectors per strack, typically 63 (28-bit LBA)
	uint8_t sector = chs->sector & 0x3F;
	uint16_t cylinder = chs->cylinder | ((chs->sector & 0xC0) << 2);
	return (cylinder * 16 * chs->head) * 63 + (sector - 1);
}

//
// mbr_lba_a
//

uint32_t mbr_lba_a(CHS *chs, uint64_t dsize) {
	uint8_t HPC;

	if (dsize <= MBR_LBA_A_504_MB)
		HPC = 16;
	else if (dsize <= MBR_LBA_A_1008_MB)
		HPC = 32;
	else if (dsize <= MBR_LBA_A_2016_MB)
		HPC = 64;
	else if (dsize <= MBR_LBA_A_4032_MB)
		HPC = 128;
	else if (dsize <= MBR_LBA_A_8032_MB)
		HPC = 255;
	else
		HPC = 16; //TODO: Verify HPC value when disksize >8.5 GiB

	uint8_t sector = chs->sector & 0x3F;
	uint16_t cylinder = chs->cylinder | ((chs->sector & 0xC0) << 2);
	return (cylinder * HPC * chs->head) * 63 + (sector - 1);
}

//
// mbr_info_stdout
//

void mbr_info_stdout(MBR *mbr, uint32_t flags) {
	//TODO: Simplified view (and leave this one in "--raw-info")
	uint64_t totalsize = SECTOR_TO_BYTE(
		(uint64_t)mbr->pe[0].sectors + (uint64_t)mbr->pe[1].sectors +
		(uint64_t)mbr->pe[2].sectors + (uint64_t)mbr->pe[3].sectors
	);
	char strsize[BINSTR_LENGTH];
	bintostr(strsize, totalsize);

	printf(
	"\nMBR: SERIAL %08X, %s USED, TYPE %04u\n"
	"   STAT  TYPE        LBA        SIZE    CHS start-end\n",
	mbr->serial, strsize, mbr->type
	);

	for (unsigned int i = 0; i < 4; ++i) {
		MBR_PARTITION pe = mbr->pe[i];
		printf(
		"%u.  %2XH   %2XH %10u  %10u  %4u:%3u:%2u-%4u:%3u:%2u\n",
		i, pe.status, pe.parttype, pe.lba, pe.sectors,
		// CHS start
		pe.chsfirst.cylinder | ((pe.chsfirst.sector & 0xC0) << 2),
		pe.chsfirst.head, pe.chsfirst.sector & 0x3F,
		// CHS end
		pe.chslast.cylinder | ((pe.chslast.sector & 0xC0) << 2),
		pe.chslast.head, pe.chslast.sector & 0x3F
		);
	}
}

//
// mbr_part_type_str
//

const char *mbr_part_type_str(uint8_t type) {
	assert(0);
	return NULL;
}