Skip to content

Commit 69d4db5

Browse files
committed
Updated: NO_KEXEC v4
No-kexec workaround version 4 for no kexec-hardboot kernels * MultiROM support for no kexec-hardboot enabled kernels. It has been tested on the HTC One M7, M8, M9 and HTC 10 as well as other devices successfully. * This commit is the multirom portion, which adds the real code for the workaround. Needs to be enabled in multirom.ini settings: (1) no_kexec=1 (refer to multirom.h for various values) or (2) preferably to do it in TWRP multirom-dev/Team-Win-Recovery-Project@0380d7b Note: * The following build flag needs to be added in BoardConfig: MR_NO_KEXEC := <value> where value is: - 1 true allowed -> No-Kexec is built but not enabled by default - 2 enabled -> No-Kexec is set to "only when needed" - 3 ui_confirm -> No-Kexec is set to "ask for confirmation" - 4 ui_choice -> No-Kexec is set to "choose boot method" - 5 forced -> No-Kexec is set to "force using no-kexec" please see http://forum.xda-developers.com/showpost.php?p=68738134&postcount=4 for a description of these options
1 parent bc0fa8c commit 69d4db5

10 files changed

+684
-0
lines changed

Android.mk

+5
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ LOCAL_C_INCLUDES += system/extras/libbootimg/include
4646

4747
include $(multirom_local_path)/device_defines.mk
4848

49+
MR_NO_KEXEC_MK_OPTIONS := true 1 allowed 2 enabled 3 ui_confirm 4 ui_choice 5 forced
50+
ifneq (,$(filter $(MR_NO_KEXEC), $(MR_NO_KEXEC_MK_OPTIONS)))
51+
LOCAL_SRC_FILES += no_kexec.c
52+
endif
53+
4954
ifneq ($(MR_DEVICE_HOOKS),)
5055
ifeq ($(MR_DEVICE_HOOKS_VER),)
5156
$(info MR_DEVICE_HOOKS is set but MR_DEVICE_HOOKS_VER is not specified!)

device_defines.mk

+20
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,26 @@ ifneq ($(MR_RD_ADDR),)
111111
LOCAL_CFLAGS += -DMR_RD_ADDR=$(MR_RD_ADDR)
112112
endif
113113

114+
MR_NO_KEXEC_MK_OPTIONS := true 1 allowed 2 enabled 3 ui_confirm 4 ui_choice 5 forced
115+
ifneq (,$(filter $(MR_NO_KEXEC), $(MR_NO_KEXEC_MK_OPTIONS)))
116+
ifneq (,$(filter $(MR_NO_KEXEC), true 1 allowed))
117+
# NO_KEXEC_DISABLED = 0x00, // no-kexec workaround disabled
118+
LOCAL_CFLAGS += -DMR_NO_KEXEC=0x00
119+
else ifneq (,$(filter $(MR_NO_KEXEC), 2 enabled))
120+
# NO_KEXEC_ALLOWED = 0x01, // "Use no-kexec only when needed"
121+
LOCAL_CFLAGS += -DMR_NO_KEXEC=0x01
122+
else ifneq (,$(filter $(MR_NO_KEXEC), 3 ui_confirm))
123+
# NO_KEXEC_CONFIRM = 0x02, // "..... but also ask for confirmation"
124+
LOCAL_CFLAGS += -DMR_NO_KEXEC=0x02
125+
else ifneq (,$(filter $(MR_NO_KEXEC), 4 ui_choice))
126+
# NO_KEXEC_CHOICE = 0x04, // "Ask whether to kexec or use no-kexec"
127+
LOCAL_CFLAGS += -DMR_NO_KEXEC=0x04
128+
else ifneq (,$(filter $(MR_NO_KEXEC), 5 forced))
129+
# NO_KEXEC_FORCED = 0x08, // "Always force using no-kexec workaround"
130+
LOCAL_CFLAGS += -DMR_NO_KEXEC=0x08
131+
endif
132+
endif
133+
114134
ifneq ($(MR_DEVICE_SPECIFIC_VERSION),)
115135
LOCAL_CFLAGS += -DMR_DEVICE_SPECIFIC_VERSION=\"$(MR_DEVICE_SPECIFIC_VERSION)\"
116136
endif

lib/Android.mk

+18
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,15 @@ LOCAL_CFLAGS += $(common_C_FLAGS)
6565
LOCAL_C_INCLUDES += $(common_C_INCLUDES)
6666
LOCAL_SRC_FILES := $(common_SRC_FILES)
6767

68+
MR_NO_KEXEC_MK_OPTIONS := true 1 allowed 2 enabled 3 ui_confirm 4 ui_choice 5 forced
69+
ifneq (,$(filter $(MR_NO_KEXEC), $(MR_NO_KEXEC_MK_OPTIONS)))
70+
# clone libbootimg to /system/extras/ from
71+
# https://github.com/Tasssadar/libbootimg.git
72+
LOCAL_STATIC_LIBRARIES += libbootimg
73+
LOCAL_C_INCLUDES += system/extras/libbootimg/include
74+
LOCAL_SRC_FILES += ../no_kexec.c
75+
endif
76+
6877
include $(multirom_local_path)/device_defines.mk
6978

7079
include $(BUILD_STATIC_LIBRARY)
@@ -80,6 +89,15 @@ LOCAL_CFLAGS += $(common_C_FLAGS)
8089
LOCAL_SRC_FILES := $(common_SRC_FILES)
8190
LOCAL_C_INCLUDES += $(common_C_INCLUDES)
8291

92+
MR_NO_KEXEC_MK_OPTIONS := true 1 allowed 2 enabled 3 ui_confirm 4 ui_choice 5 forced
93+
ifneq (,$(filter $(MR_NO_KEXEC), $(MR_NO_KEXEC_MK_OPTIONS)))
94+
# clone libbootimg to /system/extras/ from
95+
# https://github.com/Tasssadar/libbootimg.git
96+
LOCAL_STATIC_LIBRARIES += libbootimg
97+
LOCAL_C_INCLUDES += system/extras/libbootimg/include
98+
LOCAL_SRC_FILES += ../no_kexec.c
99+
endif
100+
83101
include $(multirom_local_path)/device_defines.mk
84102

85103
include $(BUILD_SHARED_LIBRARY)

lib/mrom_data.c

+10
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818
#include <string.h>
1919
#include <stdio.h>
2020

21+
#ifdef MR_NO_KEXEC
22+
#include "../no_kexec.h"
23+
#endif
24+
2125
#include "mrom_data.h"
2226

2327
static char multirom_dir[128] = { 0 };
@@ -84,6 +88,12 @@ int mrom_is_second_boot(void)
8488
}
8589
}
8690

91+
#ifdef MR_NO_KEXEC
92+
res = nokexec_is_second_boot();
93+
if (res < 0)
94+
res = 0;
95+
#endif
96+
8797
exit:
8898
fclose(f);
8999
return res;

multirom.c

+84
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@
5555
#include "rom_quirks.h"
5656
#include "kexec.h"
5757

58+
#ifdef MR_NO_KEXEC
59+
#include "no_kexec.h"
60+
#endif
61+
62+
5863
#define REALDATA "/realdata"
5964
#define BUSYBOX_BIN "busybox"
6065
#define KEXEC_BIN "kexec"
@@ -260,6 +265,23 @@ int multirom(const char *rom_to_boot)
260265
struct multirom_rom *to_boot = NULL;
261266
int exit = (EXIT_REBOOT | EXIT_UMOUNT);
262267

268+
#ifdef MR_NO_KEXEC
269+
// setup global variables here
270+
nokexec_set_struct(&s);
271+
272+
273+
// check if a partition mount failed, in which case multirom usually just boots internal
274+
if (s.current_rom->type == ROM_DEFAULT && nokexec_is_second_boot())
275+
{
276+
ERROR("NO_KEXEC: Something went wrong in mounting the needed partition, so falling back...");
277+
nokexec()->selected_method = NO_KEXEC_BOOT_NORMAL;
278+
s.is_second_boot = 0;
279+
//ERROR("NO_KEXEC: to Internal\n"); s.auto_boot_type = AUTOBOOT_FORCE_CURRENT; // force reboot to Internal (this would be mrom default behaviour)
280+
//ERROR("NO_KEXEC: to MultiROM GUI\n"); s.auto_boot_type = AUTOBOOT_NAME; // bring up the gui instead
281+
ERROR("NO_KEXEC: to Recovery\n"); exit = (EXIT_REBOOT_RECOVERY | EXIT_UMOUNT); goto finish; // reboot to recovery
282+
}
283+
#endif
284+
263285
if(rom_to_boot != NULL)
264286
{
265287
struct multirom_rom *rom = multirom_get_rom(&s, rom_to_boot, NULL);
@@ -320,6 +342,42 @@ int multirom(const char *rom_to_boot)
320342
{
321343
s.auto_boot_type &= ~(AUTOBOOT_FORCE_CURRENT);
322344

345+
#ifdef MR_NO_KEXEC
346+
#define MR_NO_KEXEC_ABORT { \
347+
ERROR("NO_KEXEC: ERROR occurred in the above, aborting to recovery\n"); \
348+
exit = (EXIT_REBOOT_RECOVERY | EXIT_UMOUNT); goto finish; \
349+
}
350+
351+
if (s.is_second_boot != 0)
352+
{
353+
// Restore primary boot.img, and continue
354+
if (nokexec_restore_primary_and_cleanup() < 0)
355+
MR_NO_KEXEC_ABORT;
356+
}
357+
else
358+
{
359+
if ((to_boot->type != ROM_DEFAULT) && to_boot->has_bootimg)
360+
{
361+
// Flash secondary boot.img, and reboot
362+
// note: a secondary boot.img in primary slot will trigger second_boot=1
363+
// so we don't need to worry about that any more
364+
if (nokexec_flash_secondary_bootimg(to_boot) < 0)
365+
MR_NO_KEXEC_ABORT;
366+
367+
s.current_rom = to_boot;
368+
369+
free(s.curr_rom_part);
370+
s.curr_rom_part = NULL;
371+
372+
if(to_boot->partition)
373+
s.curr_rom_part = strdup(to_boot->partition->uuid);
374+
375+
exit = (EXIT_REBOOT | EXIT_UMOUNT);
376+
goto finish;
377+
}
378+
}
379+
#endif
380+
323381
if(rom_to_boot == NULL)
324382
multirom_run_scripts("run-on-boot", to_boot);
325383

@@ -358,6 +416,9 @@ int multirom(const char *rom_to_boot)
358416
}
359417

360418
finish:
419+
#ifdef MR_NO_KEXEC
420+
nokexec_free_struct();
421+
#endif
361422
if (s.enable_kmsg_logging != 0)
362423
multirom_kmsg_logging(BACKUP_LATE_KLOG);
363424
multirom_save_status(&s);
@@ -515,6 +576,9 @@ int multirom_default_status(struct multirom_status *s)
515576
s->is_second_boot = 0;
516577
s->current_rom = NULL;
517578
s->roms = NULL;
579+
#ifdef MR_NO_KEXEC
580+
s->no_kexec = MR_NO_KEXEC;
581+
#endif
518582
s->colors = 0;
519583
s->brightness = MULTIROM_DEFAULT_BRIGHTNESS;
520584
s->enable_adb = 0;
@@ -657,6 +721,10 @@ int multirom_load_status(struct multirom_status *s)
657721
s->auto_boot_type = atoi(arg);
658722
else if(strstr(name, "curr_rom_part"))
659723
s->curr_rom_part = strdup(arg);
724+
#ifdef MR_NO_KEXEC
725+
else if(strstr(name, "no_kexec"))
726+
s->no_kexec = atoi(arg);
727+
#endif
660728
else if(strstr(name, "colors_v2"))
661729
s->colors = atoi(arg);
662730
else if(strstr(name, "brightness"))
@@ -764,6 +832,9 @@ int multirom_save_status(struct multirom_status *s)
764832
fprintf(f, "auto_boot_rom=%s\n", auto_boot_name);
765833
fprintf(f, "auto_boot_type=%d\n", s->auto_boot_type);
766834
fprintf(f, "curr_rom_part=%s\n", s->curr_rom_part ? s->curr_rom_part : "");
835+
#ifdef MR_NO_KEXEC
836+
fprintf(f, "no_kexec=%d\n", s->no_kexec);
837+
#endif
767838
fprintf(f, "colors_v2=%d\n", s->colors);
768839
fprintf(f, "brightness=%d\n", s->brightness);
769840
fprintf(f, "enable_adb=%d\n", s->enable_adb);
@@ -799,6 +870,9 @@ void multirom_dump_status(struct multirom_status *s)
799870
INFO(" is_second_boot=%d\n", s->is_second_boot);
800871
INFO(" is_running_in_primary_rom=%d\n", s->is_running_in_primary_rom);
801872
INFO(" current_rom=%s\n", s->current_rom ? s->current_rom->name : "NULL");
873+
#ifdef MR_NO_KEXEC
874+
INFO(" no_kexec=%d\n", s->no_kexec);
875+
#endif
802876
INFO(" colors_v2=%d\n", s->colors);
803877
INFO(" brightness=%d\n", s->brightness);
804878
INFO(" enable_adb=%d\n", s->enable_adb);
@@ -1105,7 +1179,12 @@ int multirom_prepare_for_boot(struct multirom_status *s, struct multirom_rom *to
11051179
int exit = EXIT_UMOUNT;
11061180
int type = to_boot->type;
11071181

1182+
1183+
#ifndef MR_NO_KEXEC
11081184
if(((M(type) & MASK_KEXEC) || to_boot->has_bootimg) && type != ROM_DEFAULT && s->is_second_boot == 0)
1185+
#else
1186+
if(((M(type) & MASK_KEXEC) || (to_boot->has_bootimg && (nokexec()->selected_method == NO_KEXEC_BOOT_NORMAL))) && type != ROM_DEFAULT && s->is_second_boot == 0)
1187+
#endif
11091188
{
11101189
if(multirom_load_kexec(s, to_boot) != 0)
11111190
return -1;
@@ -1686,7 +1765,12 @@ int multirom_get_bootloader_cmdline(struct multirom_status *s, char *str, size_t
16861765
*c = ' ';
16871766

16881767
// Remove the part from boot.img
1768+
//#ifndef MR_NO_KEXEC
16891769
if(s->is_running_in_primary_rom || !s->current_rom || !s->current_rom->has_bootimg)
1770+
//#else
1771+
// // probably not needed, but for consistency
1772+
// if(s->is_running_in_primary_rom || !s->current_rom || !(s->current_rom->has_bootimg && (nokexec()->selected_method == NO_KEXEC_BOOT_KEXEC)))
1773+
//#endif
16901774
{
16911775
boot = fstab_find_first_by_path(s->fstab, "/boot");
16921776
if(boot && libbootimg_load_header(&hdr, boot->device) >= 0)

multirom.h

+3
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ struct multirom_status
101101
int is_running_in_primary_rom;
102102
int auto_boot_seconds;
103103
int auto_boot_type;
104+
#ifdef MR_NO_KEXEC
105+
int no_kexec;
106+
#endif
104107
int colors;
105108
int brightness;
106109
int enable_adb;

0 commit comments

Comments
 (0)