科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件C函数入口

C函数入口

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

下面就来分析C函数部份功能,当然它还有时需要调用汇编子函数才能实现特殊的功能

作者:caimouse 来源:CSDN 2008年1月22日

关键字: C语言 Linux

  • 评论
  • 分享微博
  • 分享邮件
经历了漫长的汇编之路,最终走到光明的C世界了,进入高级语言环境,会让开发更方便,写更少的语句就可以实现更多的功能。从这里开始,就初始化PCI局部线所有设备,初始化南桥所有的功能,初始化IDE硬盘,初始化网络,初始化显示卡,并进入响应命令阶段。
下面就来分析C函数部份功能,当然它还有时需要调用汇编子函数才能实现特殊的功能。
从上次分析移动代码里,就知道代码已经移到0x8000 0000开始运行了。
void
initmips(unsigned int memsz)
{
    /*
     * Set up memory address decoders to map entire memory.
     * But first move away bootrom map to high memory.
     */
#if 0
    GT_WRITE(BOOTCS_LOW_DECODE_ADDRESS, BOOT_BASE >> 20);
    GT_WRITE(BOOTCS_HIGH_DECODE_ADDRESS, (BOOT_BASE - 1 + BOOT_SIZE) >> 20);
#endif
    memorysize = memsz > 256 ? 256 << 20 : memsz << 20;
    memorysize_high = memsz > 256 ? (memsz - 256) << 20 : 0;
上面代码,由于在汇编里就已经设置好三个参数,第一个参数为内存的大小,并且单位是字节。汇编代码如下:
move   a0,msize
    srl a0,20
memorysize就保存低端内存的大小,小于或等256Mmemorysize_high保存高于256M的内存大小。这样就知道系统内存的大小了。
 
#if 0
    {
     int start = 0x80000000;
     int end = 0x80000000 + 16384;
 
     while (start < end) {
        __asm__ volatile (" cache 1,0(%0)\r\n"
                     " cache 1,1(%0)\r\n"
                     " cache 1,2(%0)\r\n"
                     " cache 1,3(%0)\r\n"
                     " cache 0,0(%0)\r\n"::"r"(start));
        start += 32;
     }
 
     __asm__ volatile ( " mfc0 $2,$16\r\n"
                       " and $2, $2, 0xfffffff8\r\n"
              " or   $2, $2, 2\r\n"
              " mtc0 $2, $16\r\n" :::"$2");
    }
#endif
 
    /*
     * Probe clock frequencys so delays will work properly.
     */
    tgt_cpufreq();
这里实现CPU频率的设置和检测。
 
    SBD_DISPLAY("DONE",0);
    /*
     * Init PMON and debug
     */
    cpuinfotab[0] = &DBGREG;
    dbginit(NULL);
上面函数实现调试和大部份的功能初始化。
 
    /*
     * Set up exception vectors.
     */
    SBD_DISPLAY("BEV1",0);
    bcopy(MipsException, (char *)TLB_MISS_EXC_VEC, MipsExceptionEnd - MipsException);
    bcopy(MipsException, (char *)GEN_EXC_VEC, MipsExceptionEnd - MipsException);
上面代码实现异常向量的设置。
 
    CPU_FlushCache();
上面代码重新初始化缓存。
 
    CPU_SetSR(0, SR_BOOT_EXC_VEC);
上面代码设置状态寄存器,可以执行异常处理了,启动模式已经结束,进入正常模式运行。
 
    SBD_DISPLAY("BEV0",0);
   
    printf("BEV in SR set to zero.\n");
 
   
#if 0
    /* memtest */
    addr_tst1();
    addr_tst2();
    movinv1(2,0,~0);
    movinv1(2,0xaa5555aa,~0xaa5555aa);
    printf("memtest done\n");
#endif
 
    /*
     * Launch!
     */
    main();
上面就进入命令交换阶段。
 
}
/*蔡军生 2007-1-5 于深圳*/
C的代码,就是比看汇编简单多了,到这里,就已经看完了整个流程了。不过,在那些调用的函数里,还是实现非常复杂的功能的。比如显示卡,就是最复杂的部份,由于它的BIOS代码是为X86CPU执行的,不能直接在龙芯2E里运行,这样就变得非常复杂了,因此龙芯2E里就要实现一个模拟X86CPU功能才能运行显示卡的BIOS程序。不知道那天有了我们自己的显示卡厂商,才可能开发适用龙芯2E的显示卡BIOS,这样才会变得非常简单了。
 

查看本文来源
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章