QNX在MX27 LITEKIT板上的移植

以前做过linux下的开发,感觉linux开源的程度远远高于QNX,但是正是由于完全开放,所以代码风格各异,针对不同的平台的linux开发包一些底层的接口都不太一样,写驱动程序都要先去看内核的源代码,或者看驱动的代码,去寻找这些接口,然后编写驱动,而QNX就比较标准,接口比较一致,而它又是一个实时操作系统,有自己的集成开发环境,还有一个不错的界面开发工具,所以非常喜欢!
在QNX的官方网站下载到了针对MX27ADS板的BSP,MX27是一个ARM926EJ-S内核的处理器,我手上有两块MX27的板子,一块就是叫做MX27 LITEKIT的板子,是logic公司做的,有一个bootloader叫做logicloader可以使用,于是想在上面跑跑QNX看看,由于时间仓促,只是移植了串口驱动,系统运行起来了,可以在shell下面运行一些命令了,网络驱动什么的还没有修改,不能正常运行,下面是一些移植过程中的一些记录,希望对各位有用。
开始的做法是,在QNX开发环境下编译了BSP包,生成了一个叫bsp-freescale-i.mx27.ifs的image文件,也不知道它具体包含了哪些东西,后来发现在QNX开发环境下面可以看,发现它至少包含了一个完整的文件系统还有启动脚本,因此猜测这是一个完整的可执行映象,但是又看了些QNX的文档,提到了IPL这层软件,所以又有点糊涂了,因为这个针对MX27的BSP包里面没有IPL这部分代码,是不是需要IPL来引导这个bsp-freescale-i.mx27.ifs映象呢,没有IPL,如果想引导这个映象需要做哪些工作,要不要解压缩等等问题都困扰了我好久;没办法,只能试验,幸好MX27 Lite kit板可以跑logicloader和redboot这两个功能比较强的bootloader;
我首先用logicloader加载bsp-freescale-i.mx27.ifs到内存的0xa0100000地址,使用的命令是load raw 0xa0100000 文件长度;然后用命令exec跳转到0xa0100000去执行,结果出现的是乱码;这使我感到莫名其妙,但又想不出所以然;我尝试在QNX开发环境下修改bsp-freescale-i.mx27.ifs的类型,有raw、binary、srec、swaple四种类型,我修改成binary类型重新试验,结果还是不行,连乱码都不输出了;
后来我又看BSP带有文档,于是就打开看了一下,感到非常高兴,里面讲了如何用redboot加载bsp-freescale-i.mx27.ifs以及如何运行等等,于是用logicloader先把redboot加载进来运行,然后用redboot加载bsp-freescale-i.mx27.ifs,按照文档上面的说明来做发现还是不行,输出的还是乱码;
用redboot加载的命令是:
Load –r –b 0x00100000 –m xmodem; 这里的地址0x00100000是个虚拟地址,对应的物理地址其实也是0xa0100000;
然后用命令:run 0x00100000来运行;
结果是乱码;
因为这个BSP包本身不是针对这块板子的,是针对MX27ADS板的,所以不能一下子就正常运行是在意料之中的,但是我对照了MX27ADS板和MX27 Lite kit板的原理图发现晶振用的是一样的,串口硬件也是一样的,所以感觉应该可以在这个板上也能跑起来,于是就去看串口那部分代码,结果发现问题了,是系统的时钟配置不同造成的,由于没有logicloader的源码,reboot编译也麻烦,于是还是使用了以前自己引导linux的boot,根据自己的时钟配置,修改了BSP包里面串口驱动的代码,就是串口波特率相关的几个寄存器。
修改好BSP之后,就是在ADS(ARM develop suite)集成开发环境下编译自己的boot,链接地址RO_BASE和ENTRY_POINT都填写系统RAM地址0XA7000000(我这块板上有128M内存,起始地址为0XA0000000),编译出来生成的二进制文件大小不到4k字节,给它后面补0x00一直到地址0xfff,然后把bsp-freescale-i.mx27.ifs粘贴在后面,也就是从0x1000地址开始就是QNX映象了(我之所以这么做是因为我的boot程序功能比较简单,只是简单的初始化系统硬件然后加载操作系统),我的boot程序是这么写的,运行完初始化后,就到加载地址(0xa7000000)偏移0x1000处去拷贝QNX的映象bsp-freescale-i.mx27.ifs到它的运行时地址0xa0100000上,然后跳转到这个地址执行。加载合并后的这个文件是使用了logicloader,具体命令是:Load raw 0xa7000000 文件长度,然后运行命令exec,就会跳转到0xa7000000处去执行我的boot,然后我的boot执行完系统硬件的一些初始化(要把内存初始化部分去掉,因为内存初始化会把同样放在内存中的我们的代码清掉),就会到偏移0x1000处去拷贝bsp-freescale-i.mx27.ifs,把它拷贝到它的运行时地址0xa0100000,然后跳转到这个地址执行,这样,QNX就能运行起来了。这样,我就弄明白了,bsp-freescale-i.mx27.ifs只需要用一个简单的boot把它加载到它的运行时地址就可以运行。
通过这次简单的移植,我大概清楚了QNX嵌入式开发的流程,当然也花费了几天的时间,包括阅读QNX字符驱动程序开发文档等等,希望以上内容对其它人能有用,再次感谢这个论坛,给大家提供了一个交流的场地。

那你最终也没有用到QNX的IPL?也就是说用linux的bootloader就可以引导了,UBOOT应该也可以吧。

对,是这样的,u-boot可以引导QNX。

QNX里的IPL (Initial Program Loader) 是系统上电后,最先执行的那部份软件。IPL的基本职责是初始化CPU和内存控制器,然后引入Startup+Kernel。换言之,IPL是把板子初始化到startup可以执行的环境。

所以,以i.mx27的例子来说,redboot/u-boot/就是IPL了。当然它们除了初始化CPU、内存以外还做了许多别的工作,但它们都提供了足够Startup运行的环境,同时也都提供了引入Startup的手段(tftp/flash boot)