1 /* parthenope-install.c */
3 /* <project_name> -- <project_description>
5 * Copyright (C) 2006 - 2007
6 * Giuseppe Coviello <cjg@cruxppc.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 #include <sys/types.h>
30 #include "../src/rdb.h"
32 static int checksum(struct AmigaBlock
*_header
)
34 struct AmigaBlock
*header
;
36 memmove(header
, _header
, 512);
37 int32_t *block
= (int32_t *) header
;
40 if (header
->amiga_SummedLongss
> 512)
41 header
->amiga_SummedLongss
= 512;
42 for (i
= 0; i
< header
->amiga_SummedLongss
; i
++)
48 static inline void calculate_checksum(struct AmigaBlock
*blk
)
50 blk
->amiga_ChkSum
= blk
->amiga_ChkSum
- checksum(blk
);
54 static struct AmigaBlock
*read_block(FILE * dev
,
55 struct AmigaBlock
*blk
, uint32_t block
)
61 fseek(dev
, block
* 512, SEEK_SET
);
63 fread(blk
, 512, 1, dev
);
65 fseek(dev
, pos
, SEEK_SET
);
67 if (checksum(blk
) != 0) {
68 /* printf("parthenope-install: Bad checksum at block: %d!\n", block);*/
75 static struct RigidDiskBlock
*read_rdb(FILE * dev
,
76 struct RigidDiskBlock
*blk
,
82 fseek(dev
, block
* 512, SEEK_SET
);
83 fread(blk
, sizeof(struct RigidDiskBlock
), 1, dev
);
84 fseek(dev
, pos
, SEEK_SET
);
89 struct RigidDiskBlock
*find_rdb(FILE * dev
, uint32_t * rdb_block
)
92 struct RigidDiskBlock
*rdb
;
96 for (i
= 0; i
< RDB_LOCATION_LIMIT
; i
++) {
97 if (read_block(dev
, (struct AmigaBlock
*)rdb
, i
) == NULL
98 || rdb
->rdb_ID
!= IDNAME_RIGIDDISK
)
100 if (checksum((struct AmigaBlock
*)rdb
) != 0) {
101 printf("parthenope-install: Bad checksum at block "
106 return read_rdb(dev
, rdb
, i
);
113 int next_free_block(FILE * dev
, uint32_t * block
, uint32_t * free_pointer
,
116 struct AmigaBlock
*blk
;
122 if (read_block(dev
, blk
, *free_pointer
) == NULL
)
124 } while (!IS_FREE(blk
) && *free_pointer
< nblocks
);
128 *block
= *free_pointer
;
137 void write_block(FILE * dev
, void *blk
, uint32_t block
)
139 fseek(dev
, block
* 512, SEEK_SET
);
140 fwrite(blk
, 1, 512, dev
);
143 void erase_slb(FILE * dev
, struct RigidDiskBlock
*rdb
)
146 struct AmigaBlock
*blk
;
148 printf("parthenope-install: Erasing old slb ...");
152 for (block
= rdb
->rdb_BootBlockList
;
154 && read_block(dev
, blk
, block
) != NULL
155 && blk
->amiga_ID
== IDNAME_BOOT
;
156 block
= ((struct BootstrapCodeBlock
*)blk
)->bcb_Next
) {
157 blk
->amiga_ID
= IDNAME_FREE
;
158 calculate_checksum(blk
);
159 write_block(dev
, blk
, block
);
167 void install_slb(FILE * dev
, struct RigidDiskBlock
*rdb
, uint32_t * slb
,
171 uint32_t block
, next_block
, free_block_pointer
;
172 struct BootstrapCodeBlock
*blk
;
174 printf("parthenope-install: Writing new slb ...");
177 free_block_pointer
= 0;
179 if (next_free_block(dev
, &block
, &free_block_pointer
,
180 rdb
->rdb_RDBBlocksHi
- rdb
->rdb_RDBBlocksLo
) < 0) {
181 printf("parthenope-install: Not enough free blocks!\n");
185 rdb
->rdb_BootBlockList
= block
;
188 for (offset
= 0; offset
< slb_size
; offset
+= 123) {
189 if (next_free_block(dev
, &next_block
, &free_block_pointer
,
190 rdb
->rdb_RDBBlocksHi
- rdb
->rdb_RDBBlocksLo
)
193 printf("parthenope-install: Not enough free blocks!\n");
198 blk
->bcb_ID
= IDNAME_BOOT
;
199 blk
->bcb_SummedLongs
= 128;
201 blk
->bcb_Next
= next_block
;
202 if (slb_size
- offset
<= 123) {
203 blk
->bcb_SummedLongs
= 5 + slb_size
- offset
;
204 blk
->bcb_Next
= IDNAME_FREE
;
206 memmove(blk
->bcb_LoadData
, slb
+ offset
, 123
208 calculate_checksum((struct AmigaBlock
*) blk
);
209 write_block(dev
, blk
, block
);
216 int main(int argc
, char **argv
)
219 struct RigidDiskBlock
*rdb
;
220 uint32_t rdb_block
, *slb
, slb_size
;
224 fprintf(stderr
, "parthenope-install: Usage: %s "
225 "/path/to/Parthenope!\n", argv
[0]);
229 dev
= fopen("/dev/sda", "w+");
231 fprintf(stderr
, "parthenope-install: Cannot open /dev/sda!\n");
235 rdb
= find_rdb(dev
, &rdb_block
);
237 fprintf(stderr
, "parthenope-install: Cannot find RDB!\n");
242 if (lstat(argv
[1], &st
) < 0) {
244 "parthenope-install: Cannot stat %s!\n", argv
[1]);
250 f
= fopen(argv
[1], "r");
253 "parthenope-install: Cannot open %s!\n", argv
[1]);
259 slb_size
= st
.st_size
/ sizeof(uint32_t);
260 slb
= malloc(st
.st_size
);
262 fread(slb
, 1, st
.st_size
, f
);
266 install_slb(dev
, rdb
, slb
, slb_size
);
267 calculate_checksum((struct AmigaBlock
*) rdb
);
268 write_block(dev
, rdb
, rdb_block
);