Linux系统重启的最底层函数是arch_reset,这是一个全局的函数指针变量,定义在 arch/arm/mach-rk30/include/mach/system.h中:

extern void (*arch_reset)(char, const char *);

注意,这是一个变量声明,类型为函数指针。并不是函数的声明!它的实现在mach-rk30/reset.c中:

static void rk30_arch_reset(char mode, const char *cmd)
{
    u32 boot_flag = 0;
    u32 boot_mode = BOOT_MODE_REBOOT;

if (cmd) {
        if (!strcmp(cmd, "loader") || !strcmp(cmd, "bootloader"))
            boot_flag = SYS_LOADER_REBOOT_FLAG + BOOT_LOADER;
        else if(!strcmp(cmd, "recovery"))
            boot_flag = SYS_LOADER_REBOOT_FLAG + BOOT_RECOVER;
        else if (!strcmp(cmd, "charge"))
            boot_mode = BOOT_MODE_CHARGE;
    } else {
        if (system_state != SYSTEM_RESTART)
            boot_mode = BOOT_MODE_PANIC;
    }
    writel_relaxed(boot_flag, RK30_PMU_BASE + PMU_SYS_REG0);    // for loader
    writel_relaxed(boot_mode, RK30_PMU_BASE + PMU_SYS_REG1);    // for linux
    dsb();
    /* disable remap */
    writel_relaxed(1 << (12 + 16), RK30_GRF_BASE + GRF_SOC_CON0);
    /* pll enter slow mode */
    writel_relaxed(PLL_MODE_SLOW(APLL_ID) | PLL_MODE_SLOW(CPLL_ID) | PLL_MODE_SLOW(GPLL_ID), RK30_CRU_BASE + CRU_MODE_CON);
    dsb();
    writel_relaxed(0xeca8, RK30_CRU_BASE + CRU_GLB_SRST_SND);
    dsb();
}

void (*arch_reset)(char, const char *) = rk30_arch_reset;

注意,平台的真正实现在rk30_arch_reset中,然后赋值给指针变量arch_reset。 这样,你在其它地方就能把arch_reset当成函数一样任意调用了。为什么要这样?为了封装呀,不同的CPU上可能有不同的实现,但最后暴露给上层的接口始终是arch_reset。

rk30_arch_reset的内部实现很有意思,第一个参数mode没有用到,参数cmd是一个字符串,"loader" "bootloader"应该是通常的重新启动进入系统;"recovery"应该是重启进入recovery模式, “charge”应该是重启进入充电界面(相当于关机?)

下面来做个简单测试,随便找个驱动程序,在其probe函数里面加入下面的代码(记得要包含头文件哦),强行重启到recovery模式:

printk("++++++++reboot to recovery begin\n");
printk("++++++++reboot to recovery begin\n");
arch_reset(0, "recovery");
printk("++++++++reboot to recovery end\n");
printk("++++++++reboot to recovery end\n");

上电测试,串口中能打印出下面的信息,可以看出在arch_reset之后,系统确实重启了:

[    1.491413] ++++++++reboot to recovery begin
[    1.495691] ++++++++reboot to recovery begin
DDR Version 1.00 20120529
In
DDR3
freq
300MHz
config state
pctl
phy
mem

分析了这么多,那就顺便再看一下S3C2410里面的实现吧, arch_reset的定义在mach-s3c2410/system-reset.h中:

extern void (*s3c24xx_reset_hook)(void);

static void
arch_reset(char mode, const char *cmd)
{
    if (mode == 's') {
        cpu_reset(0);
    }

if (s3c24xx_reset_hook)
        s3c24xx_reset_hook();

arch_wdt_reset();

/* we'll take a jump through zero as a poor second */
    cpu_reset(0);
}

这里又不同于RK30SDK,arch_reset被定义成了一个函数,它在内部又调用了s3c24xx_reset_hook,而s3c24xx_reset_hook却被定义成了一个函数指针变量,估计不同的CPU有不同的代码,让我们继续寻找s3c24xx_reset_hook:

./mach-s3c2416/s3c2416.c:87:    s3c24xx_reset_hook = s3c2416_hard_reset;
./mach-s3c2412/s3c2412.c:169:    s3c24xx_reset_hook = s3c2412_hard_reset;
./mach-s3c2443/s3c2443.c:68:    s3c24xx_reset_hook = s3c2443_hard_reset;

看到了吧,这3种CPU里面分别对应不同的hook函数,先看看s3c2416_hard_reset的实现:

static void s3c2416_hard_reset(void)
{
    __raw_writel(S3C2443_SWRST_RESET, S3C2443_SWRST);
}

再看看s3c2412_hard_reset的实现:

static void s3c2412_hard_reset(void)
{
    /* errata "Watch-dog/Software Reset Problem" specifies that
     * this reset must be done with the SYSCLK sourced from
     * EXTCLK instead of FOUT to avoid a glitch in the reset
     * mechanism.
     *
     * See the watchdog section of the S3C2412 manual for more
     * information on this fix.
     */

__raw_writel(0x00, S3C2412_CLKSRC);
    __raw_writel(S3C2412_SWRST_RESET, S3C2412_SWRST);

mdelay(1);
}

还有s3c2443_hard_reset的实现:

static void s3c2443_hard_reset(void)
{
    __raw_writel(S3C2443_SWRST_RESET, S3C2443_SWRST);
}

仔细观察,其实都大同小异,应该是2410系列中不同型号的CPU在寄存器上有些细微的差别,或者不同的实现方式。

不过这里arch_reset的参数的用法不同于RK30SDK,这里用了第一个参数mode, 第二个参数cmd却没有使用,这里先留个问题吧,后续再去深究这2个参数的用法。

RK30SDK系统重启源码分析的更多相关文章

  1. 【精】EOS智能合约:system系统合约源码分析

    系统合约在链启动阶段就会被部署,是因为系统合约赋予了EOS链资源.命名拍卖.基础数据准备.生产者信息.投票等能力.本篇文章将会从源码角度详细研究system合约. 关键字:EOS,eosio.syst ...

  2. 开源网站流量统计系统Piwik源码分析——参数统计(一)

    Piwik现已改名为Matomo,这是一套国外著名的开源网站统计系统,类似于百度统计.Google Analytics等系统.最大的区别就是可以看到其中的源码,这正合我意.因为我一直对统计的系统很好奇 ...

  3. 开源网站流量统计系统Piwik源码分析——后台处理(二)

    在第一篇文章中,重点介绍了脚本需要搜集的数据,而本篇主要介绍的是服务器端如何处理客户端发送过来的请求和参数. 一.设备信息检测 通过分析User-Agent请求首部(如下图红线框出的部分),可以得到相 ...

  4. 精尽Spring Boot源码分析 - 日志系统

    该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...

  5. [Abp vNext 源码分析] - 2. 模块系统的变化

    一.简要说明 本篇文章主要分析 Abp vNext 当中的模块系统,从类型构造层面上来看,Abp vNext 当中不再只是单纯的通过 AbpModuleManager 来管理其他的模块,它现在则是 I ...

  6. bootstrap_栅格系统_响应式工具_源码分析

    -----------------------------------------------------------------------------margin 为负 ​使盒子重叠 ​等高 等高 ...

  7. Android源码分析(九)-----如何修改Android系统默认时间

    一 : 修改Android系统默认时间 源码路径:frameworks/base/services/java/com/android/server/SystemServer.java 主要变量EARL ...

  8. Android源码分析(三)-----系统框架设计思想

    一 : 术在内而道在外 Android系统的精髓在源码之外,而不在源码之内,代码只是一种实现人类思想的工具,仅此而已...... 近来发现很多关于Android文章都是以源码的方向入手分析Androi ...

  9. flask框架(三)——路由系统route转换成add_url_rule及源码分析

    这节我们不用@app.route来写路由,而是通过add_url_rule 传统写法  (<int:nid>传递int类型参数,endpoint是取别名) @app.route('/det ...

随机推荐

  1. WIN文件放到LINUX中无法CAT过滤的解决方法

    有个WIN文件放到LINUX服务器上处理的时候,由于编码的问题,导致无法过滤,此时需要对文件进行处理 cat file | tr -s "\r" "\n" &g ...

  2. app开发学习需要经历哪些流程

    app开发学习需要经历哪些流程?如何零基础入门app开发?以下是知乎热心开发者的经验总结,对学习app开发有很好的参考意义   1.如果没有编程基础的,学习基础知识的过程肯定是必须的.2.有了一些基础 ...

  3. 0402-服务注册与发现-Eureka Server使用、将服务注册到Eureka server上

    一.Eureka Server使用 官方文档地址:http://cloud.spring.io/spring-cloud-static/Edgware.SR3/single/spring-cloud. ...

  4. 20170401 错了两天的-XML解析

    你不找到的话,错误就在那里.你找到了错误才会成为财富! Strans XML 解析3要素:1.源xml 格式正常, eg. '<?xml version="1.0" enco ...

  5. 剑指offer 面试14题

    面试14题: 题目:剪绳子 题:给你一根长度为n的绳子,请把绳子剪成m段(m,n都是整数,且n>1,m>1),每段绳子的长度记为k[0],k[1],k[2],...,k[m].请问k[0] ...

  6. Python之正则表达式与常用模块(Day19)

    一.正则表达式:匹配字符串的一种规则 正则表达式的在线测试工具: http://tool.chinaz.com/regex/ 字符组: 正则 待匹配字符 匹配结果 说明 [0123456789] 8 ...

  7. ES集群性能调优链接汇总

    1. 集群稳定性的一些问题(一定量数据后集群变得迟钝) https://elasticsearch.cn/question/84 2. ELK 性能(2) — 如何在大业务量下保持 Elasticse ...

  8. iOS 事件响应者链的学习(也有叫 UI连锁链)

    当发生事件响应的时候,必须知道由谁来响应事件.在iOS中,由响应链来对事件进行响应,所有的事件响应的类都是继承于UIResponder的子类,响应链是一个由不同对象组成的层次结构,其中每个对象将依次获 ...

  9. LeetCode: Keyboard Row

    代码长了些,但还是比较简单的 public class Solution { public String[] findWords(String[] words) { List<String> ...

  10. CentOS 7卸载mariadb安装mysql

    CentOS 7已经将默认集成mariadb而不是mysql,这对于多数还是依赖于mysql的应用来说,需要手动的进行更新. 可能会遇到这样错误,换成MySQL就好了. error 2002 (hy0 ...