2 Copyright © 1995-2006, The AROS Development Team. All rights reserved.
9 #include <proto/exec.h>
10 #include <proto/partition.h>
11 #include <aros/macros.h>
12 #include <devices/hardblocks.h>
13 #include <devices/newstyle.h>
15 #include <exec/errors.h>
16 #include <exec/memory.h>
17 #include <libraries/partition.h>
20 #include <aros/debug.h>
22 /* Defines for grub data */
23 /* Stage 1 pointers */
24 #define MBR_BPBEND 0x3e
25 #define GRUB_BOOT_DRIVE 0x40
26 #define GRUB_FORCE_LBA 0x41
27 #define GRUB_STAGE2_SECTOR 0x44
28 #define MBR_PARTSTART 0x1be
29 #define MBR_PARTEND 0x1fe
30 /* Stage 2 pointers */
33 #define BIOS_HDISK_FLAG 0x80
48 #define VF_IS_TRACKDISK (1<<0)
49 #define VF_IS_RDB (1<<1)
60 "PARTITIONNUMBER=PN/K/N,"
64 IPTR myargs
[7] = {0,0,0,0,0,0};
66 struct FileSysStartupMsg
*getDiskFSSM(STRPTR path
) {
68 struct DeviceNode
*dn
;
72 D(bug("[install-i386] getDiskFSSM('%s')\n", path
));
74 for (i
=0;(path
[i
]) && (path
[i
]!=':');i
++)
79 dl
= LockDosList(LDF_READ
);
82 dn
= (struct DeviceNode
*)FindDosEntry(dl
, dname
, LDF_DEVICES
);
83 UnLockDosList(LDF_READ
);
86 if (IsFileSystem(dname
))
88 return (struct FileSysStartupMsg
*)BADDR(dn
->dn_Startup
);
91 printf("device '%s' doesn't contain a file system\n", dname
);
94 PrintFault(ERROR_OBJECT_NOT_FOUND
, dname
);
98 printf("'%s' doesn't contain a device name\n",path
);
102 void nsdCheck(struct Volume
*volume
) {
103 struct NSDeviceQueryResult nsdq
;
106 D(bug("[install-i386] nsdCheck(%x)\n", volume
));
110 (volume
->startblock
+volume
->countblock
)* /* last block */
111 ((volume
->SizeBlock
<<2)/512) /* 1 portion (block) equals 512 (bytes) */
114 nsdq
.SizeAvailable
=0;
115 nsdq
.DevQueryFormat
=0;
116 volume
->iotd
->iotd_Req
.io_Command
=NSCMD_DEVICEQUERY
;
117 volume
->iotd
->iotd_Req
.io_Data
=&nsdq
;
118 volume
->iotd
->iotd_Req
.io_Length
=sizeof(struct NSDeviceQueryResult
);
119 if (DoIO((struct IORequest
*)&volume
->iotd
->iotd_Req
)==IOERR_NOCMD
)
121 printf("Device doesn't understand NSD-Query\n");
126 (volume
->iotd
->iotd_Req
.io_Actual
>sizeof(struct NSDeviceQueryResult
)) ||
127 (volume
->iotd
->iotd_Req
.io_Actual
==0) ||
128 (volume
->iotd
->iotd_Req
.io_Actual
!=nsdq
.SizeAvailable
)
131 printf("WARNING wrong io_Actual using NSD\n");
135 if (nsdq
.DeviceType
!= NSDEVTYPE_TRACKDISK
)
136 printf("WARNING no trackdisk type\n");
137 for (cmdcheck
=nsdq
.SupportedCommands
;*cmdcheck
;cmdcheck
++)
139 if (*cmdcheck
== NSCMD_TD_READ64
)
140 volume
->readcmd
= NSCMD_TD_READ64
;
141 if (*cmdcheck
== NSCMD_TD_WRITE64
);
142 volume
->writecmd
= NSCMD_TD_WRITE64
;
145 (volume
->readcmd
!=NSCMD_TD_READ64
) ||
146 (volume
->writecmd
!=NSCMD_TD_WRITE64
)
148 printf("WARNING no READ64/WRITE64\n");
155 struct Volume
*initVolume(STRPTR device
, ULONG unit
, ULONG flags
, ULONG size
) {
156 struct Volume
*volume
;
159 D(bug("[install-i386] initVolume(%s:%d)\n", device
, unit
));
161 volume
= AllocVec(sizeof(struct Volume
), MEMF_PUBLIC
| MEMF_CLEAR
);
164 volume
->mp
= CreateMsgPort();
167 volume
->iotd
= (struct IOExtTD
*)CreateIORequest(volume
->mp
, sizeof(struct IOExtTD
));
170 volume
->blockbuffer
= AllocVec(size
<<2, MEMF_PUBLIC
| MEMF_CLEAR
);
171 if (volume
->blockbuffer
)
178 (struct IORequest
*)volume
->iotd
,
183 if (strcmp(device
, "trackdisk.device")==0)
184 volume
->flags
|= VF_IS_TRACKDISK
;
186 volume
->flags
|= VF_IS_RDB
; /* just assume we have RDB */
187 volume
->readcmd
= CMD_READ
;
188 volume
->writecmd
= CMD_WRITE
;
193 error
= ERROR_NO_FREE_STORE
;
194 FreeVec(volume
->blockbuffer
);
197 error
= ERROR_NO_FREE_STORE
;
198 DeleteIORequest((struct IORequest
*)volume
->iotd
);
201 error
= ERROR_NO_FREE_STORE
;
202 DeleteMsgPort(volume
->mp
);
205 error
= ERROR_NO_FREE_STORE
;
209 error
= ERROR_NO_FREE_STORE
;
210 PrintFault(error
, NULL
);
214 void uninitVolume(struct Volume
*volume
)
217 D(bug("[install-i386] uninitVolume(%x)\n", volume
));
219 CloseDevice((struct IORequest
*)volume
->iotd
);
220 FreeVec(volume
->blockbuffer
);
221 DeleteIORequest((struct IORequest
*)volume
->iotd
);
222 DeleteMsgPort(volume
->mp
);
228 struct Volume
*volume
,
229 ULONG block
, APTR buffer
, ULONG length
,
236 D(bug("[install-i386] readwriteBlock(vol:%x, block:%d, %d bytes)\n", volume
, block
, length
));
238 volume
->iotd
->iotd_Req
.io_Command
= command
;
239 volume
->iotd
->iotd_Req
.io_Length
= length
;
240 volume
->iotd
->iotd_Req
.io_Data
= buffer
;
241 offset
= (UQUAD
)(volume
->startblock
+block
)*(volume
->SizeBlock
<<2);
242 volume
->iotd
->iotd_Req
.io_Offset
= offset
& 0xFFFFFFFF;
243 volume
->iotd
->iotd_Req
.io_Actual
= offset
>>32;
244 retval
= DoIO((struct IORequest
*)&volume
->iotd
->iotd_Req
);
245 if (volume
->flags
& VF_IS_TRACKDISK
)
247 volume
->iotd
->iotd_Req
.io_Command
= TD_MOTOR
;
248 volume
->iotd
->iotd_Req
.io_Length
= 0;
249 DoIO((struct IORequest
*)&volume
->iotd
->iotd_Req
);
254 BOOL
isvalidFileSystem(struct Volume
*volume
, STRPTR device
, ULONG unit
) {
256 struct PartitionBase
*PartitionBase
;
257 struct PartitionHandle
*ph
;
259 D(bug("[install-i386] isvalidFileSystem(%x, %s, %d)\n", volume
, device
, unit
));
261 if (readwriteBlock(volume
, 0, volume
->blockbuffer
, 512, volume
->readcmd
))
263 printf("Read Error\n");
267 ((AROS_BE2LONG(volume
->blockbuffer
[0]) & 0xFFFFFF00)!=0x444F5300) ||
268 ((AROS_BE2LONG(volume
->blockbuffer
[0]) & 0xFF) == 0)
271 /* first block has no DOS\x so we don't have RDB for sure */
272 volume
->flags
&= ~VF_IS_RDB
;
273 if (readwriteBlock(volume
, 1, volume
->blockbuffer
, 512, volume
->readcmd
))
275 printf("Read Error\n");
279 ((AROS_BE2LONG(volume
->blockbuffer
[0]) & 0xFFFFFF00)!=0x444F5300) ||
280 ((AROS_BE2LONG(volume
->blockbuffer
[0]) & 0xFF) == 0)
284 volume
->partnum
= -1;
285 PartitionBase
= (struct PartitionBase
*)OpenLibrary("partition.library", 1);
288 ph
= OpenRootPartition(device
, unit
);
291 if (OpenPartitionTable(ph
) == 0)
293 struct TagItem tags
[2];
296 tags
[1].ti_Tag
= TAG_DONE
;
297 tags
[0].ti_Tag
= PTT_TYPE
;
298 tags
[0].ti_Data
= (STACKIPTR
)&type
;
299 GetPartitionTableAttrs(ph
, tags
);
300 if (type
== PHPTT_MBR
)
302 struct PartitionHandle
*pn
;
305 tags
[0].ti_Tag
= PT_DOSENVEC
;
306 tags
[0].ti_Data
= (STACKIPTR
)&de
;
307 pn
= (struct PartitionHandle
*)ph
->table
->list
.lh_Head
;
308 while (pn
->ln
.ln_Succ
)
312 GetPartitionAttrs(pn
, tags
);
313 scp
= de
.de_Surfaces
*de
.de_BlocksPerTrack
;
315 (volume
->startblock
>=(de
.de_LowCyl
*scp
)) &&
316 (volume
->startblock
<=(((de
.de_HighCyl
+1)*scp
)-1))
319 pn
= (struct PartitionHandle
*)pn
->ln
.ln_Succ
;
323 tags
[0].ti_Tag
= PT_POSITION
;
324 tags
[0].ti_Data
= (STACKIPTR
)&type
;
325 GetPartitionAttrs(pn
, tags
);
326 volume
->partnum
= (UBYTE
)type
;
332 if (type
== PHPTT_RDB
)
334 /* just use whole hard disk */
338 printf("only MBR and RDB partition tables are supported\n");
340 ClosePartitionTable(ph
);
344 /* just use whole hard disk */
347 CloseRootPartition(ph
);
350 printf("Error OpenRootPartition(%s,%ld)\n", device
, unit
);
351 CloseLibrary((struct Library
*)PartitionBase
);
354 printf("Couldn't open partition.library\n");
358 void fillGeometry(struct Volume
*volume
, struct DosEnvec
*de
) {
361 D(bug("[install-i386] fillGeometry(%x)\n", volume
));
363 spc
= de
->de_Surfaces
*de
->de_BlocksPerTrack
;
364 volume
->SizeBlock
= de
->de_SizeBlock
;
365 volume
->startblock
= de
->de_LowCyl
*spc
;
366 volume
->countblock
=((de
->de_HighCyl
-de
->de_LowCyl
+1)*spc
)-1+de
->de_Reserved
;
369 struct Volume
*getGrubStageVolume
377 struct Volume
*volume
;
379 volume
= initVolume(device
, unit
, flags
, de
->de_SizeBlock
);
381 D(bug("[install-i386] getGrubStageVolume(): volume=%x\n", volume
));
385 fillGeometry(volume
, de
);
386 if (isvalidFileSystem(volume
, device
, unit
))
390 printf("stage2 is on an unsupported file system\n");
391 PrintFault(ERROR_OBJECT_WRONG_TYPE
, NULL
);
393 uninitVolume(volume
);
398 BOOL isvalidPartition
406 struct PartitionBase
*PartitionBase
;
407 struct PartitionHandle
*ph
;
411 D(bug("[install-i386] isvalidPartition(%s:%d, part:%d)\n", device
, unit
, pnum
));
413 PartitionBase
= (struct PartitionBase
*)OpenLibrary("partition.library", 1);
416 ph
= OpenRootPartition(device
, unit
);
419 struct TagItem tags
[2];
421 tags
[1].ti_Tag
= TAG_DONE
;
422 /* is there a partition table? */
423 if (OpenPartitionTable(ph
) == 0)
427 /* install into partition bootblock */
428 tags
[0].ti_Tag
= PTT_TYPE
;
429 tags
[0].ti_Data
= (STACKIPTR
)&type
;
430 GetPartitionTableAttrs(ph
, tags
);
431 if (type
== PHPTT_MBR
)
433 struct PartitionHandle
*pn
;
435 /* search for partition */
436 tags
[0].ti_Tag
= PT_POSITION
;
437 tags
[0].ti_Data
= (STACKIPTR
)&type
;
438 pn
= (struct PartitionHandle
*)ph
->table
->list
.lh_Head
;
439 while (pn
->ln
.ln_Succ
)
441 GetPartitionAttrs(pn
, tags
);
444 pn
= (struct PartitionHandle
*)pn
->ln
.ln_Succ
;
448 struct PartitionType ptype
;
450 /* is it an AROS partition? */
451 tags
[0].ti_Tag
= PT_TYPE
;
452 tags
[0].ti_Data
= (STACKIPTR
)&ptype
;
453 GetPartitionAttrs(pn
, tags
);
454 if (ptype
.id
[0] == 0x30)
456 tags
[0].ti_Tag
= PT_DOSENVEC
;
457 tags
[0].ti_Data
= (STACKIPTR
)de
;
458 GetPartitionAttrs(pn
, tags
);
462 printf("partition is not of type AROS (0x30)\n");
468 "partition %ld not found on device %s unit %ld\n",
474 printf("you can only install in partitions which are MBR partitioned\n");
478 /* install into MBR */
479 tags
[0].ti_Tag
= PTT_TYPE
;
480 tags
[0].ti_Data
= (STACKIPTR
)&type
;
481 GetPartitionTableAttrs(ph
, tags
);
482 if ((type
== PHPTT_MBR
) || (type
== PHPTT_RDB
))
484 tags
[0].ti_Tag
= PT_DOSENVEC
;
485 tags
[0].ti_Data
= (STACKIPTR
)de
;
486 GetPartitionAttrs(ph
, tags
);
490 printf("partition table type must be either MBR or RDB\n");
492 ClosePartitionTable(ph
);
496 #warning "FIXME: GetPartitionAttr() should always work for root partition"
497 CopyMem(&ph
->de
, de
, sizeof(struct DosEnvec
));
500 CloseRootPartition(ph
);
503 printf("Error OpenRootPartition(%s,%ld)\n", device
, unit
);
504 CloseLibrary((struct Library
*)PartitionBase
);
507 printf("Couldn't open partition.library\n");
511 struct Volume
*getBBVolume(STRPTR device
, ULONG unit
, LONG
*partnum
) {
512 struct Volume
*volume
;
515 D(bug("[install-i386] getBBVolume(%s:%d, %d)\n", device
, unit
, partnum
));
517 if (isvalidPartition(device
, unit
, partnum
, &de
))
519 volume
= initVolume(device
, unit
, 0, de
.de_SizeBlock
);
520 volume
->partnum
= partnum
? *partnum
: -1;
521 fillGeometry(volume
, &de
);
522 readwriteBlock(volume
, 0, volume
->blockbuffer
, 512, volume
->readcmd
);
523 if (AROS_BE2LONG(volume
->blockbuffer
[0]) != IDNAME_RIGIDDISK
)
525 memset(volume
->blockbuffer
,0x00, 446); /* Clear the boot sector region! */
529 printf("no space for bootblock (RDB is on block 0)\n");
534 ULONG collectBlockList
536 struct Volume
*volume
,
538 struct BlockNode
*blocklist
541 ULONG retval
, first_block
;
542 WORD blk_count
,count
;
545 D(bug("[install-i386] collectBlockList(%x, %d, %x)\n", volume
, block
, blocklist
));
547 #warning "TODO: logical/physical blocks"
549 initialze stage2-blocklist
550 (it is NULL-terminated)
552 // for (blk_count=-1;blocklist[blk_count].sector!=0;blk_count--)
553 // blocklist[blk_count].sector = 0;
555 memset((char *)&blocklist
[-20],0x00, 20*sizeof(struct BlockNode
)); /* Clear the stage2 sector pointers region! */
556 D(bug("[install-i386] collectBlockList: Cleared sector list (20 entries) [start: %x, end %x]\n", &blocklist
[-20], &blocklist
[-1]));
559 the first block of stage2 will be stored in stage1
560 so skip the first filekey in the first loop
562 #warning "Block read twice"
563 retval
=readwriteBlock
565 volume
, block
, volume
->blockbuffer
, volume
->SizeBlock
<<2,
570 D(bug("[install-i386] collectBlockList: ERROR reading block (error: %ld\n", retval
));
571 printf("ReadError %ld\n", retval
);
575 i
= volume
->SizeBlock
- 52;
576 first_block
= AROS_BE2LONG(volume
->blockbuffer
[volume
->SizeBlock
-51]);
579 D(bug("[install-i386] collectBlockList: First block @ %x, i:%d\n", first_block
, i
));
584 retval
=readwriteBlock
586 volume
, block
, volume
->blockbuffer
, volume
->SizeBlock
<<2,
591 D(bug("[install-i386] collectBlockList: ERROR reading block (error: %ld)\n", retval
));
592 printf("ReadError %ld\n", retval
);
595 D(bug("[install-i386] collectBlockList: read block %lx, i = %d\n", block
, i
));
596 while ((i
>=6) && (volume
->blockbuffer
[i
]))
598 D(bug("[install-i386] collectBlockList: i = %d\n", i
));
600 if current sector follows right after last sector
601 then we don't need a new element
604 (blocklist
[blk_count
].sector
) &&
605 ((blocklist
[blk_count
].sector
+blocklist
[blk_count
].count
)==
606 AROS_BE2LONG(volume
->blockbuffer
[i
]))
609 blocklist
[blk_count
].count
+= 1;
610 D(bug("[install-i386] collectBlockList: sector %d follows previous - increasing count of block %d to %d\n", i
, blk_count
, blocklist
[blk_count
].count
));
614 blk_count
--; /* decrement first */
615 D(bug("[install-i386] collectBlockList: store new block (%d)\n", blk_count
));
616 if (blocklist
[blk_count
-1].sector
!= 0)
618 D(bug("[install-i386] collectBlockList: ERROR: out of block space at sector %d, block %d\n", i
, blk_count
));
619 printf("There is no more space to save blocklist in stage2\n");
622 D(bug("[install-i386] collectBlockList: storing sector pointer for %d in block %d\n", i
, blk_count
));
623 blocklist
[blk_count
].sector
= AROS_BE2LONG(volume
->blockbuffer
[i
]);
624 blocklist
[blk_count
].count
= 1;
628 i
= volume
->SizeBlock
- 51;
629 block
= AROS_BE2LONG(volume
->blockbuffer
[volume
->SizeBlock
- 2]);
630 D(bug("[install-i386] collectBlockList: next block %d, i = %d\n", block
, i
));
633 blocks in blocklist are relative to the first
634 sector of the HD (not partition)
636 D(bug("[install-i386] collectBlockList: successfully updated pointers for %d blocks\n", blk_count
));
639 for (count
=-1;count
>=blk_count
;count
--)
641 blocklist
[count
].sector
+= volume
->startblock
;
642 blocklist
[count
].seg_adr
= 0x820 + (i
*32);
643 i
+= blocklist
[count
].count
;
644 D(bug("[install-i386] collectBlockList: correcting block %d for partition start\n", count
));
645 D(bug("[install-i386] collectBlockList: sector : %x seg_adr : %x\n", blocklist
[count
].sector
, blocklist
[count
].seg_adr
));
650 void copyRootPath(char *dst
, char *rpdos
, BOOL isRDB
) {
652 D(bug("[install-i386] copyRootPath()\n"));
656 /* we have an RDB so use devicename */
658 while ((*rpdos
) && (*rpdos
!=':'))
663 while ((*rpdos
) && (*rpdos
!=':'))
666 rpdos
++; /* skip colon */
677 UBYTE
*memstr(UBYTE
*mem
, UBYTE
*str
, LONG len
) {
690 while ((*search
) && (left
) && (*next
++ == *search
++))
699 BOOL
setupMenu(BPTR fh
)
703 UBYTE
*buffer
= NULL
;
706 UBYTE
*position
= NULL
;
713 "configfile /dh0/boot/grub/menu.lst\n";
715 D(bug("[install-i386] setupMenu(%x)\n", fh
));
717 /* Get the filesize and reset the position */
718 Seek(fh
, 0, OFFSET_END
);
719 length
= Seek(fh
, 0, OFFSET_BEGINNING
);
721 /* Allocate memory for file data */
722 buffer
= AllocVec(length
, MEMF_ANY
);
723 if (buffer
== NULL
) goto error
;
725 /* Read in the entire file */
726 read
= Read(fh
, buffer
, length
);
729 printf("ERROR: Could not read entire file.\n");
733 /* Find begin marker */
734 start
= memstr(buffer
, "# [B] (DO NOT REMOVE THIS LINE!)", length
);
737 printf("ERROR: Could not find start marker!?\n");
740 start
+= strlen("# [B] (DO NOT REMOVE THIS LINE!)") + 2;
742 /* Find end marker */
743 stop
= memstr(buffer
, "# [E] (DO NOT REMOVE THIS LINE!)", length
);
746 printf("ERROR: Could not find stop marker!?\n");
750 /* Check if there is enough space */
751 if ((stop
- start
) < strlen(line
))
753 printf("ERROR: Not enough space to setup menu.\n");
757 /* Write the new menu config */
758 strlcpy(start
, line
, stop
- start
- 1);
761 for (position
= start
+ strlen(line
); position
< stop
; position
++)
766 /* Write the new file out */
767 Seek(fh
, 0, OFFSET_BEGINNING
);
768 Write(fh
, buffer
, length
);
775 if (buffer
!= NULL
) FreeVec(buffer
);
785 struct Volume
*volume
792 D(bug("[install-i386] writeStage2(%x)\n", volume
));
794 if (Seek(fh
, 0, OFFSET_BEGINNING
) != -1)
796 /* write back first block */
797 if (Write(fh
, buffer
, 512)==512)
799 /* read second stage2 block */
800 if (Read(fh
, buffer
, 512) == 512)
802 /* set partition number where stage2 is on */
805 buffer
[10] = volume
->partnum
;
807 /* get ptr to version string */
808 menuname
= buffer
+18;
809 while (*menuname
++); /* skip version string */
810 copyRootPath(menuname
, menupath
, volume
->flags
& VF_IS_RDB
);
811 strcat(menuname
, "/menu.lst");
812 /* write second stage2 block back */
813 if (Seek(fh
, -512, OFFSET_CURRENT
) != -1)
815 if (Write(fh
, buffer
, 512) == 512)
821 printf("%s: Write Error\n", menuname
);
824 printf("%s: Seek Error\n", menuname
);
827 printf("Read Error\n");
830 printf("Write Error\n");
833 PrintFault(IoErr(), NULL
);
839 STRPTR stage2path
, /* path of stage2 file */
840 STRPTR kernelpath
, /* path of the kernel image */
841 struct Volume
*volume
, /* volume stage2 is on */
842 ULONG
*buffer
/* a buffer of at least 512 bytes */
846 struct FileInfoBlock fib
;
849 D(bug("[install-i386] changeStage2(%x)\n", volume
));
851 fh
= Open(stage2path
, MODE_OLDFILE
);
854 if (Examine(fh
, &fib
))
856 if (Read(fh
, buffer
, 512) == 512)
859 get and store all blocks of stage2 in first block of stage2
860 first block of stage2 will be returned
862 block
= collectBlockList
863 (volume
, fib
.fib_DiskKey
, (struct BlockNode
*)&buffer
[128]);
867 if (!writeStage2(fh
, (UBYTE
*)buffer
, kernelpath
, volume
))
872 printf("%s: Read Error\n", stage2path
);
875 PrintFault(IoErr(), stage2path
);
879 PrintFault(IoErr(), stage2path
);
886 struct Volume
*volume
,
887 struct Volume
*s2vol
,
888 ULONG block
, /* first block of stage2 file */
896 D(bug("[install-i386] writeStage1(%x)\n", volume
));
898 fh
= Open(stage1path
, MODE_OLDFILE
);
901 if (Read(fh
, volume
->blockbuffer
, 512) == 512)
903 /* install into MBR ? */
904 if ((volume
->startblock
== 0) && (!(volume
->flags
& VF_IS_TRACKDISK
)))
906 D(bug("[install-i386] writeStage1: Install to HARDDISK\n"));
908 error
= readwriteBlock
909 (volume
, 0, s2vol
->blockbuffer
, 512, volume
->readcmd
);
911 D(bug("[install-i386] writeStage1: MBR Buffer @ %x\n", volume
->blockbuffer
));
912 D(bug("[install-i386] writeStage1: Copying MBR BPB to %x\n", (char *)volume
->blockbuffer
+ 0x04));
913 // copy BPB (BIOS Parameter Block)
916 (APTR
)((char *)s2vol
->blockbuffer
+ 0x04),
917 (APTR
)((char *)volume
->blockbuffer
+ 0x04),
920 // copy partition table - [Overwrites Floppy boot code]
921 D(bug("[install-i386] writeStage1: Copying MBR Partitions to %x\n", (char *)volume
->blockbuffer
+ MBR_PARTSTART
));
924 (APTR
)((char *)s2vol
->blockbuffer
+ MBR_PARTSTART
),
925 (APTR
)((char *)volume
->blockbuffer
+ MBR_PARTSTART
),
926 (MBR_PARTEND
- MBR_PARTSTART
)
928 // store the drive num stage2 is stored on
929 ((char *)volume
->blockbuffer
)[GRUB_BOOT_DRIVE
] = unit
+ BIOS_HDISK_FLAG
;
930 // Store the stage 2 pointer ..
931 ULONG
* stage2_sector_start
= (ULONG
*)((char *)volume
->blockbuffer
+ GRUB_STAGE2_SECTOR
);
932 D(bug("[install-i386] writeStage1: writing stage2 pointer @ %x\n", stage2_sector_start
));
933 stage2_sector_start
[0] = block
;
934 D(bug("[install-i386] writeStage1: stage2 pointer = %x\n", stage2_sector_start
[0]));
935 stage2_sector_start
[0] += s2vol
->startblock
;
936 D(bug("[install-i386] writeStage1: + offset [%d] = %x\n", s2vol
->startblock
, stage2_sector_start
[0]));
940 D(bug("[install-i386] writeStage1: Forcing LBA\n"));
941 ((char *)volume
->blockbuffer
)[GRUB_FORCE_LBA
] = 1;
945 D(bug("[install-i386] writeStage1: NOT Forcing LBA\n"));
946 ((char *)volume
->blockbuffer
)[GRUB_FORCE_LBA
] = 0;
951 D(bug("[install-i386] writeStage1: Install to FLOPPY\n"));
956 error
= readwriteBlock
957 (volume
, 0, volume
->blockbuffer
, 512, volume
->writecmd
);
959 printf("WriteError %ld\n", error
);
964 printf("WriteError %ld\n", error
);
967 printf("%s: Read Error\n", stage1path
);
971 PrintFault(IoErr(), stage1path
);
975 /* Flushes the cache on the volume containing the specified path. */
976 VOID
flushFS(CONST TEXT
*path
)
981 for (i
= 0; path
[i
] != ':'; i
++)
982 devname
[i
] = path
[i
];
985 if (Inhibit(devname
, DOSTRUE
))
986 Inhibit(devname
, DOSFALSE
);
989 BOOL installStageFiles
991 struct Volume
*s2vol
, /* stage2 volume */
992 STRPTR stagepath
, /* path to stage* files */
993 STRPTR kernelpath
, /* path to kernel image */
994 ULONG unit
, /* unit stage2 is on */
995 struct Volume
*s1vol
/* device on which stage1 will be stored */
1002 D(bug("[install-i386] installStageFiles(%x)\n", s1vol
));
1004 /* Flush GRUB and kernel volumes' caches */
1006 flushFS(kernelpath
);
1008 AddPart(stagename
, stagepath
, 256);
1009 AddPart(stagename
, "stage2", 256);
1010 block
= changeStage2(stagename
, kernelpath
, s2vol
, s1vol
->blockbuffer
);
1013 AddPart(stagename
, stagepath
, 256);
1014 AddPart(stagename
, "stage1", 256);
1015 if (writeStage1(stagename
, s1vol
, s2vol
, block
, unit
))
1021 int main(int argc
, char **argv
) {
1023 struct RDArgs
*rdargs
;
1024 struct Volume
*grubvol
;
1025 struct Volume
*bbvol
;
1026 struct FileSysStartupMsg
*fssm
;
1028 D(bug("[install-i386] main()\n"));
1030 rdargs
= ReadArgs(template, myargs
, NULL
);
1033 D(bug("[install-i386] FORCELBA = %d\n",myargs
[5]));
1035 fssm
= getDiskFSSM((STRPTR
)myargs
[3]);
1036 if ((fssm
) && (getDiskFSSM((STRPTR
)myargs
[4])))
1039 (strcmp(AROS_BSTR_ADDR(fssm
->fssm_Device
),(char*)myargs
[0])==0)
1040 // && (fssm->fssm_Unit == *((LONG *)myargs[1]))
1043 grubvol
= getGrubStageVolume
1045 AROS_BSTR_ADDR(fssm
->fssm_Device
),
1048 (struct DosEnvec
*)BADDR(fssm
->fssm_Environ
)
1055 *((LONG
*)myargs
[1]),
1062 getBBVolume() read block 0
1063 if the partition directly contains a filesystem
1064 (currently only DOS\x is supported) we have
1065 to move block 0 to block 1 to make space for stage1
1068 (grubvol
->startblock
== bbvol
->startblock
) &&
1069 ((AROS_BE2LONG(bbvol
->blockbuffer
[0]) & 0xFFFFFF00)==0x444F5300)
1072 grubvol
->flags
&= ~VF_IS_RDB
;
1073 retval
= readwriteBlock
1074 (bbvol
, 0, bbvol
->blockbuffer
, 512, bbvol
->readcmd
);
1081 (STRPTR
)myargs
[3], /* grub path (stage1/2) */
1082 (STRPTR
)myargs
[4], /* kernel path */
1088 printf("Read Error: %ld\n", retval
);
1089 uninitVolume(bbvol
);
1091 uninitVolume(grubvol
);
1098 "%s is not on device %s unit %ld\n",
1099 (STRPTR
)myargs
[3], (STRPTR
)myargs
[0], *((LONG
*)myargs
[1])
1105 printf("kernel path must begin with a device name\n");
1109 PrintFault(IoErr(), argv
[0]);