Android8.x和Android9.x平台user版本打开UART输出并支持控制台输入和user版本adb root的方法

1、user版本打开uart口日志输出

1.1 修改lk

mediatek\proprietary\bootable\bootloader\lk\app\mt_boot\mt_boot.c
****************************************************************************/
我们系统使用的是设备树,所以调用的是boot_linux_fdt
int boot_linux_fdt(void *kernel, unsigned *tags,
		   unsigned machtype,
		   void *ramdisk, unsigned ramdisk_sz)
{
	void *fdt = tags;
	int ret = 0;
	int offset;
	char tmpbuf[TMPBUF_SIZE];
	dt_dram_info mem_reg_property[128];
    ....................................
    	if (!has_set_p2u) {
		switch (eBuildType) {
		case BUILD_TYPE_USER:
			if ((g_boot_mode == META_BOOT) && is_meta_log_disable &&
			    (is_meta_log_disable() == 0))
				cmdline_append("printk.disable_uart=0");
			else
				//cmdline_append("printk.disable_uart=1"); //修改
                cmdline_append("printk.disable_uart=0");
#ifdef ATC_AOSP_ENHANCEMENT    
            //cmdline_append("loglevel=0"); //关闭串口打印 修改成日志级别是4       
            cmdline_append("loglevel=4");
#endif
			break;

		case BUILD_TYPE_USERDEBUG:
  .........................................
}
其它部分不需要修改,否则就达不到user编译的目的。

1.2 修改内核:

kernel-3.18\kernel\printk\printk.c
#ifdef CONFIG_MT_PRINTK_UART_CONSOLE
void mt_disable_uart(void)
{
	if (mt_need_uart_console == 0)
		//printk_disable_uart = 1; //将printk_disable_uart = 1修改成printk_disable_uart = 0
	    printk_disable_uart = 0;
}
void mt_enable_uart(void)
{
	if (mt_need_uart_console == 1) {
		if (printk_disable_uart == 0)
			return;
		printk_disable_uart = 0;
	}
}

#endif

1.3 修改init.rc

system\core\rootdir\init.rc

system\core\rootdir\init.rc
service console /system/bin/sh
    class core
    console
    #disabled   //注释掉这行,确保任何条件下控制台启动
    #user shell //控制台具有root权限
    user root
    group shell log readproc
    seclabel u:r:shell:s0

on property:ro.debuggable=1
    # Give writes to anyone for the trace folder on debug builds.
    # The folder is used to store method traces.
    chmod 0773 /data/misc/trace
    start console
    

2、user版本具有root权限

2.1 修改ro.adb.secure和ro.secure属性

build\core\main.mk
ifneq (,$(user_variant))
  # Target is secure in user builds.
  #ADDITIONAL_DEFAULT_PROPERTIES += ro.secure=1 //修改
  ADDITIONAL_DEFAULT_PROPERTIES += ro.secure=0
  ADDITIONAL_DEFAULT_PROPERTIES += security.perf_harden=1

  ifeq ($(user_variant),user)
    #ADDITIONAL_DEFAULT_PROPERTIES += ro.adb.secure=1 //修改
    ADDITIONAL_DEFAULT_PROPERTIES += ro.adb.secure=0
  endif

  ifeq ($(user_variant),userdebug)
    # Pick up some extra useful tools
    tags_to_install += debug
  else
    # Disable debugging in plain user builds.
    #enable_target_debugging :=  //去这行
  endif

2.2 修改selinux

Android8.x:
system\core\init\init.cpp
static bool selinux_is_enforcing(void)
{
	return false; //直接返回
    if (ALLOW_PERMISSIVE_SELINUX) {
        return selinux_status_from_cmdline() == SELINUX_ENFORCING;
    }
    return true;
}

android9.x:
system/core/init/selinux.cpp
 bool IsEnforcing() {
   return false; //直接返回
   if (ALLOW_PERMISSIVE_SELINUX) {
         return StatusFromCmdline() == SELINUX_ENFORCING;
     }
     return true;
  }

2.3 修改adb的android.mk文件

system\core\adb\Android.mk
LOCAL_CFLAGS := \
    $(ADB_COMMON_CFLAGS) \
    $(ADB_COMMON_linux_CFLAGS) \
    -DADB_HOST=0 \
    -D_GNU_SOURCE \
    -Wno-deprecated-declarations \

#LOCAL_CFLAGS += -DALLOW_ADBD_NO_AUTH=$(if $(filter userdebug eng,$(TARGET_BUILD_VARIANT)),1,0)  //修改
LOCAL_CFLAGS += -DALLOW_ADBD_NO_AUTH=$(if $(filter user userdebug eng,$(TARGET_BUILD_VARIANT)),1,0)

#ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT))) //修改
ifneq (,$(filter user userdebug eng,$(TARGET_BUILD_VARIANT)))
LOCAL_CFLAGS += -DALLOW_ADBD_DISABLE_VERITY=1
LOCAL_CFLAGS += -DALLOW_ADBD_ROOT=1
endif

3、另外一种user adb root打开的修改方法(不用授权adb key)如下:

  先参考:https://blog.csdn.net/kc58236582/article/details/53502177

system\core\adb\daemon\main.cpp
int adbd_main(int server_port) {
    umask(0);
 
    signal(SIGPIPE, SIG_IGN);
 
    init_transport_registration();
 
    // We need to call this even if auth isn't enabled because the file
    // descriptor will always be open.
    adbd_cloexec_auth_socket();
 
    // Respect ro.adb.secure in userdebug/eng builds (ALLOW_ADBD_NO_AUTH), or when the
    // device is unlocked.
    if ((ALLOW_ADBD_NO_AUTH || is_device_unlocked()) &&
        !android::base::GetBoolProperty("ro.adb.secure", false)) {
        auth_required = false;
    }
 
    auth_required = false; //添加这行

然后就是处理adb root的service,我们将版本不是debuggable的处理去除。

system\core\adb\services.cpp
void restart_root_service(int fd, void *cookie) {
    if (getuid() == 0) {
        WriteFdExactly(fd, "adbd is already running as root\n");
        adb_close(fd);
    } else {
        /*if (!__android_log_is_debuggable()) { //去掉这个代码
            WriteFdExactly(fd, "adbd cannot run as root in production builds\n");
            adb_close(fd);
            return;
        }*/

        android::base::SetProperty("service.adb.root", "1");
        WriteFdExactly(fd, "restarting adbd as root\n");
        adb_close(fd);
    }
}

接着我们来看drop_privileges函数,这个函数如果adb不用root权限会给她降级到shell。而就是通过should_drop_privileges这个函数来判断是否要降级,返回false就是使用root权限。

system\core\adb\daemon\main.cpp
static void drop_privileges(int server_port) {
    ScopedMinijail jail(minijail_new());

    // Add extra groups:
    // AID_ADB to access the USB driver
    // AID_LOG to read system logs (adb logcat)
    // AID_INPUT to diagnose input issues (getevent)
    // AID_INET to diagnose network issues (ping)
    // AID_NET_BT and AID_NET_BT_ADMIN to diagnose bluetooth (hcidump)
    // AID_SDCARD_R to allow reading from the SD card
    // AID_SDCARD_RW to allow writing to the SD card
    // AID_NET_BW_STATS to read out qtaguid statistics
    // AID_READPROC for reading /proc entries across UID boundaries
    // AID_UHID for using 'hid' command to read/write to /dev/uhid
    gid_t groups[] = {AID_ADB,          AID_LOG,          AID_INPUT,    AID_INET,
                      AID_NET_BT,       AID_NET_BT_ADMIN, AID_SDCARD_R, AID_SDCARD_RW,
                      AID_NET_BW_STATS, AID_READPROC,     AID_UHID};
    minijail_set_supplementary_gids(jail.get(), arraysize(groups), groups);

    // Don't listen on a port (default 5037) if running in secure mode.
    // Don't run as root if running in secure mode.
    if (should_drop_privileges()) {  //通过这里进行降级
        drop_capabilities_bounding_set_if_needed(jail.get());

        minijail_change_gid(jail.get(), AID_SHELL);
        minijail_change_uid(jail.get(), AID_SHELL);
        // minijail_enter() will abort if any priv-dropping step fails.
        minijail_enter(jail.get());

        D("Local port disabled");
    } else {
        // minijail_enter() will abort if any priv-dropping step fails.
        minijail_enter(jail.get());

        if (root_seclabel != nullptr) {
            if (selinux_android_setcon(root_seclabel) < 0) {
                LOG(FATAL) << "Could not set SELinux context";
            }
        }
        std::string error;
        std::string local_name =
            android::base::StringPrintf("tcp:%d", server_port);
        if (install_listener(local_name, "*smartsocket*", nullptr, 0, nullptr, &error)) {
            LOG(FATAL) << "Could not install *smartsocket* listener: " << error;
        }
    }
}

因此我们在should_drop_privileges函数最上面直接判断处理,当service.adb.root(adb root会设置这个权限)是1就返回false

system\core\adb\daemon\main.cpp

static bool should_drop_privileges() {
#if defined(ALLOW_ADBD_ROOT)
    // The properties that affect `adb root` and `adb unroot` are ro.secure and
    // ro.debuggable. In this context the names don't make the expected behavior
    // particularly obvious.
    //
    // ro.debuggable:
    //   Allowed to become root, but not necessarily the default. Set to 1 on
    //   eng and userdebug builds.
    //
    // ro.secure:
    //   Drop privileges by default. Set to 1 on userdebug and user builds.
    bool ro_secure = android::base::GetBoolProperty("ro.secure", true);
    bool ro_debuggable = __android_log_is_debuggable();

    // Drop privileges if ro.secure is set...
    bool drop = ro_secure;

    // ... except "adb root" lets you keep privileges in a debuggable build.
    std::string prop = android::base::GetProperty("service.adb.root", "");
    bool adb_root = (prop == "1");
    bool adb_unroot = (prop == "0");
    if (ro_debuggable && adb_root) {
        drop = false;
    }
    // ... and "adb unroot" lets you explicitly drop privileges.
    if (adb_unroot) {
        drop = true;
    }

    return drop;
#else
    //return true; // "adb root" not allowed, always drop privileges.
    //添加
    std::string prop1 = android::base::GetProperty("service.adb.root", "");
    if (prop1 == "1") {
        return false;
    //结束添加
    return true;
#endif // ALLOW_ADBD_ROOT
}

这样adbd的流程就差不多处理完了,但是发现adbd在输入adb root的时候会crash最后定位到是selinux问题。

这里我们提供一个在init中关闭selinux的简单方法。init初始化的时候会调用selinux_initialize函数,这个函数又会调用selinux_is_enforcing函数,我们确保这个函数返回false就可以了。

system\core\init\init.cpp
static selinux_enforcing_status selinux_status_from_cmdline() {
   //移除以下代码
    /*selinux_enforcing_status status = SELINUX_ENFORCING;

    import_kernel_cmdline(false, [&](const std::string& key, const std::string& value, bool in_qemu) {
        if (key == "androidboot.selinux" && value == "permissive") {
            status = SELINUX_PERMISSIVE;
        }
    });*/ //结束移除

    return status;
}

static bool selinux_is_enforcing(void)
{
    if (ALLOW_PERMISSIVE_SELINUX) {
        return selinux_status_from_cmdline() == SELINUX_ENFORCING;
    }
    //return true;
    return false; //修改为返回false
}

这样adb root以及不用授权问题在user版本上就实现了。

你可能感兴趣的:(系统开发,Android)