Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 112 additions & 6 deletions app/aboot/aboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -1576,6 +1576,56 @@ void get_recovery_dtbo_info(uint32_t *dtbo_size, void **dtbo_buf)
return;
}

bool detect_android_from_mmc(void)
{
const char *ptn_names[] = {"boot", "real_boot"};
unsigned int i;
int index = INVALID_PTN;
unsigned long long ptn = 0;
uint64_t image_size = 0;
bool partition_found = false;
boot_img_hdr *hdr = (void*) buf;
static bool detected = false, result = false;

if (detected)
return result;

for (i = 0; i < ARRAY_SIZE(ptn_names); i++) {
index = partition_get_index(ptn_names[i]);
if (index != INVALID_PTN) {
ptn = partition_get_offset(index);
image_size = partition_get_size(index);
}
if (index != INVALID_PTN && ptn != 0 && image_size != 0) {
partition_found = true;
break;
}
dprintf(CRITICAL, "ERROR: No %s partition found\n", ptn_names[i]);
}

if (!partition_found) {
detected = true;
return result;
}

/* Set Lun for boot & recovery partitions */
mmc_set_lun(partition_get_lun(index));

if (mmc_read(ptn, (uint32_t *) buf, page_size)) {
dprintf(CRITICAL, "ERROR: Cannot read boot image header\n");
detected = true;
return result;
}

if (strstr((const char *)hdr->cmdline, "androidboot.")) {
dprintf(INFO, "Detected Android boot parameter\n");
result = true;
}

detected = true;
return result;
}

int boot_linux_from_mmc(void)
{
boot_img_hdr *hdr = (void*) buf;
Expand Down Expand Up @@ -1625,8 +1675,9 @@ int boot_linux_from_mmc(void)
#endif
struct kernel64_hdr *kptr = NULL;
int current_active_slot = INVALID;
bool try_alternate_partition = false;

if (!IS_ENABLED(ABOOT_STANDALONE) && check_format_bit())
if (detect_android_from_mmc() && check_format_bit())
boot_into_recovery = 1;

if (!IS_ENABLED(ABOOT_STANDALONE) && !boot_into_recovery) {
Expand All @@ -1653,6 +1704,7 @@ int boot_linux_from_mmc(void)
}
}

retry_boot:
index = partition_get_index(ptn_name);
ptn = partition_get_offset(index);
image_size = partition_get_size(index);
Expand All @@ -1670,8 +1722,21 @@ int boot_linux_from_mmc(void)
}

if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
dprintf(CRITICAL, "ERROR: Invalid boot image header\n");
return ERR_INVALID_BOOT_MAGIC;
dprintf(CRITICAL, "ERROR: Invalid boot image header on partition %s\n", ptn_name);
if (IS_ENABLED(WITH_LK2ND_DEVICE_2ND) && !try_alternate_partition) {
try_alternate_partition = true;
if (strcmp(ptn_name, "boot") == 0) {
ptn_name = "real_boot";
} else if (strcmp(ptn_name, "recovery") == 0) {
ptn_name = "real_recovery";
} else {
dprintf(CRITICAL, "No alternate partition for %s, Abort.\n", ptn_name);
return ERR_INVALID_BOOT_MAGIC;
}
dprintf(CRITICAL, "Retrying boot with %s partition\n", ptn_name);
goto retry_boot;
}
return ERR_INVALID_BOOT_MAGIC;
}

if (hdr->page_size && (hdr->page_size != page_size)) {
Expand Down Expand Up @@ -3168,7 +3233,9 @@ void cmd_boot(const char *arg, void *data, unsigned sz)
unsigned int kernel_size = 0;
enum boot_type boot_type = 0;
#if DEVICE_TREE
void * image_buf = NULL;
uint8_t dtb_copied = 0;
unsigned dtb_image_size = 0;
unsigned int scratch_offset = 0;
#endif
#if VERIFIED_BOOT_2
Expand All @@ -3184,6 +3251,9 @@ void cmd_boot(const char *arg, void *data, unsigned sz)
static bool is_mdtp_activated = 0;
#endif /* MDTP_SUPPORT */
#endif
#ifdef OSVERSION_IN_BOOTIMAGE
uint32_t dtb_image_offset = 0;
#endif

#if FBCON_DISPLAY_MSG
/* Exit keys' detection thread firstly */
Expand Down Expand Up @@ -3221,13 +3291,39 @@ void cmd_boot(const char *arg, void *data, unsigned sz)
dt_size = hdr->dt_size;
#endif
dt_actual = ROUND_TO_PAGE(dt_size, page_mask);
dtb_image_size = hdr->kernel_size;
#endif

image_actual = ADD_OF(page_size, kernel_actual);
image_actual = ADD_OF(image_actual, ramdisk_actual);
image_actual = ADD_OF(image_actual, second_actual);
image_actual = ADD_OF(image_actual, dt_actual);

#ifdef OSVERSION_IN_BOOTIMAGE
if (hdr->header_version == BOOT_HEADER_VERSION_TWO) {
struct boot_img_hdr_v1 *hdr1 =
(struct boot_img_hdr_v1 *) (data + sizeof(boot_img_hdr));
struct boot_img_hdr_v2 *hdr2 = (struct boot_img_hdr_v2 *)
(data + sizeof(boot_img_hdr) +
BOOT_IMAGE_HEADER_V2_OFFSET);
unsigned int recovery_dtbo_actual = 0;

recovery_dtbo_actual =
ROUND_TO_PAGE(hdr1->recovery_dtbo_size, page_mask);
image_actual += recovery_dtbo_actual;

image_actual += ROUND_TO_PAGE(hdr2->dtb_size, page_mask);


dtb_image_offset = page_size +/* patched_kernel_hdr_size +*/
kernel_actual + ramdisk_actual + second_actual +
recovery_dtbo_actual;

dprintf(SPEW, "Header version: %d\n", hdr->header_version);
dprintf(SPEW, "Dtb image offset 0x%x\n", dtb_image_offset);
}
#endif

/* Checking to prevent oob access in read_der_message_length */
if (image_actual > sz) {
fastboot_fail("bootimage header fields are invalid");
Expand Down Expand Up @@ -3439,10 +3535,20 @@ void cmd_boot(const char *arg, void *data, unsigned sz)
* memory address to the DTB appended location on RAM.
* Else update with the atags address in the kernel header
*/
image_buf = (void*)(ptr + page_size);

#ifdef OSVERSION_IN_BOOTIMAGE
if ( hdr->header_version == BOOT_HEADER_VERSION_TWO) {
image_buf = (void*)(ptr);
dtb_offset = dtb_image_offset;
dtb_image_size = image_actual;
}
#endif

if (!dtb_copied) {
void *dtb;
dtb = dev_tree_appended((void*)(ptr + page_size),
hdr->kernel_size, dtb_offset,
dtb = dev_tree_appended(image_buf,
dtb_image_size, dtb_offset,
(void *)hdr->tags_addr);
#if WITH_LK2ND_DEVICE_2ND
if (!dtb && lk2nd_device2nd_have_atags())
Expand Down Expand Up @@ -5658,7 +5764,7 @@ void aboot_init(const struct app_descriptor *app)

if (target_is_emmc_boot())
{
if(!IS_ENABLED(ABOOT_STANDALONE) && emmc_recovery_init())
if(detect_android_from_mmc() && emmc_recovery_init())
dprintf(ALWAYS,"error in emmc_recovery_init\n");
if(target_use_signed_kernel())
{
Expand Down
4 changes: 3 additions & 1 deletion app/aboot/recovery.c
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ int send_recovery_cmd(const char *command)

int _emmc_recovery_init(void)
{
int update_status = 0;
int update_status __attribute__((unused)) = 0;
struct recovery_message *msg;
uint32_t block_size = 0;

Expand Down Expand Up @@ -428,6 +428,7 @@ int _emmc_recovery_init(void)
boot_into_recovery = 1;
}

#if !ABOOT_STANDALONE
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you tried

if (IS_ENABLED(ABOOT_STANDALONE))
	goto out;

(Not sure if that code causes compile errors...)

Rule of thumb: Avoid macros where possible, this improves compile testing. I'm not saying goto is great, but the jump label is there already, so not our fault. >:D

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep, some of those code should cause compilation errors...

as far as I can see, reset_device_info() and set_device_root() functions are already excluded by macro !ABOOT_STANDALONE in commit app: aboot: Avoid using special partitions using ABOOT_STANDALONE=1, and those code is calling that two functions

if (!strcmp("update-radio",msg->command))
{
/* We're now here due to radio update, so check for update status */
Expand Down Expand Up @@ -460,6 +461,7 @@ int _emmc_recovery_init(void)
emmc_set_recovery_msg(msg); // send recovery message

out:
#endif
if(msg)
free(msg);
return 0;
Expand Down
1 change: 0 additions & 1 deletion app/aboot/rules.mk
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ OBJS += \

ifeq ($(ABOOT_STANDALONE), 1)
DEFINES += ABOOT_STANDALONE=1
OBJS := $(filter-out $(LOCAL_DIR)/recovery.o, $(OBJS))
DEFINES := $(filter-out SSD_ENABLE TZ_SAVE_KERNEL_HASH TZ_TAMPER_FUSE, $(DEFINES))
endif

Expand Down
45 changes: 38 additions & 7 deletions lk2nd/device/2nd/partition.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
static void partition_split_mmc(const char *base_name, const char *name,
uint32_t num_blocks, bool end)
{
struct partition_entry *base, *split;
struct partition_entry *backup, *base, *split;
int index = partition_get_index(base_name);

if (index == INVALID_PTN) {
Expand All @@ -29,6 +29,15 @@ static void partition_split_mmc(const char *base_name, const char *name,
return;
}

backup = partition_allocate();
if (backup) {
memcpy(backup, base, sizeof(*backup));
snprintf((char*)backup->name, sizeof(backup->name), "real_%s", base_name);
} else {
dprintf(CRITICAL, "Too many partitions, cannot backup %s partition entry\n",
base_name);
}

split = partition_allocate();
if (split) {
memcpy(split, base, sizeof(*split));
Expand Down Expand Up @@ -67,6 +76,16 @@ static void partition_split_flash(struct ptable *ptable, const char *base_name,
return;
}

if (ptable_size(ptable) < MAX_PTABLE_PARTS) {
char backup_name[MAX_PTENTRY_NAME];
snprintf(backup_name, sizeof(backup_name), "real_%s", base_name);
ptable_add(ptable, backup_name, base->start, base->length,
base->flags, base->type, base->perm);
} else {
dprintf(CRITICAL, "Too many partitions, cannot backup %s partition entry\n",
base_name);
}

if (ptable_size(ptable) < MAX_PTABLE_PARTS) {
unsigned start = base->start;
if (end)
Expand All @@ -88,9 +107,15 @@ static void lk2nd_partition_split_mmc(void)
{
uint32_t block_size __UNUSED = mmc_get_device_blocksize();

#ifdef LK2ND_PARTITION_SIZE
partition_split_mmc(LK2ND_PARTITION_BASE, LK2ND_PARTITION_NAME,
LK2ND_PARTITION_SIZE / block_size, false);
#ifdef LK2ND_BOOT_PARTITION_SIZE
partition_split_mmc(LK2ND_BOOT_PARTITION_BASE,
LK2ND_BOOT_PARTITION_NAME,
LK2ND_BOOT_PARTITION_SIZE / block_size, false);
#endif
#ifdef LK2ND_RECOVERY_PARTITION_SIZE
partition_split_mmc(LK2ND_RECOVERY_PARTITION_BASE,
LK2ND_RECOVERY_PARTITION_NAME,
LK2ND_RECOVERY_PARTITION_SIZE / block_size, false);
#endif
}

Expand All @@ -102,9 +127,15 @@ static void lk2nd_partition_split_flash(void)
if (!ptable)
return;

#ifdef LK2ND_PARTITION_SIZE
partition_split_flash(ptable, LK2ND_PARTITION_BASE, LK2ND_PARTITION_NAME,
LK2ND_PARTITION_SIZE / block_size, false);
#ifdef LK2ND_BOOT_PARTITION_SIZE
partition_split_flash(ptable, LK2ND_BOOT_PARTITION_BASE,
LK2ND_BOOT_PARTITION_NAME,
LK2ND_BOOT_PARTITION_SIZE / block_size, false);
#endif
#ifdef LK2ND_RECOVERY_PARTITION_SIZE
partition_split_flash(ptable, LK2ND_RECOVERY_PARTITION_BASE,
LK2ND_RECOVERY_PARTITION_NAME,
LK2ND_RECOVERY_PARTITION_SIZE / block_size, false);
#endif
}

Expand Down
14 changes: 10 additions & 4 deletions lk2nd/device/2nd/rules.mk
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,17 @@ OBJS += \
$(LOCAL_DIR)/samsung-muic-reset.o \
$(if $(filter %/mdss_spi.o, $(OBJS)), $(LOCAL_DIR)/spi-display.o) \

ifneq ($(LK2ND_PARTITION_SIZE),)
ifneq ($(LK2ND_BOOT_PARTITION_SIZE),)
DEFINES += \
LK2ND_PARTITION_BASE="$(LK2ND_PARTITION_BASE)" \
LK2ND_PARTITION_NAME="$(LK2ND_PARTITION_NAME)" \
LK2ND_PARTITION_SIZE=($(LK2ND_PARTITION_SIZE))
LK2ND_BOOT_PARTITION_BASE="$(LK2ND_BOOT_PARTITION_BASE)" \
LK2ND_BOOT_PARTITION_NAME="$(LK2ND_BOOT_PARTITION_NAME)" \
LK2ND_BOOT_PARTITION_SIZE=($(LK2ND_BOOT_PARTITION_SIZE))
endif
ifneq ($(LK2ND_RECOVERY_PARTITION_SIZE),)
DEFINES += \
LK2ND_RECOVERY_PARTITION_BASE="$(LK2ND_RECOVERY_PARTITION_BASE)" \
LK2ND_RECOVERY_PARTITION_NAME="$(LK2ND_RECOVERY_PARTITION_NAME)" \
LK2ND_RECOVERY_PARTITION_SIZE=($(LK2ND_RECOVERY_PARTITION_SIZE))
endif

include $(if $(BUILD_GPL),$(LOCAL_DIR)/gpl/rules.mk)
Expand Down
6 changes: 6 additions & 0 deletions lk2nd/project/base.mk
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,15 @@ DEFINES += GENERATE_CMDLINE_ONLY_FOR_ANDROID=1
# Disable reading splash partition to avoid crashes on some devices
DEFINES += DISABLE_SPLASH_PARTITION=1

# Disable updating Android fstab devicetree node
DEFINES += SKIP_UPDATE_ANDROID_FSTAB=1

# Enable "fastboot oem help" for a list of supported fastboot commands
DEFINES += FASTBOOT_HELP=1

# Enable Android dynamic partitions support
DEFINES += DYNAMIC_PARTITION_SUPPORT=1

# Allow entering fastboot after forced reset
DEFINES := $(filter-out USER_FORCE_RESET_SUPPORT=1, $(DEFINES))

Expand Down
13 changes: 8 additions & 5 deletions lk2nd/project/lk2nd.mk
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@ ifneq ($(ENABLE_FBCON_DISPLAY_MSG),1)
MODULES += $(if $(filter $(MODULES), lk2nd/display), lk2nd/device/menu)
endif

# Use part of the "boot" partition for the lk2nd boot image. The real Android
# boot image can be placed in the partition with 512 KiB offset.
LK2ND_PARTITION_BASE ?= boot
LK2ND_PARTITION_NAME ?= lk2nd
LK2ND_PARTITION_SIZE ?= 512*1024
# Use part of the "boot" and "recovery" partition for the lk2nd boot image.
# The real Android boot image can be placed in the partition with 512 KiB offset.
LK2ND_BOOT_PARTITION_BASE ?= boot
LK2ND_BOOT_PARTITION_NAME ?= lk2nd
LK2ND_BOOT_PARTITION_SIZE ?= 512*1024
LK2ND_RECOVERY_PARTITION_BASE ?= recovery
LK2ND_RECOVERY_PARTITION_NAME ?= lk2nd_recovery
LK2ND_RECOVERY_PARTITION_SIZE ?= 512*1024

# The primary bootloader will implement LONG_PRESS_POWER_ON if needed.
# If we do it again in lk2nd we might accidentally shutdown the device because
Expand Down
4 changes: 4 additions & 0 deletions makefile
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ ifeq ($(DYNAMIC_PARTITION_SUPPORT),1)
DEFINES += DYNAMIC_PARTITION_SUPPORT=1
endif

ifeq ($(SKIP_UPDATE_ANDROID_FSTAB),1)
DEFINES += SKIP_UPDATE_ANDROID_FSTAB=1
endif

ifeq ($(TARGET_DTBO_NOT_SUPPORTED),1)
DEFINES += TARGET_DTBO_NOT_SUPPORTED=1
endif
Expand Down
Loading
Loading