Ejemplo n.º 1
0
/*
 * Search for the Rigid Disk Block. The rigid disk block is required
 * to be within the first 16 blocks of a drive, needs to have
 * the ID AMIGA_ID_RDISK ('RDSK') and needs to have a valid
 * sum-to-zero checksum
 */
struct rigid_disk_block *get_rdisk(struct blk_desc *dev_desc)
{
    int i;
    int limit;
    char *s;

    s = getenv("amiga_scanlimit");
    if (s)
	limit = simple_strtoul(s, NULL, 10);
    else
	limit = AMIGA_BLOCK_LIMIT;

    for (i=0; i<limit; i++)
    {
	ulong res = blk_dread(dev_desc, i, 1, (ulong *)block_buffer);
	if (res == 1)
	{
	    struct rigid_disk_block *trdb = (struct rigid_disk_block *)block_buffer;
	    if (trdb->id == AMIGA_ID_RDISK)
	    {
		PRINTF("Rigid disk block suspect at %d, checking checksum\n",i);
		if (sum_block((struct block_header *)block_buffer) == 0)
		{
		    PRINTF("FOUND\n");
		    memcpy(&rdb, trdb, sizeof(struct rigid_disk_block));
		    return (struct rigid_disk_block *)&rdb;
		}
	    }
	}
    }
    PRINTF("Done scanning, no RDB found\n");
    return NULL;
}
Ejemplo n.º 2
0
void print_part_amiga (block_dev_desc_t *dev_desc)
{
    struct rigid_disk_block *rdb;
    struct bootcode_block *boot;
    struct partition_block *p;
    u32 block;
    int i = 1;

    rdb = get_rdisk(dev_desc);
    if (!rdb)
    {
	PRINTF("print_part_amiga: no rdb found\n");
	return;
    }

    PRINTF("print_part_amiga: Scanning partition list\n");

    block = rdb->partition_list;
    PRINTF("print_part_amiga: partition list at 0x%x\n", block);

    printf("Summary:  DiskBlockSize: %d\n"
	   "          Cylinders    : %d\n"
	   "          Sectors/Track: %d\n"
	   "          Heads        : %d\n\n",
	   rdb->block_bytes, rdb->cylinders, rdb->sectors,
	   rdb->heads);

    printf("                 First   Num. \n"
	   "Nr.  Part. Name  Block   Block  Type        Boot Priority\n");

    while (block != 0xFFFFFFFF)
    {
	ulong res;

	PRINTF("Trying to load block #0x%X\n", block);

	res = dev_desc->block_read(dev_desc->dev, block, 1,
				   (ulong *)block_buffer);
	if (res == 1)
	{
	    p = (struct partition_block *)block_buffer;
	    if (p->id == AMIGA_ID_PART)
	    {
		PRINTF("PART block suspect at 0x%x, checking checksum\n",block);
		if (sum_block((struct block_header *)p) == 0)
		{
		    printf("%-4d ", i); i++;
		    print_part_info(p);
		    block = p->next;
		}
	    } else block = 0xFFFFFFFF;
	} else block = 0xFFFFFFFF;
    }

    boot = get_bootcode(dev_desc);
    if (boot)
    {
	printf("Disk is bootable\n");
    }
}
Ejemplo n.º 3
0
/*
 * Find partition number partnum on the given drive.
 */
static struct partition_block *find_partition(struct blk_desc *dev_desc,
					      int partnum)
{
    struct rigid_disk_block *rdb;
    struct partition_block *p;
    u32 block;

    PRINTF("Trying to find partition block %d\n", partnum);
    rdb = get_rdisk(dev_desc);
    if (!rdb)
    {
	PRINTF("find_partition: no rdb found\n");
	return NULL;
    }

    PRINTF("find_partition: Scanning partition list\n");

    block = rdb->partition_list;
    PRINTF("find_partition: partition list at 0x%x\n", block);

    while (block != 0xFFFFFFFF)
    {
	ulong res = blk_dread(dev_desc, block, 1, (ulong *)block_buffer);
	if (res == 1)
	{
	    p = (struct partition_block *)block_buffer;
	    if (p->id == AMIGA_ID_PART)
	    {
		PRINTF("PART block suspect at 0x%x, checking checksum\n",block);
		if (sum_block((struct block_header *)p) == 0)
		{
		    if (partnum == 0) break;
		    else
		    {
			partnum--;
			block = p->next;
		    }
		}
	    } else block = 0xFFFFFFFF;
	} else block = 0xFFFFFFFF;
    }

    if (block == 0xFFFFFFFF)
    {
	PRINTF("PART block not found\n");
	return NULL;
    }

    return (struct partition_block *)block_buffer;
}
Ejemplo n.º 4
0
struct bootcode_block *get_bootcode(struct blk_desc *dev_desc)
{
    int i;
    int limit;
    char *s;

    s = getenv("amiga_scanlimit");
    if (s)
	limit = simple_strtoul(s, NULL, 10);
    else
	limit = AMIGA_BLOCK_LIMIT;

    PRINTF("Scanning for BOOT from 0 to %d\n", limit);

    for (i = 0; i < limit; i++)
    {
	ulong res = blk_dread(dev_desc, i, 1, (ulong *)block_buffer);
	if (res == 1)
	{
	    struct bootcode_block *boot = (struct bootcode_block *)block_buffer;
	    if (boot->id == AMIGA_ID_BOOT)
	    {
		PRINTF("BOOT block at %d, checking checksum\n", i);
		if (sum_block((struct block_header *)block_buffer) == 0)
		{
		    PRINTF("Found valid bootcode block\n");
		    memcpy(&bootcode, boot, sizeof(struct bootcode_block));
		    return &bootcode;
		}
	    }
	}
    }

    PRINTF("No boot code found on disk\n");
    return 0;
}
Ejemplo n.º 5
0
int do_boota (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
    unsigned char *load_address = (unsigned char *) CFG_LOAD_ADDR;
    unsigned char *base_address;
    unsigned long offset;

    unsigned long part_number = 0;
    block_dev_desc_t *boot_disk;
    char *s;
    struct bootcode_block *boot_code;

    /* Get parameters */

    switch (argc) {
    case 2:
        load_address = (unsigned char *) simple_strtol (argv[1], NULL, 16);
        part_number = 0;
        break;
    case 3:
        load_address = (unsigned char *) simple_strtol (argv[1], NULL, 16);
        part_number = simple_strtol (argv[2], NULL, 16);
        break;
    }

    base_address = load_address;

    PRINTF ("Loading boot code from disk %d to %p\n", part_number,
            load_address);

    /* Find the appropriate disk device */
    boot_disk = ide_get_dev (part_number);
    if (!boot_disk) {
        PRINTF ("Unknown disk %d\n", part_number);
        return 1;
    }

    /* Find the bootcode block */
    boot_code = get_bootcode (boot_disk);
    if (!boot_code) {
        PRINTF ("Not a bootable disk %d\n", part_number);
        return 1;
    }

    /* Only use the offset from the first block */
    offset = boot_code->load_data[0];
    memcpy (load_address, &boot_code->load_data[1], 122 * 4);
    load_address += 122 * 4;

    /* Setup for the loop */
    bblk.next = boot_code->next;
    boot_code = &bblk;

    /* Scan the chain, and copy the loader succesively into the destination area */
    while (0xffffffff != boot_code->next) {
        PRINTF ("Loading block %d\n", boot_code->next);

        /* Load block */
        if (1 !=
                boot_disk->block_read (boot_disk->dev, boot_code->next, 1,
                                       (ulong *) & bblk)) {
            PRINTF ("Read error\n");
            return 1;
        }

        /* check sum */
        if (sum_block ((struct block_header *) (ulong *) & bblk) != 0) {
            PRINTF ("Checksum error\n");
            return 1;
        }

        /* Ok, concatenate it to the already loaded code */
        memcpy (load_address, boot_code->load_data, 123 * 4);
        load_address += 123 * 4;
    }

    printf ("Bootcode loaded to %p (size %d)\n", base_address,
            load_address - base_address);
    printf ("Entry point at %p\n", base_address + offset);

    flush_cache (base_address, load_address - base_address);


    s = getenv ("autostart");
    if (s && strcmp (s, "yes") == 0) {
        DECLARE_GLOBAL_DATA_PTR;

        void (*boot) (bd_t *, char *, block_dev_desc_t *);
        char *args;

        boot = (void (*)(bd_t *, char *, block_dev_desc_t *)) (base_address + offset);
        boot (gd->bd, getenv ("amiga_bootargs"), boot_disk);
    }


    return 0;
}