android 9 reboot流程

机器出现开机 自动进入fastboot模式。可能是init 那个进程挂了 然后调用了
RebootSystem(ANDROID_RB_RESTART2, “bootloader”); 函数进入重启流程,然后重启后进入fastboot
浅读一下reboot流程和怎么进入的fastboot
比如说是那个进程挂了调用了这个函数,然后就是会调用到 RebootSystem
在这里插入图片描述
在查看一下RebootSystem(unsigned int cmd, const std::string& rebootTarget)的paramete
paramete 1 :cmd 就是 reboot 命令是poweroff 还是restart
paramete 2: rebootTarget 就是重启的参数只有restart才会用到这个参数(reboot recovery/bootloader)重启后进入指定模式 例如fastboot
recovery模式
在这里插入图片描述
看重启流程:
syscall是一个系统调用 在这调用_NR_reboot指令
系统调用之后就是进入内核
include\linux\syscall.h 中调用SYSCALL_DEFINE4 因为 _NR_reboot后面带4个参数 实际
SYSCALL_DEFINE4会根据你的命令(reboot star stop 等一下关于内核的命令调用实际函数)
在这里插入图片描述
就是这个name
-------------------------分界线---------------
比如_NR_reboot 就是调用sys_reboot函数,其他exit或者shutdown同理
在这里插入图片描述
那么我们就在内核中调用了sys_reboot并且系统层给了参数
asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user *arg);
syscall(__NR_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,LINUX_REBOOT_CMD_RESTART2, rebootTarget.c_str()
对应就是 magic1 = LINUX_REBOOT_MAGIC1
magic2 =LINUX_REBOOT_MAGIC2
cmd = LINUX_REBOOT_CMD_RESTART2(重启)
rebootTarget.c_str() = 重启参数在开头给的是“bootloder”
--------------------------分界线-------------------------------------------
分界线内的说明好像不正确,他不是调用的sys_reboot函数,而是把函数重新定义
在这里插入图片描述
实际调用的还是SYSCALL_DEFINE4(name ,arg…)
reboot: SYSCALL_DEFINE4(reboot ,arg…)

kernel-4.9/kernel/reboot.c中
SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,void __user *, arg)
{struct pid_namespace *pid_ns = task_active_pid_ns(current);char buffer[256];int ret = 0;/* We only trust the superuser with rebooting the system. */if (!ns_capable(pid_ns->user_ns, CAP_SYS_BOOT))return -EPERM;/* For safety, we require "magic" arguments. */if (magic1 != LINUX_REBOOT_MAGIC1 ||(magic2 != LINUX_REBOOT_MAGIC2 &&magic2 != LINUX_REBOOT_MAGIC2A &&magic2 != LINUX_REBOOT_MAGIC2B &&magic2 != LINUX_REBOOT_MAGIC2C))return -EINVAL;/** If pid namespaces are enabled and the current task is in a child* pid_namespace, the command is handled by reboot_pid_ns() which will* call do_exit().*/ret = reboot_pid_ns(pid_ns, cmd);if (ret)return ret;/* Instead of trying to make the power_off code look like* halt when pm_power_off is not set do it the easy way.*/if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)cmd = LINUX_REBOOT_CMD_HALT;mutex_lock(&reboot_mutex);switch (cmd) {case LINUX_REBOOT_CMD_RESTART:kernel_restart(NULL);break;case LINUX_REBOOT_CMD_CAD_ON:C_A_D = 1;break;case LINUX_REBOOT_CMD_CAD_OFF:C_A_D = 0;break;case LINUX_REBOOT_CMD_HALT:kernel_halt();do_exit(0);panic("cannot halt");case LINUX_REBOOT_CMD_POWER_OFF:kernel_power_off();do_exit(0);break;case LINUX_REBOOT_CMD_RESTART2:ret = strncpy_from_user(&buffer[0], arg, sizeof(buffer) - 1);if (ret < 0) {ret = -EFAULT;break;}buffer[sizeof(buffer) - 1] = '\0';kernel_restart(buffer);break;#ifdef CONFIG_KEXEC_COREcase LINUX_REBOOT_CMD_KEXEC:ret = kernel_kexec();break;
#endif#ifdef CONFIG_HIBERNATIONcase LINUX_REBOOT_CMD_SW_SUSPEND:ret = hibernate();break;
#endifdefault:ret = -EINVAL;break;}mutex_unlock(&reboot_mutex);return ret;
}

如果走重启流程调用:kernel_restart(buffer);

void kernel_restart(char *cmd)
{kernel_restart_prepare(cmd);migrate_to_reboot_cpu();syscore_shutdown();if (!cmd)pr_emerg("Restarting system\n");elsepr_emerg("Restarting system with command '%s'\n", cmd);kmsg_dump(KMSG_DUMP_RESTART);machine_restart(cmd);
}

调用 machine_restart(cmd)
kernel4.9/arch/arm/kernel/reboot.c
在这里插入图片描述
调用do_kernel_restart

void do_kernel_restart(char *cmd)
{atomic_notifier_call_chain(&restart_handler_list, reboot_mode, cmd);
}

atomic_notifier_call_chain做的是向注册restart_handler_list的驱动发送一个通知,通知各个通过register_restart_handler注册的钩子函数,执行这个关机函数
在kernel4.9/drivers/watchdog_core.c
__watchdog_register_device函数中注册
在这里插入图片描述
调用:watchdog_restart_notifier
在这里插入图片描述
调用:wdd->ops->restart(wdd, action, data);
看一下restart的实现在哪里
mtk_wdt.c

static int mtk_reset_handler(struct notifier_block *this, unsigned long mode,void *cmd)
{struct mtk_wdt_dev *mtk_wdt;void __iomem *wdt_base;u32 reg;mtk_wdt = container_of(this, struct mtk_wdt_dev, restart_handler);wdt_base = mtk_wdt->wdt_base;/** WDT_STATUS will be cleared to  zero after writing to WDT_MODE, so we backup it in WDT_NONRST_REG,* and then print it out in mtk_wdt_probe() after reset*/writel(__raw_readl(wdt_base + WDT_STATUS), wdt_base + WDT_NONRST_REG);reg = ioread32(wdt_base + WDT_MODE);reg &= ~(WDT_MODE_DUAL_EN | WDT_MODE_IRQ_EN | WDT_MODE_EN);reg |= WDT_MODE_KEY;iowrite32(reg, wdt_base + WDT_MODE);if (cmd && (strcmp(cmd, "rpmbpk") == 0)) {iowrite32(ioread32(wdt_base + WDT_NONRST_REG2) | (1U << 0), wdt_base + WDT_NONRST_REG2);} else if (cmd && (strcmp(cmd, "recovery") == 0)) {iowrite32(ioread32(wdt_base + WDT_NONRST_REG2) | (1U << 1), wdt_base + WDT_NONRST_REG2);#ifdef CONFIG_MT6397_MISCmtk_misc_mark_recovery();#endif} else if (cmd && (strcmp(cmd, "bootloader") == 0)) {iowrite32(ioread32(wdt_base + WDT_NONRST_REG2) | (1U << 2), wdt_base + WDT_NONRST_REG2);#ifdef CONFIG_MT6397_MISCmtk_misc_mark_fast();#endif} else {//do nothing}if (!arm_pm_restart) {while (1) {writel(WDT_SWRST_KEY, wdt_base + WDT_SWRST);mdelay(5);}}return NOTIFY_DONE;
}

这里就是resart实现的地方,那么我们传下来的参数是bootloader
iowrite32(ioread32(wdt_base + WDT_NONRST_REG2) | (1U << 2), wdt_base + WDT_NONRST_REG2);
看到这是写看了一个寄存器,这要看数据手册才知道写的是那个寄存器了,不过在lk阶段就是判断RTC的寄存器来判断进入fasterboot模式的。
vendor\mediatek\proprietary\bootable\bootloader\lk\platform\mt8163\boot_mode.c

void boot_mode_select(void)
{int factory_forbidden = 0;//  int forbid_mode;
/*We put conditions here to filer some cases that can not do key detection*/extern int kedump_mini(void) __attribute__((weak));if (kedump_mini){if (kedump_mini()){mrdump_check();return;}}if (meta_detection()){return;}mrdump_check();#if defined (HAVE_LK_TEXT_MENU)
/*Check RTC to know if system want to reboot to Fastboot*/if(Check_RTC_PDN1_bit13()){dprintf(CRITICAL, "[FASTBOOT] reboot to boot loader\n");g_boot_mode = FASTBOOT;Set_Clr_RTC_PDN1_bit13(false);return;}/*If forbidden mode is factory, cacel the factory key detection*/if(g_boot_arg->sec_limit.magic_num == 0x4C4C4C4C){if(g_boot_arg->sec_limit.forbid_mode == F_FACTORY_MODE){//Forbid to enter factory modedprintf(CRITICAL, "%s Forbidden\n",MODULE_NAME);factory_forbidden=1;}}//  forbid_mode = g_boot_arg->boot_mode &= 0x000000FF;/*If boot reason is power key + volumn down, thendisable factory mode dectection*/if(mtk_detect_pmic_just_rst()){factory_forbidden=1;}/*Check RTC to know if system want to reboot to Recovery*/if(Check_RTC_Recovery_Mode()){g_boot_mode = RECOVERY_BOOT;return;}/*If MISC Write has not completed  in recovery modebefore system reboot, go to recovery mode tofinish remain tasks*/if(unshield_recovery_detection()){return;}ulong begin = get_timer(0);/*we put key dectection here to detect key which is pressed*/

所以这俩个就是通过判断RTC_PDN1_bit13这个位进入fastboot模式。
同理我们使用adb 命令 adb reboot bootloader 就是reboot d带bootloader参数也是一样的进fastboot

不一样的是系统层下发命令进入fastboot是由于系统崩溃导致,可以查看在哪里崩溃的日志定位问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/339113.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android Studio 禁用插件(Plugin)后无法启动(Mac电脑)

问题描述&#xff1a; 昨天为了解决某个问题&#xff0c;禁用了Kotlin&#xff08;Plugins&#xff09;&#xff0c;结果android无法启动了 启动界面如图所示&#xff1a; Internal error. Please refer to https://code.google.com/p/android/issuescom.intellij.ide.plugins…

SV-298XT IP网络广播板 SV-298XT-共公广播音频模块IP网络广播板

SV-298XT IP网络广播板 SV-298XT-共公广播音频模块IP网络广播板 SV-298XT网络广播模块是一款全数字网络型广播模组&#xff0c;核心部分采用了成熟的私有协议解决方案&#xff0c;性能稳定可靠。支持TCP、UDP、组播协议能针对当前服务器中不同的广播任务设置不同的广播传输方式…

linux kernel:devres模块架构分析

参考文档&#xff1a; https://www.kernel.org/doc/html/latest/driver-api/driver-model/devres.html https://www.cnblogs.com/sammei/p/3498052.html devres in linux driver devres: Managed Device Resource device resource managementdevres_alloc()动态申请内存分配…

2023年全国职业院校技能大赛(高职组)“云计算应用”赛项赛卷⑨

2023年全国职业院校技能大赛&#xff08;高职组&#xff09; “云计算应用”赛项赛卷9 目录 需要竞赛软件包环境以及备赛资源可私信博主&#xff01;&#xff01;&#xff01; 2023年全国职业院校技能大赛&#xff08;高职组&#xff09; “云计算应用”赛项赛卷9 模块一 …

【软件测试】学习笔记-设计GUI自动化测试策略

这篇文章从“实战”这个角度展开&#xff0c;探讨实际的大型全球化电商网站的GUI自动化测试如何开展。这场实战&#xff0c;从以下两个方面展开&#xff1a; 测试策略如何设计&#xff1f;这一点&#xff0c;我会根据亲身经历的实际项目&#xff0c;和你探讨GUI测试的分层测试…

【MMC子系统】四、MMC控制器驱动层

我的圈子&#xff1a; 高级工程师聚集地 我是董哥&#xff0c;高级嵌入式软件开发工程师&#xff0c;从事嵌入式Linux驱动开发和系统开发&#xff0c;曾就职于世界500强企业&#xff01; 创作理念&#xff1a;专注分享高质量嵌入式文章&#xff0c;让大家读有所得&#xff01; …

[openGL]在ubuntu20.06上搭建openGL环境

就在刚刚, 我跑上了一个6小时后出结果的测试程序. 离下班还有很久, 于是我打开了接单群 , 发现了很多可以写的openGL项目. 但是!!我的电脑现在是ubuntu呀, 但是不要慌!!!接下来我一步一步教你如何完美搭建一个ubuntu上的openGL环境. 保证一个坑也不会踩! 文章目录 创建项目工作…

win7添加access的odbc数据源

从控制面板打开odbc数据源&#xff1b;如果像下面没有access的驱动程序&#xff0c; 根据资料&#xff0c;打开C盘-Windows-SysWow64-odbcad32.exe&#xff0c;看一下就有了&#xff1b; 然后添加用户DSN&#xff0c;选中access的驱动程序&#xff0c; 自己输入一个数据源名&am…

linux搭建zabbix

1、访问官网地址&#xff0c;选择对应的版本等 在下方会有命令列出来&#xff0c;按照实际情况运行命令 a. Install Zabbix repository # wget https://repo.zabbix.com/zabbix/6.4/debian/pool/main/z/zabbix-release/zabbix-release_6.4-1debian12_all.deb # dpkg -i zabb…

从0到1实现html文件转换为markdown文档(进度0.1)

Spider-Man 前言准备环境1、node.js2、git 执行指令顺序报错及其解决方案一、npm 错误&#xff01;可以在以下位置找到此运行的完整日志解决方案 二、没有修改权限解决方案&#xff1a; 注意事项总结 前言 当我们处理文档时&#xff0c;常常会遇到将HTML文档转换为Markdown文档…

e2studio开发LPS28DFW气压计(1)----轮询获取气压计数据

e2studio开发LPS28DFW气压计.1--轮询获取气压计数据 概述视频教学样品申请完整代码下载产品特性通信模式速率新建工程工程模板保存工程路径芯片配置工程模板选择时钟设置UART配置UART属性配置设置e2studio堆栈e2studio的重定向printf设置R_SCI_UART_Open()函数原型回调函数user…

项目经理快速晋升应当具备的四个能力

项目的成功与失败都直接压在项目经理的肩上。不论问题的根源在何处&#xff0c;最终承担责任的总是项目经理。身为项目经理&#xff0c;你务必清楚&#xff0c;自己背负的是何等的重任。 1、计划能力 计划是行动的灯塔&#xff0c;若管理者无法制定计划&#xff0c;又如何引…