ecos运行流程分析

先实践后理论,我使用一块CPE301G-QCA9535的开发板进行分析。这块开发板是在开发中的ecos。

一)宏观分析ecos的运行

我们从启动日志入手,去一步一步了解ecos的运行。

总所周知,板子(soc)启动有3阶段。分别为运行ROM上的固化程序,运行u-boot-spl 和运行uboot。所以我们打包的uboot的名称经常叫uboot-with-spl.bin。细节可以自行百度。

运行ROM上的固化程序阶段没有打印,这就是为什么板子能从其他地方加载系统的原因。

板子启动spl+uboot阶段,打印如下:

ecos运行流程分析

ecos运行流程分析

程序就Now running in RAM - U-Boot at: 807dc000,开始运行uboot了。

初始化串口和网卡

ecos运行流程分析

开始加载镜像

ecos运行流程分析

开始运行kernel

ecos运行流程分析

程序开始运行一个应用程序了,这个程序ecosap这个可执行程序。

ecos运行流程分析

ecos运行流程分析

这样我们从宏观上看到了整个ecos的运行情况。

二)从代码层面分析ecos的运行

在qca9535_ecos_sdk/ecos/ecosap 目录下有个ecosap.c文件,文件里面有个main函数。因为ecos只能运行一个程序,所以就只能运行ecosap这个可执行文件了。如下图:

ecos运行流程分析

ecos运行流程分析

怎么运行这个ecosap文件呢?我们看一下它的文件格式是我们熟悉的elf,我们知道运行elf是需要ELF Loader的,ecos应该是没有这个东西的;毕竟ecos只需运行一个程序就万事大吉了。格式如下图:

ecos运行流程分析

然后我就去看make 编译的打印,被我发现了一些线索。如下图:

ecos运行流程分析

Objcopy就是把裸的机器码拷贝出来,啥说明和格式都不要。要想运行裸的机器码,第一步加载到内存;第二步从该地址进行运行。这下我知道ecosap是脱了衣服成ecosap.bin之后再运行的。

ecos运行流程分析

给一个运行裸文件的例子:

RedBoot> lo -b 0x81010000 -r -m xmodem

    Raw file loaded 0x81010000-0x810252cb, assumed entry at 0x81010000

    xyzModem - CRC mode, 679(SOH)/0(STX)/0(CAN) packets, 2 retries

RedBoot> go 0x81010000

不可能每次上电后,手敲运行。那就打一个包,自动加载运行。

我们发现这些编译控制都在eCosap.mk中,如下图。先对ecosap进行使用lzma进行压缩,然后使用mkimage进行打包出一个ecosap.lzma.uImage_201910231807包,这个只是一个内核,不带uboot;也没有根文件系统。

ecos运行流程分析

mkimage的基本参数如下:

ecos运行流程分析

这样子就实现了使用uboot自动将kerenl加载到指定RAM地址中,然后运行就好了。这样就万事大吉了。

 

三)验证一下上面的分析

3.1再回首uboot加载image的过程

一顿操作猛如虎,一看战绩0-5。我们回头看一下uboot加载image的截图,如下。

ecos运行流程分析

你会发现参数都是我们使用mkimage生成的。Image Name 就是我们使用mkimage写的-n eCosAP;Image Type:MIIPS Linux Kernel Image (lzma compressed);Load Address 0x80000000,Entry Point 0x800001bc世界真小。

见证奇迹的时刻,解压 内核的大小 1183484bytes,我们看一我们裸奔的ecosap.bin的大小就是1183484bytes。这就对上了。

ecos运行流程分析

然后就开始在0x800001bc上疯狂的裸奔。

3.2再回首kernel的裸奔

ecos运行流程分析

上面是在运行ecosap的main-->ecosap_start--> print Starting AP之前的打印,这些函数在哪里运行的呢?

ecos运行流程分析

现在探究一下上面的问题。看了一下代码,原来是利用c++的类的构造函数+使用__attribute__((init_priority(_pri_)))属性来实现在main函数之前运行一些初始化。这下终于揭开了一个裸奔的ecos的正面目。

ecos运行流程分析