6 #include <sys/bootblock.h>
7 #include <sys/syslimits.h>
12 #include "installboot.h"
15 #define DFL_SECSIZE 512
18 #define MFS_FIRST_SUBP_OFFSET 32
27 minixfs3_read_mbr(const char* device
, char* buf
)
33 fd
= open(device
, O_RDONLY
);
35 fprintf(stderr
, "Can't open %s: %s\n", device
, strerror(errno
));
39 if (lseek(fd
, MBR_PART_OFFSET
, SEEK_SET
) != MBR_PART_OFFSET
) {
40 fprintf(stderr
, "Can't seek in %s to %d: %s\n",
41 device
, MBR_PART_OFFSET
, strerror(errno
));
46 bytes
= DFL_SECSIZE
- MBR_PART_OFFSET
;
48 if ((n
= read(fd
, buf
, bytes
)) != bytes
) {
49 fprintf(stderr
, "Can't read %d bytes from %s, %d read instead"
51 bytes
, device
, n
, strerror(errno
));
56 if ((uint8_t)buf
[bytes
-2] != 0x55 || (uint8_t)buf
[bytes
-1] != 0xAA) {
57 fprintf(stderr
, "No MBR on %s, signature is %x\n",
58 device
, *(uint16_t*)(&buf
[bytes
-2]));
68 minixfs3_get_dev_type(const char *device
, ib_params
*params
)
73 * Unless the -f flag is given, we expect to be provided with a primary
74 * partition. That is, a device name that ends with "pN", N being 0-3.
75 * If the -f flag is given, we assume that anything else is a whole
76 * disk. If we were given a subpartition, it will fail the subsequent
77 * MBR signature test, so we need not check this explicitly.
81 if (len
> 2 && device
[len
-2] == 'p' &&
82 (unsigned) (device
[len
-1] - '0') <= 3) {
88 if (type
!= TYPE_PART
&& !(params
->flags
& IB_FORCE
)) {
89 fprintf(stderr
, "Wrong device %s, must be /.../cxdyp[0-3]\n",
98 minixfs3_is_minix_partition(ib_params
*params
)
100 char buf
[DFL_SECSIZE
]; /* part table + signature */
102 if (minixfs3_get_dev_type(params
->filesystem
, params
) == TYPE_BAD
)
105 /* MINIX 3 partition with current scheme *must* have subpartitions,
106 * thus MBR has signature. minixfs3_read_mbr checks the signature.
108 if (minixfs3_read_mbr(params
->filesystem
, buf
))
113 /* bootxx from NetBSD is ~8Kb, and old MINIX installations have just
114 * 1Kb of space for their bootblock. Check if there is enough space
115 * to install bootxx_minixfs3. New installation should have 16Kb before
116 * the first subpartition.
119 minixfs3_has_bootblock_space(ib_params
*params
)
122 char buf
[DFL_SECSIZE
]; /* part table + signature */
123 char parent_name
[NAME_MAX
];
124 struct mbr_partition
*part
;
125 uint32_t first_subpartition
= (uint32_t) ~0;
126 uint32_t parent_partition
;
127 int i
, len
, type
= 0;
129 device
= params
->filesystem
;
131 if ((type
= minixfs3_get_dev_type(device
, params
)) == TYPE_BAD
)
134 if (minixfs3_read_mbr(device
, buf
))
137 part
= (struct mbr_partition
*) buf
;
139 for (i
= 0; i
< 4; i
++) {
140 if (part
[i
].mbrp_size
&&
141 part
[i
].mbrp_start
< first_subpartition
)
142 first_subpartition
= part
[i
].mbrp_start
;
145 if (type
== TYPE_PART
) {
146 /* The target is a partition. Look up its starting offset. */
147 len
= strlen(device
);
148 strncpy(parent_name
, device
, len
- 2);
149 parent_name
[len
- 2] = '\0';
151 if (minixfs3_read_mbr(parent_name
, buf
))
154 parent_partition
= 0;
155 for (i
= 0; i
< 4; i
++) {
156 struct mbr_partition
*p
= &part
[i
];
157 if (p
->mbrp_size
&& p
->mbrp_start
<= first_subpartition
158 && (p
->mbrp_start
+ p
->mbrp_size
) >
159 first_subpartition
) {
160 parent_partition
= p
->mbrp_start
;
165 /* The target is a whole disk. The starting offset is 0. */
166 parent_partition
= 0;
169 if ((first_subpartition
- parent_partition
) < MFS_FIRST_SUBP_OFFSET
)