示例#1
0
// vol->lock must be held!
static int _volmgr_consider_disk_and_vol(volume_t *vol, blkdev_t *dev)
{
    int rc = 0;

#if DEBUG_VOLMGR
    LOG_VOL("volmgr_consider_disk_and_vol(%s, %d:%d):", vol->mount_point,
            dev->major, dev->minor); 
#endif

    if (vol->state == volstate_unknown ||
        vol->state == volstate_mounted ||
        vol->state == volstate_mounted_ro) {
        LOGE("Cannot consider volume '%s' because it is in state '%d", 
             vol->mount_point, vol->state);
        return -EADDRINUSE;
    }

    if (vol->state == volstate_formatting) {
        LOG_VOL("Evaluating dev '%s' for formattable filesystems for '%s'",
                dev->devpath, vol->mount_point);
        /*
         * Since we only support creating 1 partition (right now),
         * we can just lookup the target by devno
         */
        blkdev_t *part;
        if (vol->media_type == media_mmc)
            part = blkdev_lookup_by_devno(dev->major, ALIGN_MMC_MINOR(dev->minor) + 1);
        else
            part = blkdev_lookup_by_devno(dev->major, 1);
        if (!part) {
            if (vol->media_type == media_mmc)
                part = blkdev_lookup_by_devno(dev->major, ALIGN_MMC_MINOR(dev->minor));
            else
                part = blkdev_lookup_by_devno(dev->major, 0);
            if (!part) {
                LOGE("Unable to find device to format");
                return -ENODEV;
            }
        }

        if ((rc = format_partition(part,
                                   vol->media_type == media_devmapper ?
                                   FORMAT_TYPE_EXT2 : FORMAT_TYPE_FAT32)) < 0) {
            LOGE("format failed (%d)", rc);
            return rc;
        }
        
    }

    LOGI("Evaluating dev '%s' for mountable filesystems for '%s'",
            dev->devpath, vol->mount_point);

    if (dev->nr_parts == 0) {
        rc = _volmgr_start(vol, dev);
#if DEBUG_VOLMGR
        LOG_VOL("_volmgr_start(%s, %d:%d) rc = %d", vol->mount_point,
                dev->major, dev->minor, rc);
#endif
    } else {
        /*
         * Device has multiple partitions
         * This is where interesting partition policies could be implemented.
         * For now just try them in sequence until one succeeds
         */
   
        rc = -ENODEV;
        int i;
        for (i = 0; i < dev->nr_parts; i++) {
            blkdev_t *part;
            if (vol->media_type == media_mmc)
                part = blkdev_lookup_by_devno(dev->major, ALIGN_MMC_MINOR(dev->minor) + (i+1));
            else
                part = blkdev_lookup_by_devno(dev->major, (i+1));
            if (!part) {
                LOGE("Error - unable to lookup partition for blkdev %d:%d",
                    dev->major, dev->minor);
                continue;
            }
            rc = _volmgr_start(vol, part);
#if DEBUG_VOLMGR
            LOG_VOL("_volmgr_start(%s, %d:%d) rc = %d",
                    vol->mount_point, part->major, part->minor, rc);
#endif
            if (!rc || rc == -EBUSY) 
                break;
        }

        if (rc == -ENODEV) {
            // Assert to make sure each partition had a backing blkdev
            LOGE("Internal consistency error");
            return 0;
        }
    }

    if (rc == -ENODATA) {
        LOGE("Device %d:%d contains no usable filesystems",
             dev->major, dev->minor);
        rc = 0;
    }

    return rc;
}
示例#2
0
/* 
 * Entry point of bootmenu 
 * Magic is Acer BL data structure, used as parameter for some functions.
 * 
 * - keystate at boot is loaded
 * - boot partition (primary or secondary) is loaded
 * - can continue boot, and force fastboot or recovery mode
 * 
 * boot_handle - pass to boot partition
 */
void main(void* global_handle, int boot_handle)
{
	/* Selected option in boot menu */
	int selected_option = 0;
	
	/* Key press: -1 nothing, 0 Vol DOWN, 1 Vol UP, 2 Power */
	enum key_type key_press = KEY_NONE;

	/* Which kernel image is booted */
	const char* boot_partition_str;
	const char* other_boot_partition_str;
	const char* boot_partition_attempt;
	
	/* Debug mode status */
	const char* debug_mode_str;
	const char* other_debug_mode_str;
	
	/* Print error, from which partition booting failed */
	char error_message[TEXT_LINE_CHARS + 1];
	
	/* Line builder - two color codes used */
	char line_builder[TEXT_LINE_CHARS + 8 + 1];
	
	int i, l;
	struct color* b;
	struct font_color* fc;
	
	error_message[0] = '\0';
		
	/* Initialize framebuffer */
	fb_init();
	
	/* Set title */
	fb_set_title(bootloader_id);
	
	/* Print it */
	fb_refresh();
	
	/* Ensure we have bootloader update */
	check_bootloader_update(global_handle);
		
	/* Read msc command */
	msc_cmd_read();
	
	/* First, check MSC command */
	if (!strncmp((const char*)msc_cmd.boot_command, MSC_CMD_RECOVERY, strlen(MSC_CMD_RECOVERY)))
		this_boot_mode = BM_RECOVERY;
	else if (!strncmp((const char*)msc_cmd.boot_command, MSC_CMD_FCTRY_RESET, strlen(MSC_CMD_FCTRY_RESET)))
		this_boot_mode = BM_FCTRY_RESET;
	else if (!strncmp((const char*)msc_cmd.boot_command, MSC_CMD_FASTBOOT, strlen(MSC_CMD_FASTBOOT)))
		this_boot_mode = BM_FASTBOOT;
	else if (!strncmp((const char*)msc_cmd.boot_command, MSC_CMD_BOOTMENU, strlen(MSC_CMD_BOOTMENU)))
		this_boot_mode = BM_BOOTMENU;
	else
		this_boot_mode = BM_NORMAL;
	
	msc_boot_mode = this_boot_mode;
	
	/* Evaluate key status */
	if (get_key_active(KEY_VOLUME_UP))
		this_boot_mode = BM_BOOTMENU;
	else if (get_key_active(KEY_VOLUME_DOWN))
		this_boot_mode = BM_RECOVERY;
		
	/* Clear boot command from msc */
	memset(msc_cmd.boot_command, 0, ARRAY_SIZE(msc_cmd.boot_command));
	msc_cmd_write();
	
	/* Evaluate boot mode */
	if (this_boot_mode == BM_NORMAL)
	{		
		if (msc_cmd.boot_partition == 0)
			boot_partition_attempt = "primary (LNX)";
		else
			boot_partition_attempt = "secondary (AKB)";
		
		boot_normal(msc_cmd.boot_partition, boot_handle);
		snprintf(error_message, ARRAY_SIZE(error_message), "ERROR: Invalid %s kernel image.", boot_partition_attempt);
	}
	else if (this_boot_mode == BM_RECOVERY)
	{
		boot_recovery(boot_handle);
		snprintf(error_message, ARRAY_SIZE(error_message), "ERROR: Invalid recovery (SOS) kernel image.");
	}
	else if (this_boot_mode == BM_FCTRY_RESET)
	{
		fb_set_status("Factory reset\n");
		
		/* Erase userdata */
		fb_printf("Erasing UDA partition...\n\n");
		fb_refresh();
		format_partition("UDA");
		 
		/* Erase cache */
		fb_printf("Erasing CAC partition...\n\n");
		fb_refresh();
		format_partition("CAC");
		
		/* Finished */
		fb_printf("Done.\n");
		fb_refresh();
		
		/* Sleep */
		sleep(5000);
		
		/* Reboot */
		reboot(global_handle);
		
		/* Reboot returned */
		bootmenu_error();
	}
	else if (this_boot_mode == BM_FASTBOOT)
	{
		/* Load fastboot */
		fastboot_main(global_handle, boot_handle, error_message, ARRAY_SIZE(error_message));
		
		/* Fastboot returned - show bootmenu */
	}
	
	/* Allright - now we're in bootmenu */
	
	/* Boot menu */
	while (1)
	{ 
		/* New frame */
		bootmenu_frame();
		
		/* Print current boot mode */
		if (msc_cmd.boot_partition == 0)
		{
			boot_partition_str = "Primary";
			other_boot_partition_str = "Secondary";
		}
		else
		{
			boot_partition_str = "Secondary";
			other_boot_partition_str = "Primary";
		}
		
		fb_printf("Current boot mode: %s kernel image\n", boot_partition_str);
		
		if (msc_cmd.debug_mode == 0)
		{
			debug_mode_str = "OFF";
			other_debug_mode_str = "ON";
		}
		else
		{
			debug_mode_str = "ON";
			other_debug_mode_str = "OFF";
		}
		
		fb_printf("Debug mode: %s\n\n", debug_mode_str);
		
		/* Print error if we're stuck in bootmenu */
		if (error_message[0] != '\0')
			fb_color_printf("%s\n\n", NULL, &error_text_color, error_message);
		else
			fb_printf("\n");
		
		/* Print options */
		for (i = 0; i < ARRAY_SIZE(boot_menu_items); i++)
		{
			memset(line_builder, 0x20, ARRAY_SIZE(line_builder));
			line_builder[ARRAY_SIZE(line_builder) - 1] = '\0';
			line_builder[ARRAY_SIZE(line_builder) - 2] = '\n';
			
			if (i == selected_option)
			{
				b = &highlight_color;
				fc = &highlight_text_color;
			}
			else
			{
				b = NULL;
				fc = &text_color;
			}
			
			if (i == 5)
				snprintf(line_builder, ARRAY_SIZE(line_builder), boot_menu_items[i], other_boot_partition_str);
			else if (i == 6)
				snprintf(line_builder, ARRAY_SIZE(line_builder), boot_menu_items[i], other_debug_mode_str);
			else
				snprintf(line_builder, ARRAY_SIZE(line_builder), boot_menu_items[i]);
			
			l = strlen(line_builder);
			if (l == ARRAY_SIZE(line_builder) - 1)
				line_builder[ARRAY_SIZE(line_builder) - 2] = '\n';
			else if (l < ARRAY_SIZE(line_builder) - 1)
				line_builder[l] = ' ';
			
			fb_color_printf(line_builder, b, fc);
		}
		
		/* Draw framebuffer */
		fb_refresh();
		
		key_press = wait_for_key_event();
		
		if (key_press == KEY_NONE)
			continue;
		
		/* Volume DOWN */
		if (key_press == KEY_VOLUME_DOWN)
		{
			selected_option++;
			
			if (selected_option >= ARRAY_SIZE(boot_menu_items))
				selected_option = 0;
			
			continue;
		}
		
		/* Volume UP */
		if (key_press == KEY_VOLUME_UP)
		{
			selected_option--;
			
			if (selected_option < 0)
				selected_option = ARRAY_SIZE(boot_menu_items) - 1;
			
			continue;
		}
		
		/* Power */
		if (key_press == KEY_POWER)
		{
			switch(selected_option)
			{
				case 0: /* Reboot */
					reboot(global_handle);
					
					/* Reboot returned */
					bootmenu_error();
					
				case 1: /* Fastboot mode */
					fastboot_main(global_handle, boot_handle, error_message, ARRAY_SIZE(error_message));
					
					/* Returned? Continue bootmenu */
					break;
				
				case 2: /* Primary kernel image */
					boot_normal(0, boot_handle);
					snprintf(error_message, ARRAY_SIZE(error_message), "ERROR: Invalid primary (LNX) kernel image.");
					break;
					
				case 3: /* Secondary kernel image */
					boot_normal(1, boot_handle);
					snprintf(error_message, ARRAY_SIZE(error_message), "ERROR: Invalid secondary (AKB) kernel image.");
					break;
					
				case 4: /* Recovery kernel image */
					boot_recovery(boot_handle);
					snprintf(error_message, ARRAY_SIZE(error_message), "ERROR: Invalid recovery (SOS) kernel image.");
					break;
					
				case 5: /* Toggle boot kernel image */
					msc_cmd.boot_partition = !msc_cmd.boot_partition;
					msc_cmd_write();
					selected_option = 0;
					break;
					
				case 6: /* Toggle debug mode */
					msc_cmd.debug_mode = !msc_cmd.debug_mode;
					msc_cmd_write();
					selected_option = 0;
					break;
					
				case 7: /* Wipe cache */
					bootmenu_basic_frame();
					fb_set_status("Bootmenu Mode");
					fb_printf("Erasing CAC partition...\n\n");
					fb_refresh();
					
					format_partition("CAC");
					
					fb_printf("Done.\n");
					fb_refresh();
					sleep(2000);
					
					selected_option = 0;
					break;
			}
		}
		
	}
}