Support A only System-as-root Devices

Most Chinese devices (and supposedly Galaxy S10) running Android Pie
is using system-as-root without A/B partition.

https://source.android.com/devices/bootloader/system-as-root#about-system-as-root

According to the docs above, these devices will have a ramdisk block
with size 0 in their boot images. Since magiskinit can run independently
on system-as-root devices, we simply just create an empty ramdisk with
magiskinit added as init.

Huge thanks to @vvb2060 for the heads up and original PR.
Close #980, close #1102
This commit is contained in:
topjohnwu 2019-02-28 05:46:36 -05:00
parent 99d6bd8efc
commit e72c6685ed
4 changed files with 43 additions and 20 deletions

View File

@ -22,6 +22,7 @@ static const char *MAGISK_LIST[] =
class magisk_cpio : public cpio_rw { class magisk_cpio : public cpio_rw {
public: public:
magisk_cpio() = default;
explicit magisk_cpio(const char *filename) : cpio_rw(filename) {} explicit magisk_cpio(const char *filename) : cpio_rw(filename) {}
void patch(bool keepverity, bool keepforceencrypt); void patch(bool keepverity, bool keepforceencrypt);
int test(); int test();
@ -140,6 +141,8 @@ void magisk_cpio::restore() {
} }
void magisk_cpio::backup(const char *orig) { void magisk_cpio::backup(const char *orig) {
if (access(orig, R_OK))
return;
entry_map bkup_entries; entry_map bkup_entries;
string remv; string remv;
@ -257,7 +260,9 @@ int cpio_commands(int argc, char *argv[]) {
++argv; ++argv;
--argc; --argc;
magisk_cpio cpio(incpio); magisk_cpio cpio;
if (access(incpio, R_OK) == 0)
cpio.load_cpio(incpio);
int cmdc; int cmdc;
char *cmdv[6]; char *cmdv[6];
@ -305,7 +310,7 @@ int cpio_commands(int argc, char *argv[]) {
return 0; return 0;
} }
} else if (cmdc == 3 && strcmp(cmdv[0], "mkdir") == 0) { } else if (cmdc == 3 && strcmp(cmdv[0], "mkdir") == 0) {
cpio.makedir(strtoul(cmdv[1], nullptr, 8), cmdv[2]); cpio.mkdir(strtoul(cmdv[1], nullptr, 8), cmdv[2]);
} else if (cmdc == 3 && strcmp(cmdv[0], "ln") == 0) { } else if (cmdc == 3 && strcmp(cmdv[0], "ln") == 0) {
cpio.ln(cmdv[1], cmdv[2]); cpio.ln(cmdv[1], cmdv[2]);
} else if (cmdc == 4 && strcmp(cmdv[0], "add") == 0) { } else if (cmdc == 4 && strcmp(cmdv[0], "add") == 0) {

View File

@ -149,11 +149,15 @@ void cpio::output(OutStream &out) {
out_align(); out_align();
} }
cpio_rw::cpio_rw(const char *filename) { cpio_rw::cpio_rw(const char *file) {
load_cpio(file);
}
void cpio_rw::load_cpio(const char *file) {
char *buf; char *buf;
size_t sz; size_t sz;
mmap_ro(filename, buf, sz); mmap_ro(file, buf, sz);
fprintf(stderr, "Loading cpio: [%s]\n", filename); fprintf(stderr, "Loading cpio: [%s]\n", file);
load_cpio(buf, sz); load_cpio(buf, sz);
munmap(buf, sz); munmap(buf, sz);
} }
@ -182,7 +186,7 @@ void cpio_rw::add(mode_t mode, const char *name, const char *file) {
fprintf(stderr, "Add entry [%s] (%04o)\n", name, mode); fprintf(stderr, "Add entry [%s] (%04o)\n", name, mode);
} }
void cpio_rw::makedir(mode_t mode, const char *name) { void cpio_rw::mkdir(mode_t mode, const char *name) {
insert(new cpio_entry(name, S_IFDIR | mode)); insert(new cpio_entry(name, S_IFDIR | mode));
fprintf(stderr, "Create directory [%s] (%04o)\n", name, mode); fprintf(stderr, "Create directory [%s] (%04o)\n", name, mode);
} }
@ -241,9 +245,9 @@ void cpio_rw::load_cpio(char *buf, size_t sz) {
} }
} }
cpio_mmap::cpio_mmap(const char *filename) { cpio_mmap::cpio_mmap(const char *file) {
mmap_ro(filename, buf, sz); mmap_ro(file, buf, sz);
fprintf(stderr, "Loading cpio: [%s]\n", filename); fprintf(stderr, "Loading cpio: [%s]\n", file);
size_t pos = 0; size_t pos = 0;
cpio_newc_header *header; cpio_newc_header *header;
unique_ptr<cpio_entry_base> entry; unique_ptr<cpio_entry_base> entry;

View File

@ -53,21 +53,23 @@ protected:
class cpio_rw : public cpio { class cpio_rw : public cpio {
public: public:
explicit cpio_rw(const char *filename); cpio_rw() = default;
void insert(cpio_entry *e); explicit cpio_rw(const char *file);
void load_cpio(const char *file);
void add(mode_t mode, const char *name, const char *file); void add(mode_t mode, const char *name, const char *file);
void makedir(mode_t mode, const char *name); void mkdir(mode_t mode, const char *name);
void ln(const char *target, const char *name); void ln(const char *target, const char *name);
bool mv(const char *from, const char *to); bool mv(const char *from, const char *to);
protected: protected:
void insert(cpio_entry *e);
void mv(entry_map::iterator &it, const char *to); void mv(entry_map::iterator &it, const char *to);
void load_cpio(char *buf, size_t sz); void load_cpio(char *buf, size_t sz);
}; };
class cpio_mmap : public cpio { class cpio_mmap : public cpio {
public: public:
explicit cpio_mmap(const char *filename); explicit cpio_mmap(const char *file);
~cpio_mmap(); ~cpio_mmap();
private: private:
char *buf; char *buf;

View File

@ -87,10 +87,15 @@ esac
# Ramdisk restores # Ramdisk restores
########################################################################################## ##########################################################################################
# Test patch status and do restore, after this section, ramdisk.cpio.orig is guaranteed to exist # Test patch status and do restore
ui_print "- Checking ramdisk status" ui_print "- Checking ramdisk status"
if [ -e ramdisk.cpio ]; then
./magiskboot --cpio ramdisk.cpio test ./magiskboot --cpio ramdisk.cpio test
STATUS=$? STATUS=$?
else
# Stock A only system-as-root
STATUS=0
fi
case $((STATUS & 3)) in case $((STATUS & 3)) in
0 ) # Stock boot 0 ) # Stock boot
ui_print "- Stock boot image detected" ui_print "- Stock boot image detected"
@ -98,18 +103,24 @@ case $((STATUS & 3)) in
SHA1=`./magiskboot --sha1 "$BOOTIMAGE" 2>/dev/null` SHA1=`./magiskboot --sha1 "$BOOTIMAGE" 2>/dev/null`
STOCKDUMP=stock_boot_${SHA1}.img.gz STOCKDUMP=stock_boot_${SHA1}.img.gz
./magiskboot --compress "$BOOTIMAGE" $STOCKDUMP ./magiskboot --compress "$BOOTIMAGE" $STOCKDUMP
cp -af ramdisk.cpio ramdisk.cpio.orig cp -af ramdisk.cpio ramdisk.cpio.orig 2>/dev/null
;; ;;
1 ) # Magisk patched 1 ) # Magisk patched
ui_print "- Magisk patched boot image detected" ui_print "- Magisk patched boot image detected"
# Find SHA1 of stock boot image # Find SHA1 of stock boot image
[ -z $SHA1 ] && SHA1=`./magiskboot --cpio ramdisk.cpio sha1 2>/dev/null` [ -z $SHA1 ] && SHA1=`./magiskboot --cpio ramdisk.cpio sha1 2>/dev/null`
./magiskboot --cpio ramdisk.cpio restore ./magiskboot --cpio ramdisk.cpio restore
if ./magiskboot --cpio ramdisk.cpio "exists init.rc"; then
# Normal boot image
cp -af ramdisk.cpio ramdisk.cpio.orig cp -af ramdisk.cpio ramdisk.cpio.orig
else
# A only system-as-root
rm -f ramdisk.cpio
fi
;; ;;
2 ) # Other patched 2 ) # Unsupported
ui_print "! Boot image patched by unsupported programs" ui_print "! Boot image patched by unsupported programs"
abort "! Please restore stock boot image" abort "! Please restore back to stock boot image"
;; ;;
esac esac
@ -127,6 +138,7 @@ echo "KEEPFORCEENCRYPT=$KEEPFORCEENCRYPT" >> config
"add 750 init magiskinit" \ "add 750 init magiskinit" \
"patch $KEEPVERITY $KEEPFORCEENCRYPT" \ "patch $KEEPVERITY $KEEPFORCEENCRYPT" \
"backup ramdisk.cpio.orig" \ "backup ramdisk.cpio.orig" \
"mkdir 000 .backup" \
"add 000 .backup/.magisk config" "add 000 .backup/.magisk config"
if [ $((STATUS & 4)) -ne 0 ]; then if [ $((STATUS & 4)) -ne 0 ]; then