OK335xS Linux kernel check clock 24M hacking

/******************************************************************************
 *              OK335xS Linux kernel check clock 24M hacking
 * 声明:
 *     由于需要确认kernel中的时钟和引脚配置的时钟是否一致,于是需要去跟踪内核
 * 中的代码是如何对引脚配置时钟进行识别,并对其进行相关配置的额。
 *
 *                                            2016-1-5 深圳 南山平山村 曾剑锋
 *****************************************************************************/

MACHINE_START(AM335XEVM, "am335xevm")
    /* Maintainer: Texas Instruments */
    .atag_offset    = 0x100,
    .map_io         = am335x_evm_map_io,
    .init_early     = am33xx_init_early,    ---------------+
    .init_irq       = ti81xx_init_irq,                     |
    .handle_irq     = omap3_intc_handle_irq,               |
    .timer          = &omap3_am33xx_timer,                 |
    .init_machine   = am335x_evm_init,                     |
MACHINE_END                                                |
                                                           |
void __init am33xx_init_early(void)         <--------------+
{
    omap2_set_globals_am33xx();
    omap3xxx_check_revision();
    am33xx_check_features();
    omap_common_init_early();
    am33xx_voltagedomains_init();
    omap44xx_prminst_init();
    am33xx_powerdomains_init();
    omap44xx_cminst_init();
    am33xx_clockdomains_init();
    am33xx_hwmod_init();
    omap_hwmod_init_postsetup();
    omap3xxx_clk_init();                    --------------+
}                                                         |
                                                          |
int __init omap3xxx_clk_init(void)          <-------------+
{
    struct omap_clk *c;
    u32 cpu_clkflg = 0;

    /*
     * 3505 must be tested before 3517, since 3517 returns true
     * for both AM3517 chips and AM3517 family chips, which
     * includes 3505.  Unfortunately there‘s no obvious family
     * test for 3517/3505 :-(
     */
    if (cpu_is_omap3505()) {
        cpu_mask = RATE_IN_34XX;
        cpu_clkflg = CK_3505;
    } else if (cpu_is_omap3517()) {
        cpu_mask = RATE_IN_34XX;
        cpu_clkflg = CK_3517;
    } else if (cpu_is_omap3505()) {
        cpu_mask = RATE_IN_34XX;
        cpu_clkflg = CK_3505;
    } else if (cpu_is_omap3630()) {
        cpu_mask = (RATE_IN_34XX | RATE_IN_36XX);
        cpu_clkflg = CK_36XX;
    } else if (cpu_is_ti816x()) {
        cpu_mask = RATE_IN_TI816X;
        cpu_clkflg = CK_TI816X;
    } else if (cpu_is_am33xx()) {
        am33xx_clk_init();                      ---------------------------+
        return 0;                                                          |
    } else if (cpu_is_ti814x()) {                                          |
        cpu_mask = RATE_IN_TI814X;                                         |
    } else if (cpu_is_omap34xx()) {                                        |
        if (omap_rev() == OMAP3430_REV_ES1_0) {                            |
            cpu_mask = RATE_IN_3430ES1;                                    |
            cpu_clkflg = CK_3430ES1;                                       |
        } else {                                                           |
            /*                                                             |
             * Assume that anything that we haven‘t matched yet            |
             * has 3430ES2-type clocks.                                    |
             */                                                            |
            cpu_mask = RATE_IN_3430ES2PLUS;                                |
            cpu_clkflg = CK_3430ES2PLUS;                                   |
        }                                                                  |
    } else {                                                               |
        WARN(1, "clock: could not identify OMAP3 variant\n");              |
    }                                                                      |
    ......                                                                 |
}                                                                          |
                                                                           |
int __init am33xx_clk_init(void)                   <-----------------------+
{
    struct omap_clk *c;
    u32 cpu_clkflg;

    if (cpu_is_am33xx()) {
        cpu_mask = RATE_IN_AM33XX;
        cpu_clkflg = CK_AM33XX;
    }

    clk_init(&omap2_clk_functions);                ------------------------+
                                                                           |
    for (c = am33xx_clks; c < am33xx_clks + ARRAY_SIZE(am33xx_clks); c++)--*---+
        clk_preinit(c->lk.clk);                                            |   |
                                                                           |   |
    for (c = am33xx_clks; c < am33xx_clks + ARRAY_SIZE(am33xx_clks); c++)  |   |
        if (c->cpu & cpu_clkflg) {                                         |   |
            clkdev_add(&c->lk);                                            |   |
            clk_register(c->lk.clk);                                       |   |
            omap2_init_clk_clkdm(c->lk.clk);               ----------------*-+ |
        }                                                                  | | |
                                                                           | | |
    recalculate_root_clocks();                                             | | |
                                                                           | | |
    /*                                                                     | | |
     * Only enable those clocks we will need, let the drivers              | | |
     * enable other clocks as necessary                                    | | |
     */                                                                    | | |
    clk_enable_init_clocks();                     -------------------------*-*-*-+
                                                                           | | | |
    return 0;                                                              | | | |
}                                                                          | | | |
                                                                           | | | |
                                                                           | | | |
/* Common data */                                                          | | | |
                                                                           | | | |
struct clk_functions omap2_clk_functions = {            <------------------+ | | |
    .clk_enable            = omap2_clk_enable,                             | | | |
    .clk_disable        = omap2_clk_disable,                               | | | |
    .clk_round_rate        = omap2_clk_round_rate,                         | | | |
    .clk_set_rate        = omap2_clk_set_rate,                             | | | |
    .clk_set_parent        = omap2_clk_set_parent,                         | | | |
    .clk_disable_unused    = omap2_clk_disable_unused,                     | | | |
#ifdef CONFIG_CPU_FREQ                                                     | | | |
    /* These will be removed when the OPP code is integrated */            | | | |
    .clk_init_cpufreq_table    = omap2_clk_init_cpufreq_table,             | | | |
    .clk_exit_cpufreq_table    = omap2_clk_exit_cpufreq_table,             | | | |
#endif                                                                     | | | |
};                                                                         | | | |
                                                                           | | | |
static struct clk_functions *arch_clock;                     --------------*-*-*-*-+
int __init clk_init(struct clk_functions * custom_clocks)    <-------------+ | | | |
{                                                                            | | | |
    if (!custom_clocks) {                                                    | | | |
        pr_err("No custom clock functions registered\n");                    | | | |
        BUG();                                                               | | | |
    }                                                                        | | | |
                                                                             | | | |
    arch_clock = custom_clocks;                                              | | | |
                                                                             | | | |
    return 0;                                                                | | | |
}                                                                            | | | |
                                                                             | | | |
void omap2_init_clk_clkdm(struct clk *clk)        <--------------------------+ | | |
{                                                                              | | |
    struct clockdomain *clkdm;                                                 | | |
                                                                               | | |
    if (!clk->clkdm_name)                                                      | | |
        return;                                                                | | |
                                                                               | | |
    clkdm = clkdm_lookup(clk->clkdm_name);              -------+               | | |
    if (clkdm) {                                               |               | | |
        printk("clock: associated clk %s to clkdm %s\n",       |               | | |
             clk->name, clk->clkdm_name);                      |               | | |
        pr_debug("clock: associated clk %s to clkdm %s\n",     |               | | |
             clk->name, clk->clkdm_name);                      |               | | |
        clk->clkdm = clkdm;                                    |               | | |
    } else {                                                   |               | | |
        pr_debug("clock: could not associate clk %s to "       |               | | |
             "clkdm %s\n", clk->name, clk->clkdm_name);        |               | | |
    }                                                          |               | | |
}                                                              |               | | |
                                                               |               | | |
struct clockdomain *clkdm_lookup(const char *name)      <------+               | | |
{                                                                              | | |
    struct clockdomain *clkdm, *temp_clkdm;                                    | | |
                                                                               | | |
    if (!name)                                                                 | | |
        return NULL;                                                           | | |
                                                                               | | |
    clkdm = NULL;                                                              | | |
                                                                               | | |
    list_for_each_entry(temp_clkdm, &clkdm_list, node) {                       | | |
        if (!strcmp(name, temp_clkdm->name)) {                                 | | |
            clkdm = temp_clkdm;                                                | | |
            break;                                                             | | |
        }                                                                      | | |
    }                                                                          | | |
                                                                               | | |
    return clkdm;                                                              | | |
}                                                                              | | |
                                                                               | | |
                                                                               | | |
/*                                                                             | | |
 * clkdev         +----------------------------------------------------------+ | | |
 */               |                                                          | | | |
static struct omap_clk am33xx_clks[] = {                     <---------------*-+ | |
    ......                                                                   |   | |
    CLK(NULL,    "clk_rc32k_ck",        &clk_rc32k_ck,    CK_AM33XX),        |   | |
    CLK(NULL,    "virt_19_2m_ck",    &virt_19_2m_ck,    CK_AM33XX),          |   | |
    CLK(NULL,    "virt_24m_ck",        &virt_24m_ck,    CK_AM33XX),          |   | |
    CLK(NULL,    "virt_25m_ck",        &virt_25m_ck,    CK_AM33XX),          |   | |
    CLK(NULL,    "virt_26m_ck",        &virt_26m_ck,    CK_AM33XX),          |   | |
    CLK(NULL,    "sys_clkin_ck",        &sys_clkin_ck,    CK_AM33XX),  ----+ |   | |
    CLK(NULL,    "tclkin_ck",        &tclkin_ck,    CK_AM33XX),            | |   | |
    CLK(NULL,    "dpll_core_ck",        &dpll_core_ck,        CK_AM33XX),  | |   | |
    CLK(NULL,    "dpll_core_x2_ck",    &dpll_core_x2_ck,    CK_AM33XX),    | |   | |
    CLK(NULL,    "dpll_core_m4_ck",    &dpll_core_m4_ck,    CK_AM33XX),    | |   | |
    CLK(NULL,    "dpll_core_m5_ck",    &dpll_core_m5_ck,    CK_AM33XX),    | |   | |
    CLK(NULL,    "dpll_core_m6_ck",    &dpll_core_m6_ck,    CK_AM33XX),    | |   | |
    CLK(NULL,    "sysclk1_ck",        &sysclk1_ck,    CK_AM33XX),          | |   | |
    CLK(NULL,    "sysclk2_ck",        &sysclk2_ck,    CK_AM33XX),          | |   | |
    ......                                                                 | |   | |
};   |                                                                     | |   | |
     +-----------------------------------------+                           | |   | |
struct omap_clk {                              |             <-------------*-+   | |
    u16                        cpu;            |                           |     | |
    struct clk_lookup        lk;               |                           |     | |
};                                             |                           |     | |
                                               |                           |     | |
#define CLK(dev, con, ck, cp)         \   <----+                           |     | |
    {                \                                                     |     | |
         .cpu = cp,        \                                               |     | |
        .lk = {            \                                               |     | |
            .dev_id = dev,    \                                            |     | |
            .con_id = con,    \                                            |     | |
            .clk = ck,    \                                                |     | |
        },            \                                                    |     | |
    }                                                                      |     | |
                                                                           |     | |
/* sys_clk_in */                                                           |     | |
static struct clk sys_clkin_ck = {                      <------------------+     | |
    .name        = "sys_clkin_ck",                                               | |
    .parent        = &virt_24m_ck,                                               | |
    .init        = &omap2_init_clksel_parent,           ----------------------+  | |
/**                                                                           |  | |
 * +------------------------------------------------------------------------+ |  | |
 * |        Table 9-14. control_status Register Field Descriptions          | |  | |
 * +-------+----------+------------+----------------------------------------+ |  | |
 * | Bit   | Field    | Type Reset | Description                            | |  | |
 * +-------+----------+------------+----------------------------------------+ |  | |
 * | 23-22 | sysboot1 | R/W 0h     | Used to select crystal clock frequency.| |  | |
 * |       |          |            | See SYSBOOT Configuration Pins.        | |  | |
 * |       |          |            | Reset value is from SYSBOOT[15:14].    | |  | |
 * +-------+----------+------------+----------------------------------------+ |  | |
 */                                                                           |  | |
    .clksel_reg    = AM33XX_CTRL_REGADDR(0x40),    /* CONTROL_STATUS */       |  | |
    .clksel_mask    = (0x3 << 22),                                            |  | |
    .clksel        = sys_clkin_sel,       -----------+                        |  | |
    .ops        = &clkops_null,           -----------*-----+                  |  | |
    .recalc        = &omap2_clksel_recalc,           |     |                  |  | |
};                                                   |     |                  |  | |
                                                     |     |                  |  | |
/* Oscillator clock */                               |     |                  |  | |
/* 19.2, 24, 25 or 26 MHz */                         |     |                  |  | |
static const struct clksel sys_clkin_sel[] = {  <----+     |                  |  | |
    { .parent = &virt_19_2m_ck, .rates = div_1_0_rates },  |                  |  | |
    { .parent = &virt_24m_ck, .rates = div_1_1_rates },    |   ------+        |  | |
    { .parent = &virt_25m_ck, .rates = div_1_2_rates },    |         |        |  | |
    { .parent = &virt_26m_ck, .rates = div_1_3_rates },    |         |        |  | |
    { .parent = NULL },                  |                 |         |        |  | |
};                                       |                 |         |        |  | |
                                         |                 |         |        |  | |
static struct clk virt_24m_ck = {        |        <--------*---------+        |  | |
    .name        = "virt_24m_ck",        |                 |                  |  | |
    .rate        = 24000000,             |                 |                  |  | |
    .ops        = &clkops_null,          |                 |                  |  | |
};                                       |                 |                  |  | |
                                         v                 |                  |  | |
static const struct clksel_rate div_1_1_rates[] = {        |                  |  | |
    { .div = 1, .val = 1, .flags = RATE_IN_AM33XX },       |                  |  | |
    { .div = 0 },                                          |                  |  | |
};                                                         |                  |  | |
                                                           |                  |  | |
const struct clkops clkops_null = {             <----------+                  |  | |
    .enable        = clkll_enable_null,                                       |  | |
    .disable    = clkll_disable_null,                                         |  | |
};                                                                            |  | |
                                                                              |  | |
                                                                              |  | |
// 到目前为止都不知道哪里调用了这个函数,因为这个函数是用来判断系统接入的晶振 |  | |
// 大小的,没跟踪到到底是谁调用了该函数。                                     |  | |
void omap2_init_clksel_parent(struct clk *clk)           <--------------------+  | |
{                                                                                | |
    const struct clksel *clks;                                                   | |
    const struct clksel_rate *clkr;                                              | |
    u32 r, found = 0;                                                            | |
                                                                                 | |
    if (!clk->clksel || !clk->clksel_mask)                                       | |
        return;                                                                  | |
                                                                                 | |
    r = __raw_readl(clk->clksel_reg) & clk->clksel_mask;                         | |
    r >>= __ffs(clk->clksel_mask);                                               | |
                                                                                 | |
    for (clks = clk->clksel; clks->parent && !found; clks++) {                   | |
        for (clkr = clks->rates; clkr->div && !found; clkr++) {                  | |
            if (!(clkr->flags & cpu_mask))                                       | |
                continue;                                                        | |
                                                                                 | |
            if (clkr->val == r) {                                                | |
                if (clk->parent != clks->parent) {                               | |
                    pr_debug("clock: inited %s parent "                          | |
                         "to %s (was %s)\n",                                     | |
                         clk->name, clks->parent->name,                          | |
                         ((clk->parent) ?                                        | |
                          clk->parent->name : "NULL"));                          | |
                    clk_reparent(clk, clks->parent);         ------------+       | |
                };                                                       |       | |
                found = 1;                                               |       | |
            }                                                            |       | |
        }                                                                |       | |
    }                                                                    |       | |
                                                                         |       | |
    printk("zengjf ckeck function calling [%s].\n", __func__);           |       | |
    /* This indicates a data error */                                    |       | |
    WARN(!found, "clock: %s: init parent: could not find regval %0x\n",  |       | |
         clk->name, r);                                                  |       | |
                                                                         |       | |
    return;                                                              |       | |
}                                                                        |       | |
                                                                         |       | |
int clk_reparent(struct clk *c, struct clk *parent)          <-----------+       | |
{                                                                                | |
    c->parent = parent;                                                          | |
    return 0;                                                                    | |
}                                                                                | |
                                                                                 | |
void clk_enable_init_clocks(void)                            <-------------------+ |
{                                                                                  |
    struct clk *clkp;                                                              |
                                                                                   |
    list_for_each_entry(clkp, &clocks, node) {                                     |
        if (clkp->flags & ENABLE_ON_INIT)                                          |
            clk_enable(clkp);                                -------+              |
    }                                                               |              |
}                                                                   |              |
                                                                    |              |
/*                                                                  |              |
 * Standard clock functions defined in include/linux/clk.h          |              |
 */                                                                 |              |
                                                                    |              |
int clk_enable(struct clk *clk)                              <------+              |
{                                                                                  |
    unsigned long flags;                                                           |
    int ret;                                                                       |
                                                                                   |
    if (clk == NULL || IS_ERR(clk))                                                |
        return -EINVAL;                                                            |
                                                                                   |
    if (!arch_clock || !arch_clock->clk_enable)                                    |
        return -EINVAL;                                                            |
                                                                                   |
    spin_lock_irqsave(&clockfw_lock, flags);                                       |
    ret = arch_clock->clk_enable(clk);                      <----------------------+
    spin_unlock_irqrestore(&clockfw_lock, flags);

    return ret;
}
EXPORT_SYMBOL(clk_enable);
时间: 2024-10-28 22:09:48

OK335xS Linux kernel check clock 24M hacking的相关文章

[RK_2014_0919]Linux Kernel Hacking

KernelBuild Guide to building the Linux kernel. Where do I find the kernel? The latest source code for the Linux kernel is kept on kernel.org. You can either download the full source code as a tar ball (not recommended and will take forever to downlo

Linux Kernel - Debug Guide (Linux内核调试指南 )

http://blog.csdn.net/blizmax6/article/details/6747601 linux内核调试指南 一些前言 作者前言 知识从哪里来 为什么撰写本文档 为什么需要汇编级调试 ***第一部分:基础知识*** 总纲:内核世界的陷阱 源码阅读的陷阱 代码调试的陷阱 原理理解的陷阱 建立调试环境 发行版的选择和安装 安装交叉编译工具 bin工具集的使用 qemu的使用 initrd.img的原理与制作 x86虚拟调试环境的建立 arm虚拟调试环境的建立 arm开发板调试环

linux内核可以接受的参数 | Linux kernel启动参数 | 通过grub给内核传递参数

在Linux中,给kernel传递参数以控制其行为总共有三种方法: 1.build kernel之时的各个configuration选项. 2.当kernel启动之时,可以参数在kernel被GRUB或LILO等启动程序调用之时传递给kernel. 3.在kernel运行时,修改/proc或/sys目录下的文件. 这里我简单讲的就是第二种方式了,kernel在grub中配置的启动参数. 首先,kernel有哪些参数呢? 在linux的源代码中,有这样的一个文档Documentation/kern

linux kernel 字符设备详解

有关Linux kernel 字符设备分析: 参考:http://blog.jobbole.com/86531/ 一.linux kernel 将设备分为3大类,字符设备,块设备,网络设备. 字符设备是指只能一个字节一个字节读写的设备, 常见的外设基本上都是字符设备. 块设备:常见的存储设备,硬盘,SD卡都归为块设备,块设备是按一块一块读取的. 网络设备:linux 将对外通信的一个机制抽象成一个设备, 通过套接字对其进行相关的操作. 每一个字符设备或块设备都在/dev目录下对应一个设备文件.l

Linux snacks from &lt;linux kernel development&gt;

introduction to the Linux kernel 1.operating system 1) considered the parts of the system 2) responsible for basic use and administration. 3) includes the kernel and device drivers, boot loader, command shell or other user interface, and basic file a

Android linux kernel privilege escalation vulnerability and exploit (CVE-2014-4322)

In this blog post we'll go over a Linux kernel privilege escalation vulnerability I discovered which enables arbitrary code execution within the kernel. The vulnerability affected all devices based on Qualcomm chipsets (that is, based on the "msm&quo

Linux kernel parameter command line设置

现在CPU2核以上比较普遍了,平时用linux上上网可能用不着双核甚至4核,大部分发行版内核都启用了CPU_HOTPLUG,到/sys/devices/system/cpu下可以看到文件夹cpu0.cpu1,除cpu0(这个不能关)每个文件夹下都有一个online文件,往里面写0就可以关闭核心,比如我的T7300,echo '0' >/sys/devices/system/cpu/cpu1/online 就可以关闭第二个核,不影响小型应用.要开启,往里面echo 1就行.这个操作好像要root完

#26 Linux kernel(内核)详解与uname、lsmod、modinfo、depmod、insmod、rmmod、modprobe...命令用法

Linux kernel: 内核设计流派: 单内核设计,但是充分借鉴了微内核体系设计的优点,为内核引入了模块化机制,内核高度模块化: 内核被模块化之后,一些最为基本最为重要的内容,被编译到内核核心:而其他更多的功能则以模块的方式来提供:而且支持动态装载和卸载各内核模块: 内核的组成部分: kernel:内核核心文件,一般为bzimage,经过压缩处理的镜像文件:通常内核核心文件保存在/boot/目录下,名称为vmlinuz-version-release kernel object(ko):内核

video : Write and Submit your first Linux kernel Patch

http://v.youku.com/v_show/id_XNDMwNzc3MTI4.html After working with Linux (mostly as an advanced user) for years, I decided to post my first p=linux/kernel/git/x86/linux-2.6-tip.git;a=commitdiff;h=e19e074b1525d11a66c8e3386fec7db248ad3005" style="