zoukankan      html  css  js  c++  java
  • linux2.4内核启动流程简述及2410主频修改

    内核版本2.4.18

    一、linux2.4内核启动流程

    arch/arm/boot/compressed/head.s ----->调用arch/arm/boot/compressed/misc.c的decompress_kernel()
    函数解压内核。---->arch/arm/kernel/head-armv.s 初始化 --->
    init/main.c的asmlinkage void __init start_kernel(void)

     

    二、修改2410linux主频

    (1)代码修改

    在内核启动之时切换CPU主频arch/arm/boot/compressed/head.S,代码如下(主频设为264M):
            ldr  r8, =0x4C000000
            ldr  r9, =0xffffff
            str  r9, [r8]

            ldr  r8, =0x4C000014
            mov  r9, #3
            str  r9, [r8]

            ldr  r8, =0x4C000004
            ldr  r9, =0xa8021
            str  r9, [r8]

            ldr  r8, =0x50000028
            ldr  r9, =0x23
            str  r9, [r8]

     

    (2)问题及bug。若将2410的主频设为266M等其他,内核启动都会停在:

    Uncompressing Linux......................................................................................................................... done, booting the kernel.

    网上很多人遇到的情况与此不同,很多都是启动参数配置错误导致或CPU的id与内核不匹配导致。

    此因修改了2410的主频原因导致,根本原因不是2410(尾数为20)不能支持这么高的频率

    也不是内存clk频率过高而导致的不稳定。而是kernel的start_kernel()函数中对timer的

    初始化有bug。

    ./arch/arm/kernel/time.c:void __init time_init(void)

    include/asm-arm/arch-s3c2410/time.h:static inline void setup_timer(void)

    在第二个函数中代码修改如下:

    -----------------

    static inline void setup_timer(void)
    {
        struct timer_counts *timer_count = count_values;
        unsigned long pclk;

        gettimeoffset = s3c2410_gettimeoffset;
        set_rtc = s3c2410_set_rtc;
        xtime.tv_sec = s3c2410_get_rtc_time();

        /* set timer interrupt */
        /*TCFG0 = (TCFG0_DZONE(0) | TCFG0_PRE1(15) | TCFG0_PRE0(0));*/

        TCFG0 = (15<<8)|32;

        pclk = s3c2410_get_bus_clk(GET_PCLK)/1000;

    /*(TCFG0_DZONE(0) | TCFG0_PRE1(30) | TCFG0_PRE0(((pclk/2000000)-1)));*/

        //while (timer_count != 0) {   //---------------fix bug------------leaven
        while(timer_count->freq != 0){
            if (pclk == timer_count->freq) {
                printk("DEBUG: timer count %d\n", timer_count->count);
                TCNTB4 = timer_count->count;
                break;
            }
            timer_count++;
        }

        //if (timer_count == 0) {   //------------------fix bug---------leaven
        if(timer_count->freq==0){
                /* Error, assume that PCLK is 50 Mhz */
            TCNTB4 = 15626;    /* down-counter, maximum value is 65535 (2^16) */
        }

        TCON = (TCON_4_AUTO | TCON_4_UPDATE | COUNT_4_OFF);   
        timer_irq.handler = s3c2410_timer_interrupt;
        setup_arm_irq(IRQ_TIMER4, &timer_irq);
        TCON = (TCON_4_AUTO | COUNT_4_ON);
    }

    -----------------

    从如下代码中可以看到linux2410默认支持的主频是有限的,如要设置自己的频率需要加入新的成员至数组中:

    -----------------

    /*
    * priod = (prescaler value + 1) * (divider value) * buffer count / PCLK = 10 ms
    *
    * e.g.; PCLK = 50 Mhz
    * 10 ms = (15 + 1) * 2 * 15625 / (50000 * 1000)
    * 15626 = 10 ms * (50000 * 1000) / 2 / (15 + 1)
    *
    * Other values
    *  5156 = 10 ms * ( 16.5 * 1,000,000) / 2 / (15+1)
    *  6250 = 10 ms * ( 20 * 1,000,000) / 2 / (15+1)
    * 10312 = 10 ms * ( 33 * 1,000,000) / 2 / (15+1)
    * 20625 = 10 ms * ( 66 * 1,000,000) / 2 / (15+1) //for 264M
    * 21875 = 10 ms * ( 70 * 1,000,000) / 2 / (15+1)
    * 23437 = 10 ms * ( 75 * 1,000,000) / 2 / (15+1)
    * 25000 = 10 ms * ( 80 * 1,000,000) / 2 / (15+1)
    * 28125 = 10 ms * ( 90 * 1,000,000) / 2 / (15+1)
    * 31250 = 10 ms * ( 100 * 1,000,000) / 2 / (15+1)
    */
    struct timer_counts count_values[] = {
        {  16500,     5156 },
        {  20000,     6250 },
        {  33000,    10312 },
        {  50000,    15626 },
        {  66000,    20625 },
        {  70000,    21875 },
        {  75000,    23437 },
        {  80000,    25000 },
        {  90000,    28125 },
        { 100000,    31250 },
        {      0,        0 }    /* last entry */
    };

    -----------------

    arch/arm/kernel/Makefile中对time.c的编译十分特别,别的都是*.o 而其为time.module

  • 相关阅读:
    spring事务注解@Transactional注解失效场景
    Dubbo中服务消费者和服务提供者之间的请求和响应过程
    说说Java的Unsafe类
    java程序二叉树的深度优先和广度优先遍历
    重复注解与类型注解
    git pull 和 git fetch的区别?
    Java8新特性系列(Interface)
    二十种健康食品排行榜
    赞美的时机
    越过胆怯这道栅栏
  • 原文地址:https://www.cnblogs.com/leaven/p/1804442.html
Copyright © 2011-2022 走看看