1 /* $NetBSD: chg_pid.c,v 1.8 2009/03/31 11:48:15 tsutsui Exp $ */
4 * Copyright (c) 1995 L. Weppelman
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 * This program changes the partition id field (p_id) in the GEM
31 * partition info. NetBSD uses these id-fields to determine the kind
32 * of partition. Sensible id's to set are:
33 * NBU : NetBSD User partition
34 * NBR : NetBSD Root partition
35 * NBS : NetBSD Swap partition
36 * NBD : General NetBSD partition
37 * RAW : Partition hidden for GEMDOS
39 * When NetBSD auto boots, the first 'NBR' partition found when scanning the
40 * SCSI-disks becomes the active root partition. The same goes for 'NBS'.
41 * Drives are scanned in 'SCSI-id' order.
43 #include <sys/types.h>
52 #define Dmawrite DMAwrite
55 #define Dmaread DMAread
59 * Format of GEM root sector
61 typedef struct gem_part
{
62 u_char p_flg
; /* bit 0 is in-use flag */
63 char p_id
[3]; /* id: GEM, BGM, XGM, UNX, MIX */
64 u_long p_st
; /* block where partition starts */
65 u_long p_size
; /* partition size */
71 #define P_VALID 0x01 /* info is valid */
72 #define P_ACTIVE 0x80 /* partition is active */
74 #define NGEM_PARTS 4 /* Max. partition infos in root sector */
76 typedef struct gem_root
{
77 u_char fill
[0x1c2]; /* Filler, can be boot code */
78 u_long hd_siz
; /* size of entire volume */
79 GEM_PART parts
[NGEM_PARTS
]; /* see above */
80 u_long bsl_st
; /* start of bad-sector list */
81 u_long bsl_cnt
; /* nr. blocks in bad-sector list*/
82 u_short csum
; /* checksum correction */
85 void help
PROTO((void));
86 void usage
PROTO((void));
87 int chg_tosparts
PROTO((int, int, char *));
88 void change_it
PROTO((int, GEM_PART
*, char *));
89 int read_block
PROTO((void *, int, int));
90 int write_block
PROTO((void *, int, int));
91 void set_csum
PROTO((char *));
93 const char version
[] = "$Revision: 1.9 $";
95 char *Progname
= NULL
; /* What are we called */
96 int t_flag
= 0; /* Test -- don't actually do it */
97 int v_flag
= 0; /* show version */
98 int h_flag
= 0; /* show help */
101 main(int argc
, char *argv
[])
111 char *newname
= NULL
;
114 init_toslib(argv
[0]);
117 while ((c
= getopt(argc
, argv
, "htVwo:")) != -1) {
123 redirect_output(optarg
);
145 eprintf("%s\r\n", version
);
153 eprintf("Note: >>> Both drive and partition numbers start "
156 driveno
= atoi(argv
[0]);
157 partno
= atoi(argv
[1]);
159 eprintf("About to change id of partition %d on drive %d to %s\r\n",
160 partno
, driveno
, newname
);
163 c
= key_wait("Are you sure (y/n)? ");
168 if(chg_tosparts(partno
, driveno
, newname
)) {
171 else eprintf("Not Done\r\n");
174 else eprintf("Partition number not found\r\n");
177 eprintf("Aborted\r\n");
184 int chg_tosparts(chg_part
, drive
, newname
)
189 GEM_PART g_local
[NGEM_PARTS
];
197 if (read_block(buf
, 0, drive
) == 0)
198 fatal(-1, "Cannot read block 0\r\n");
201 * Make local copy of partition info, we may need to re-use
202 * the buffer in case of 'XGM' partitions.
204 g_root
= (GEM_ROOT
*)buf
;
205 memcpy(g_local
, g_root
->parts
, NGEM_PARTS
*sizeof(GEM_PART
));
207 for (i
= 0; i
< NGEM_PARTS
; i
++) {
208 if (!(g_local
[i
].p_flg
& 1))
210 if (!strncmp(g_local
[i
].p_id
, "XGM", 3)) {
212 daddr_t new_root
= g_local
[i
].p_st
;
215 * Loop through extended partition list
218 if (read_block(buf
, new_root
, drive
) == 0)
219 fatal(-1, "Cannot read block %d\r\n", new_root
);
220 for (j
= 0; j
< NGEM_PARTS
; j
++) {
221 if (!(g_root
->parts
[j
].p_flg
& 1))
223 if (!strncmp(g_root
->parts
[j
].p_id
, "XGM", 3)) {
224 new_root
= g_local
[i
].p_st
+ g_root
->parts
[j
].p_st
;
228 if (pno
== chg_part
) {
229 change_it(pno
, &g_root
->parts
[j
], newname
);
232 if (write_block(buf
, new_root
, drive
) == 0)
233 fatal(-1, "Cannot write block %d\r\n",new_root
);
244 if (pno
== chg_part
) {
248 if (read_block(buf
, 0, drive
) == 0)
249 fatal(-1, "Cannot read block 0\r\n");
250 change_it(pno
, &g_root
->parts
[i
], newname
);
254 if (write_block(buf
, 0, drive
) == 0)
255 fatal(-1, "Cannot write block 0\r\n");
264 void change_it(pno
, gp
, newname
)
271 strncpy(s1
, gp
->p_id
, 3);
272 strncpy(s2
, newname
, 3);
273 s1
[3] = s2
[3] = '\0';
274 eprintf("Changing partition %d: %s -> %s ...", pno
, s1
, s2
);
275 gp
->p_id
[0] = s2
[0]; gp
->p_id
[1] = s2
[1]; gp
->p_id
[2] = s2
[2];
278 int read_block(buf
, blkno
, drive
)
283 if(Dmaread(blkno
, 1, buf
, drive
+ 8) != 0)
288 int write_block(buf
, blkno
, drive
)
293 if(Dmawrite(blkno
, 1, buf
, drive
+ 8) != 0)
301 unsigned short *p
= (unsigned short *)buf
;
302 unsigned short csum
= 0;
306 for(i
= 0; i
< 256; i
++)
308 *--p
= (0x1234 - csum
) & 0xffff;
313 eprintf("Usage: %s [-hVwt] [ -o <output file>] <driveno> <partno> "
314 "<newid>\r\n", Progname
);
322 Change partition identifiers\r
324 Usage: %s [-hVwt] [ -o <output file>] <driveno> <partno> <newid>\r
326 Description of options:\r
328 \t-h What you're getting right now.\r
329 \t-o Write output to both <output file> and stdout.\r
330 \t-V Print program version.\r
331 \t-w Wait for a keypress before exiting.\r
332 \t-t Test mode. It does everyting except the modifications on disk.\r
334 The <driveno> and <partno> arguments specify the drive and the partition\r
335 this program acts on. Both are zero based.\r
336 The <newid> argument specifies a 3 letter string that will become the new\r
338 Finally note that the actions of %s are reversable.\r
339 ", Progname
, Progname
);