编写IPL程序

QNX相关历史文章:

这篇文章主要描述Initial program loader的相关内容,并以Freescale IXM6处理器为例讲解

1. Initial program loader

IPL的功能可以类比Uboot,IPL程序的任务是对硬件进行最低限度的配置,以创建一个startup程序运行的环境,至少包括以下内容:

  • 从Reset异常向量开始执行;
  • 配置内存控制器;
  • 配置时钟;
  • 设置堆栈,以便允许IPL库执行OS的验证和设置(下载、扫描、设置、跳转到OS镜像)

IPL的代码可能很简单,也可能非常复杂,这分别对应到Warm-start和Cold-start。在Warm-start中,已经有BIOS或者ROM monitor了,IPL需要做的工作就会少很多,而在Cold-start中,没有BIOS或者ROM monitor,因此需要实现全部的功能。

IPL的初始化部分是用汇编实现的(因为它从ROM执行,没有内存控制器),初始化硬件之后,IPL调用main()函数来初始化C语言环境。

设置好C语言环境后,IPL可以执行不同的任务,这个具体取决于操作系统是从linearly mapped设备启动,还是从bank-switched设备启动:

  • linearly mapped,整个镜像在处理器的线性地址空间中,比如ROM;
  • bank-switched,镜像不能完全由处理器寻址,比如Disk device、Network设备、串口或并口、以及bank-switched的ROM或RAM;

1.1 bank-switched

从bank-switched设备中启动时,需要以下几步:

  • IPL必须调用函数与相关设备通信,比如串口下载时,IPL使用image_download_8250()函数,该函数用于配置和控制8250类串口控制器,完成设置后,该函数会将image拷贝到RAM中;
  • IPL调用image_sacn()来扫描整个image,完成一些校验工作;
  • IPL调用image_setup()来完成一些设置工作;
  • IPL调用image_start(),跳转到startup的起始地址,将控制权交给startup;
    镜像加载时,由于是bank-switched,所以需要将整个镜像都拷贝到RAM中,如下图所示:


从图中可以看出来,IPL处理时可以分为三步:

  • IPL接收控制;
  • IPL将image加载到RAM中;
  • IPL将控制权交给加载的image;

1.2 linearly mapped

linearly mapped设备的启动方式与bank-switched设备是一致的,不同点在于,不需要将整个image都拷贝到RAM中,如下图所示:


2. 自定义IPL程序

编写IPL程序,需要以下几个步骤:

  • 初始化硬件,包括对系统RAM的访问。注意,只需要初始化必须的硬件(比如时钟等),外围硬件不需要初始化;(汇编实现)
  • 将image镜像(使用mkifs生成)加载到RAM中,加载程序使用header信息来拷贝header和startup到RAM中,如果不是在linearly mapped的设备中,则需要将整个镜像拷贝到RAM中;(比如image_download_8250())
  • 定位OS镜像,并做一些校验工作;(调用image_sacn())
  • 拷贝startup程序;(调用image_setup())
  • 跳转到加载镜像起始位置执行;(调用image_start())

3. IPL库

IPL库包含了一系列的接口,用于实现自定义的IPL程序,可用的函数接口如下:


4. Freescale IMX6 IPL

Freescale IMX6 BSP包:BSP_freescale-imx6SoloX-sabre-sdb_br-660_be-660_SVN815609_JBN555.zip

下载Freescale IMX6 BSP zip包并解压,IPL代码位于src/hardware/ipl/boards/mx6sx-sabre-sdb中,其中mx6sx-sabre-sdb.lnk为链接文件,指定了程序的入口以及内存的分段及布局等。
程序的入口:ENTRY(_start),在start.S文件中完成了以下工作:

  • 设置CPU为SVC32模式
  • Invalidate L1 I/D and TLBs
  • Disable MMU和Caches
  • 使能ICache
  • 设置堆栈
  • 跳转到main函数
    在该目录中的main.c完成IPL的主要工作:
int main(void)
{
    unsigned int image = QNX_LOAD_ADDR;
 
    init_aips();
 
    init_clocks();
 
    init_pinmux();
 
    init_sermx6(MXC_CONSOLE_BASE, 115200, 80000000, 2);
 
    ser_putstr("\nWelcome to QNX Neutrino Initial Program Loader for:\n");
    ser_putstr("  Freescale i.MX6 SoloX Sabre SDB (ARM Cortex-A9/M4)\n");
 
    while (1) {
    ser_putstr("Command:\n");
    ser_putstr("Press 'D' for UART IFS download, using the 'sendnto' utility.\n");
    ser_putstr("Press 'M' for SDMMC IFS download.\n");
    ser_putstr("Press 'J' for JTAG IFS boot of image loaded to 0x"); ser_puthex(QNX_LOAD_ADDR); ser_putstr(".\n");
    switch (ser_getchar()) {
        case 'D': case 'd':
        ser_putstr("send image now...\n");
        if (image_download_ser(QNX_LOAD_ADDR)) {
            ser_putstr(str_download_failed);
            continue;
        } else {
            ser_putstr(str_download_ok);
        }
        break;
 
        case 'M': case 'm':
        if (sdmmc_load_file(QNX_LOAD_ADDR, QNX_IFS_FILENAME) != 0) {
            ser_putstr(str_download_failed);
            continue;
        }
        ser_putstr(str_download_ok);
        break;
 
        case 'J': case 'j':
        break;
 
        default:
        break;
    }
 
    /* No safe boot media, must be scanned */
    image = image_scan_2(image, image + MAX_SCAN, 1);
    if (image != 0xffffffff) {
        ser_putstr(str_found_image);
        ser_puthex(image);
        ser_putstr("\n");
        image_setup_2(image);
 
        ser_putstr(str_jump_to_image);
        ser_puthex(startup_hdr.startup_vaddr);
        ser_putstr("\n\n");
 
        image_start_2(image);
 
        /* Never reaches here */
        return 0;
    }
    ser_putstr(str_image_scan_fail);
    } /* Forever */
 
    /* Never reaches here */
    return 0;
}

进入main分别完成了以下工作:

  • init_aips(),该函数用于设置AHB到IP Bridge的属性,跟Trust Zone相关;
  • init_clocks(),该函数用于设置系统的时钟;
  • init_pinmux(),该函数用于设置管脚的复用,主要是设置Uart和SD相关,其中Uart用于调试,而SD用于加载image;
  • init_sermx6(),该函数用于初始化串口信息;
  • image_download_ser()/sdmmc_load_file(),这两个函数用于完成Image的加载;
  • image_scan_2(),该函数用于扫描image,对Image进行一些校验检查;
  • image_start_2(),该函数跳转到Image的入口去执行,也就是跳转到startup程序中去运行;
    从以上的流程可以看出IPL整体的功能并不复杂,完成最少硬件(需要用到的,比如时钟、串口、SD)的初始化,然后对Image加载和校验,最终跳转过去执行即可。

当然,我对这个IPL可运行性是持怀疑态度的,因为很重要的DDR Controler的相关初始化并没有看到。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,076评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,658评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,732评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,493评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,591评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,598评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,601评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,348评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,797评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,114评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,278评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,953评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,585评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,202评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,180评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,139评论 2 352

推荐阅读更多精彩内容

  • QNX相关历史文章:QNX简介QNX Neutrino微内核QNX IPC机制QNX进程管理器QNX资源管理器QN...
    Loyen阅读 7,934评论 0 4
  • 一、温故而知新 1. 内存不够怎么办 内存简单分配策略的问题地址空间不隔离内存使用效率低程序运行的地址不确定 关于...
    SeanCST阅读 7,796评论 0 27
  • QNX相关历史文章:QNX简介QNX Neutrino微内核QNX IPC机制QNX进程管理器QNX资源管理器QN...
    Loyen阅读 7,992评论 2 5
  • [TOC] Android 简介 Android 操作系统是基于Linux内核, Google使用Linux内核构...
    Joe_HUST阅读 8,926评论 0 9
  • 转发https://www.jianshu.com/p/439ce15436c1 Android 简介 Andro...
    wholesky阅读 1,307评论 0 1