/* find first device whose first partition is a DOS filesystem */ int find_fat_partition (void) { int i, j; block_dev_desc_t *dev_desc; unsigned char *part_table; unsigned char buffer[ATA_BLOCKSIZE]; for (i = 0; i < CONFIG_SYS_IDE_MAXDEVICE; i++) { dev_desc = ide_get_dev (i); if (!dev_desc) { debug ("couldn't get ide device!\n"); return (-1); } if (dev_desc->part_type == PART_TYPE_DOS) { if (dev_desc-> block_read (dev_desc->dev, 0, 1, (ulong *) buffer) != 1) { debug ("can't perform block_read!\n"); return (-1); } part_table = &buffer[0x1be]; /* start with partition #4 */ for (j = 0; j < 4; j++) { if ((part_table[4] == 1 || /* 12-bit FAT */ part_table[4] == 4 || /* 16-bit FAT */ part_table[4] == 6) && /* > 32Meg part */ part_table[0] == 0x80) { /* bootable? */ curr_dev = i; part_offset = part_table[11]; part_offset <<= 8; part_offset |= part_table[10]; part_offset <<= 8; part_offset |= part_table[9]; part_offset <<= 8; part_offset |= part_table[8]; debug ("found partition start at %ld\n", part_offset); return (0); } part_table += 16; } } } debug ("no valid devices found!\n"); return (-1); }
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; }
int do_bootext2 (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { int dev,part,active_part= -1 ; ulong addr; volatile disk_partition_t info[2]; volatile char *env,*env2; block_dev_desc_t *dev_desc; ulong boot_part[MAX_BOOT_PART]; char *ep; if (argc != 5) { printf ("Usage:\n%s\n", cmdtp->usage); return 1; } dev = simple_strtoul(argv[1], &ep, 16); if (*ep) { if (*ep != ':') { printf ("Usage:\n%s\n", cmdtp->usage); return(1); } for (part=0 ; part < MAX_BOOT_PART-1 ; part++) { ep++; boot_part[part] = (ulong)simple_strtoul(ep, &ep, 16); if (*ep != ',') { printf ("Usage:\n%s\n", cmdtp->usage); return(1); } } boot_part[part] = (ulong)simple_strtoul(++ep, NULL, 16); } else { puts ("\n** Invalid boot device, use `dev:boot_part1,boot_part2' **\n"); return(1); } addr = simple_strtoul(argv[2], NULL, 16); dev_desc = (dev >= CFG_IDE_MAXDEVICE) ? NULL : ide_get_dev(dev); if (dev_desc == NULL) { printf("Non valid dev number %x\n",dev); return 1; } /* Initialize IDE */ sprintf(tmp_string,"ide reset"); run_command(tmp_string,0); /* Search for Active partition in partition #1 and partition #2*/ for (part = 0; part < MAX_BOOT_PART ;part++ ) { if (get_partition_info (dev_desc, boot_part[part], (disk_partition_t*)&info[part])) { continue; } if (info[part].boot_ind ) { active_part = part; break; } } /* If no active partition then return */ if (active_part == -1) { printf("No active partition on %d and %d\n", boot_part[0],boot_part[1]); return 1; } /* Load /boot/uImage from active_part to addr */ sprintf(tmp_string,"ext2load ide %x:%x %x %s", dev, boot_part[active_part], addr,argv[3]); printf("%s\n",tmp_string); run_command(tmp_string,0); sprintf(tmp_string,"root=%s%d ro",argv[4],boot_part[active_part]); setenv("bootargs_root",tmp_string); env = getenv("bootargs"); env2 = getenv("bootargs_root"); /* Save bootargs for secondary boot option if boot from active partition will fail */ sprintf(tmp_string1,"%s",env); sprintf(tmp_string,"%s %s",env,env2); setenv("bootargs",tmp_string); sprintf(tmp_string,"bootm %x", addr); printf("%s\n",tmp_string); run_command(tmp_string,0); /* If we get here then first boot fail */ active_part = (active_part + 1)%MAX_BOOT_PART; sprintf(tmp_string,"ext2load ide %x:%x %x %s", dev, boot_part[active_part], addr,argv[3]); printf("%s\n",tmp_string); run_command(tmp_string,0); sprintf(tmp_string,"root=%s%d ro",argv[4],boot_part[active_part]); setenv("bootargs_root",tmp_string); env2 = getenv("bootargs_root"); sprintf(tmp_string,"%s %s %s",tmp_string1,env2, "boot_failure"); setenv("bootargs",tmp_string); sprintf(tmp_string,"bootm %x", addr); printf("Starting secondary boot...\n"); printf("%s\n",tmp_string); run_command(tmp_string,0); printf("Secondary boot fail...\n"); return 1; }