aboutsummaryrefslogtreecommitdiffstats
path: root/src/pmbr.c
blob: b110850a2deed01ac850d30812601599c1a60e4c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include "project.h"


void
mbr_entry_show (MBR_entry * e)
{
  printf ("      flags  %02x start chs %5d/%3d/%2d start sector %10d\n",
          e->bootable,
          MBR_CYLINDER (e->chs_start.cs),
          e->chs_start.head, MBR_SECTOR (e->chs_start.cs), e->start);

  printf ("      system %02x end   chs %5d/%3d/%2d end   sector %10d\n",
          e->system,
          MBR_CYLINDER (e->chs_end.cs),
          e->chs_end.head, MBR_SECTOR (e->chs_end.cs),
          e->size + e->start - 1);
}

void
mbr_show (MBR * m)
{
  int i;

  printf ("  PMBR:\n");

  for (i = 0; i < 4; ++i)
    {
      if (m->entry[i].system)
        {
          printf ("    Entry %d:\n", i);
          mbr_entry_show (&m->entry[i]);
        }
    }
  if (memcmp (m->signature, MBR_SIGNATURE, sizeof (m->signature)))
    {
      printf ("    Signature INVALID\n");
    }
  else
    {
      printf ("    Signature valid\n");
    }
}

MBR
mbr_new (uint64_t lbas)
{
  uint64_t cyls = lbas;
  MBR ret = { 0 };

  cyls = cyls / (63 * 255);
  if (cyls > 1023)
    cyls = 1023;

  ret.entry[0].bootable = 0;
  ret.entry[0].chs_start.cs = MBR_CS (0, 1);
  ret.entry[0].system = MBR_PARTITION_TYPE_EFI;
  ret.entry[0].chs_end.head = 254;
  ret.entry[0].chs_end.cs = MBR_CS (cyls, 63);
  ret.entry[0].start = 1;
  ret.entry[0].size = lbas - 1;

  memcpy (ret.signature, MBR_SIGNATURE, sizeof (ret.signature));

  return ret;
}


static CHS
sector_to_chs (uint32_t lba)
{
  CHS ret;
  int c;
  int h;
  int s;

  c = lba / (63 * 255);

  if (c > 1023)
    {
      ret.head = 254;
      ret.cs = MBR_CS (1023, 63);
      return ret;
    }

  lba -= (c * 63 * 255);
  h = lba / 63;
  lba -= (h * 63);
  s = lba + 1;


  ret.head = h;
  ret.cs = MBR_CS (c, s);

  return ret;
}

static CHS
invalid_chs (void)
{
  CHS ret;

  ret.head = 254;
  ret.cs = MBR_CS (1023, 63);
  return ret;
}





void
mbr_entry_from_gpt_entry (MBR_entry * m, GPT_header * h, GPT_entry * g,
                          int bootable, uint8_t type)
{
  MBR ret = { 0 };
  uint32_t start = g->start;
  uint32_t end = g->end;


  m->system = type;
  m->bootable = bootable ? MBR_PARTITION_BOOTABLE : 0x00;
  m->chs_start = invalid_chs ();
  m->chs_end = invalid_chs ();
  m->start = start;
  m->size = (end - start) + 1;

  if (type == MBR_PARTITION_TYPE_EFI)
    {
      m->size += m->start -1;
      m->start = 1;
    }

}