/* * Test if the given partition has an Amiga partition table/Rigid * Disk block */ static int part_test_amiga(struct blk_desc *dev_desc) { struct rigid_disk_block *rdb; struct bootcode_block *bootcode; PRINTF("part_test_amiga: Testing for an Amiga RDB partition\n"); rdb = get_rdisk(dev_desc); if (rdb) { bootcode = get_bootcode(dev_desc); if (bootcode) PRINTF("part_test_amiga: bootable Amiga disk\n"); else PRINTF("part_test_amiga: non-bootable Amiga disk\n"); return 0; } else { PRINTF("part_test_amiga: no RDB found\n"); return -1; } }
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"); } }
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; }