您的位置:首页 > 编程语言

自己动手写J-LINK脚本,烧写NAND启动代码

2012-06-09 18:01 435 查看
一、背景

对于J-LINK,一般只能使用J-Flash软件来烧写Norflash,而对于烧写Nandflash不支持,而Hjtag只能够烧写大部分固定平台的Nandflash,问了度娘,也没得到满意的答案,于是索性自己写一个J-LINK脚本来完成烧写工作。

二、平台介绍

CPU:AT91SAM9G10

内部SRAM:16KB

NANDFLASH:128M

三、上电启动过程分析

分为2步,Bootloader0,Bootloader1。

Bootloader0:这一部分主要执行CPU内部ROM中的代码。

1. Stack setup for ARM supervisor mode

2. Main Oscillator Frequency Detection

3. C variable initialization

4. PLL setup: PLLB is initialized to generate a 48 MHz clock necessary to use the USB

Device. A register located in the Power Management Controller (PMC) determines the

frequency of the main oscillator and thus the correct factor for the PLLB.

5. Initialization of the DBGU serial port (115200 bauds, 8, N, 1)

6. Enable the user reset

7. Jump to SerialFlash Boot sequence through NPCS0. If SerialFlash Boot succeeds, perform

a remap and jump to 0x0.

8. Jump to DataFlash Boot sequence through NPCS0. If DataFlash Boot succeeds, perform

a remap and jump to 0x0.

9. Jump to NAND Flash Boot sequence. If NAND Flash Boot succeeds, perform a remap

and jump to 0x0.

10. Jump to SD Card Boot sequence. If SD Card Boot succeeds, perform a remap and

jump to 0x0.

11. Jump to EEPROM Boot sequence. If EEPROM Boot succeeds, perform a remap and

jump to 0x0.

12. Activation of the Instruction Cache

13. Jump to SAM-BA Boot sequence

14. Disable the WatchDog

15. Initialization of the USB Device Port

从上面可以看出,内部ROM做的工作主要为:

1、使能主时钟源。

2、从外设中,一次寻找“有效序列”,找到有效序列,则加载到内部SRAM,然后REMAP,跳转到内部SRAM执行。

有效序列:

以B或LDR的相对寻址异常向量表,其中地址0x14存放的是需要搬运到SRAM的代码长度。

Bootloader1:Nandflash中启动代码,这部分代码主要完成主时钟配置,SDRAM初始化,代码搬运,堆栈初始化等工作。

四、烧写脚本

思路1:在JLinkARM.dll基础上做2次开发。正所谓内事问百度,外事问谷歌,2个都问了,都没有找到接口文档说明,所以此路暂时不通。

思路2:编写一个脚本文件,利用J-LINK的命令窗口J-Link Commander来执行。

方案A:用Window程序来将脚本进行封装,创建2个PIPE,然后CreateProcess一个子进程,将InputR绑定到子进程的标准输入端,OutputW绑定到子进程的标准输出端,这样可以对输出结果进行条件判断。

编写3个BIN文件:

第一个BIN1:加载到SRAM,用来初始化主时钟,和SDRAM。

第二个BIN2:加载到内存地址0x21000000,用于下载第三个BIN到Nandflash。

第三个BIN3:加载到内存0x22000000,Nandflash启动代码。

首先,loadbin BIN1,0x0; setpc 0x0; g;

然后,h; loadbin BIN2,0x21000000; loadbin BIN3,0x22000000; setpc 0x21000000; g;

最后还是存在一个问题,通过WriteFile函数向句柄InputW写数据时,从OutputR端未读到数据。

方案B:纯脚本,使用Windows的system函数来执行脚本文件了。

#include <stdio.h>

#include <process.h>

#define BOOT_LOAD "d:\\boot_download\\boot_down.bin"

#define BOOT_NAND "d:\\boot_nandflash\\boot_nand.bin"

#define JLINK_BAT "d:\\jlink_bat"

#define JLINK_DIR "\"C:\\Program Files\\SEGGER\\JLinkARM_V436c\\JLink.exe\""

FILE *stream;

void main(void)

{

stream = fopen(JLINK_BAT,"w");

fprintf(stream, "speed 8000 \n");

fprintf(stream, "le \n");

//禁止内部看门狗

fprintf(stream, "w4 0xFFFFFD44,0x00008000 \n");

//配置时钟

fprintf(stream, "w4 0xFFFFFC14,0xFFFFFFFF \n");

fprintf(stream, "w4 0xFFFFFC04,0xFFFFFFFE \n");

fprintf(stream, "w4 0xFFFFFC20,0x00004001 \n");

fprintf(stream, "w4 0xFFFFFC28,0x2064BF07 \n");

fprintf(stream, "w4 0xFFFFFC30,0x00000102 \n");

fprintf(stream, "Sleep 500 \n");

//配置SDRAM

fprintf(stream, "w4 0xFFFFEE30,0x0001003A \n");

fprintf(stream, "w4 0xFFFFF870,0xFFFF0000 \n");

fprintf(stream, "w4 0xFFFFF874,0x00000000 \n");

fprintf(stream, "w4 0xFFFFF804,0xFFFF0000 \n");

fprintf(stream, "w4 0xFFFFEA08,0xA6339279 \n");

fprintf(stream, "w4 0xFFFFEA24,0x00000000 \n");

fprintf(stream, "w4 0xFFFFEA00,0x00000001 \n");

fprintf(stream, "w4 0x20000000,0x00000000 \n");

fprintf(stream, "w4 0xFFFFEA00,0x00000002 \n");

fprintf(stream, "w4 0x20000000,0x00000000 \n");

fprintf(stream, "w4 0xFFFFEA00,0x00000004 \n");

fprintf(stream, "w4 0x20000000,0x00000000 \n");

fprintf(stream, "w4 0x20000004,0x00000000 \n");

fprintf(stream, "w4 0x20000008,0x00000000 \n");

fprintf(stream, "w4 0x2000000C,0x00000000 \n");

fprintf(stream, "w4 0x20000010,0x00000000 \n");

fprintf(stream, "w4 0x20000014,0x00000000 \n");

fprintf(stream, "w4 0x20000018,0x00000000 \n");

fprintf(stream, "w4 0x2000001C,0x00000000 \n");

fprintf(stream, "w4 0xFFFFEA00,0x00000003 \n");

fprintf(stream, "w4 0x20000000,0x00000000 \n");

fprintf(stream, "w4 0xFFFFEA00,0x00000000 \n");

fprintf(stream, "w4 0x20000000,0x00000000 \n");

fprintf(stream, "w4 0xFFFFEA04,0x000003A3 \n");

fprintf(stream, "loadbin ");

fprintf(stream, BOOT_LOAD);

fprintf(stream, ",0x21000000 \n");

fprintf(stream, "loadbin ");

fprintf(stream, BOOT_NAND);

fprintf(stream, ",0x22000000 \n");

fprintf(stream, "h \n");

fprintf(stream, "setpc 0x21000000 \n");

fprintf(stream, "g \n");

fclose(stream);

system("\"C:\\Program Files\\SEGGER\\JLinkARM_V436c\\JLink.exe\" d:\\jlink_bat");

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: