由于下面分析的内容与硬件平台将会有紧密的联系,但是整体的处理流程类似,所以在开始先声明一下硬件平台:
Android6410
开发板
BSP
、
WinCE6.0
。本文的内容仅是本人在学习bootloader过程中的一些记录,如果有不正确的地方,还望指正。
上传的图片被自动缩小了,想看的话直接拖到下一个标签中看吧,那样看到的是大图。
前面已经分析了
BootloaderMain
的全局变量重定位和调试串口初始化,接下来便是函数
OEMPlatformInit
,该函数主要实现目标板上设备的初始化,由
OEM
实现,包括初始化显示器、
Flash
、网卡以及
BSP
共享参数,如果在
EBoot
里面用到
USB
下载,则还需要进行
USB
的初始化。下面先给出源代码:
832
行的
InitializeDisplay
函数用来初始化显示设备,定义在同一源文件
main.c
中,在这个函数中实现了开机启动界面以及启动时的进度条的显示,如果想要修改启动界面和进度条的话,可以在该函数里面找到方法。
835
行的
OALArgsInit
函数初始化
BSP
参数结构体,定义在文件
\WINCE600\PLATFORM\\SRC\COMMOM\ARG\args.c
中。
pBSPArgs
是结构体
BSP_ARGS
的指针,指向内存
RAM
中的一块内存,用来存储一些数据信息,这些数据是在
BootLoader
和操作系统
OAL
之间的共享信息,也称为共享启动参数。
837
到
839
行使用全局变量记录
BSP
的共享参数。
841
行的
InitializeInterrupt
函数进行中断相关的初始化,包括清空中断向量表,开启
IRQ
中断等,其实现在
\WINCE600\PLATFORM\\SRC\BOOTLOADER\EBOOT\usb.c
文件中。
846
到
865
行主要对
NAND Flash
初始化。这里用到了微软提供的一个分区模块,它是在
Flash
驱动支持下的用来操作存储设备的模块。首先调用
BP_Init
函数对
NAND Flash
进行分区,即调用
FMD_Init
来初始化
Flash
设备并初始化一块内存,并记录下相关的
Flash
信息。
868
到
872
行的
TOC_Read
函数,用来从
NAND Flash
中读取
TOC
的内容,定义在文件
\WINCE600\PLATFORM\\SRC\BOOTLOADER\EBOOT\Nand.cpp
中。如果读取失败了,调用
TOC_Init
函数将
TOC
设置为默认,它的定义也在
Nand.cpp
中。
905
到
907
行,调用
OEMEthGetSecs
函数获取当前时间,这部分为后面判断超时做准备工作。
910
到
913
行对
USB
设备进行初始化,为后面通过
USB
进行镜像下载等准备。函数
InitializeUSB
在
\WINCE600\PLATFORM\\SRC\BOOTLOADER\EBOOT\usb.c
文件中。
917
到
961
行等待用户输入,从而进入
bootloader menu
界面,并回显剩余的等待时间,如果超时则继续启动工作。
967
到
987
行对用户输入的选择进行判断,如果用户按下了空格键,则进入
bootloader menu
主界面,通过函数
MainMenu
显示主界面,它定义在文件
main.c
源文件中,其他选项则继续后面的工作。
991
到
1018
行记录前面用户配置的一些参数,都保存到了全局变量中。
1020
到
1052
行表示如果用户不想要下载镜像,则从
NAND Flash
中启动。
g_ImageType
代表镜像的类别,包括
stepldr.bin
、
eboot.bin
和
nk.bin
,如果是要启动
nk.bin
,则从
Flash
中读出
OSImage
,实现函数为
ReadOSImageFromBootMedia
。
1055
到
1062
行表示如果用户想要下载镜像,而且不希望通过
USB
下载,那么初始化以太网设备,从以太网进行下载。当然本开发板是采用
USB
下载镜像的,所以
g_bUSBDownload
的值为
TRUE
。
InitEthDevice
函数定义在文件
\WINCE600\PLATFORM\\SRC\BOOTLOADER\EBOOT
中。
一、那么按着流程图的顺序,先来解析一下InitializeDisplay函数,调用InitializeDisplay主要用来初始化显示设备,也是这里对开机的启动界面进行的设置。先把源码粘出来。
static void InitializeDisplay(void)
{
tDevInfo RGBDevInfo;
volatile S3C6410_GPIO_REG *pGPIOReg = (S3C6410_GPIO_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_GPIO, FALSE);
volatile S3C6410_DISPLAY_REG *pDispReg = (S3C6410_DISPLAY_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_DISPLAY, FALSE);
volatile S3C6410_SPI_REG *pSPIReg = (S3C6410_SPI_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_SPI0, FALSE);
volatile S3C6410_MSMIF_REG *pMSMIFReg = (S3C6410_MSMIF_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_MSMIF_SFR, FALSE);
volatile S3C6410_SYSCON_REG *pSysConReg = (S3C6410_SYSCON_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_SYSCON, FALSE);
EdbgOutputDebugString("[Eboot] ++InitializeDisplay()\r\n");
// Initialize Display Power Gating
if(!(pSysConReg->BLK_PWR_STAT & (1<<4))) {
pSysConReg->NORMAL_CFG |= (1<<14);
while(!(pSysConReg->BLK_PWR_STAT & (1<<4)));
}
//denis_wei add to turn on the backlight 2009-09-28
pGPIOReg->GPFCON &= ~(0x03<<28); // Set GPF14 to OUTPUT mode.
pGPIOReg->GPFCON |= (0x1 << 28);
pGPIOReg->GPFDAT |= (1<<14);
//add end 2009-09-28
// Initialize Virtual Address
LDI_initialize_register_address((void *)pSPIReg, (void *)pDispReg, (void *)pGPIOReg);
Disp_initialize_register_address((void *)pDispReg, (void *)pMSMIFReg, (void *)pGPIOReg);
//gao0131
// Set LCD Module Type
#if (SMDK6410_LCD_MODULE == LCD_MODULE_UT_LCD35A)
LDI_set_LCD_module_type(LDI_LCD35A_RGB);
#elif (SMDK6410_LCD_MODULE == LCD_MODULE_UT_LCD43D)
LDI_set_LCD_module_type(LDI_LCD43D_RGB);
#elif (SMDK6410_LCD_MODULE == LCD_MODULE_UT_LCD7B)
LDI_set_LCD_module_type(LDI_LCD7B_RGB);
#elif (SMDK6410_LCD_MODULE == LCD_MODULE_UT_LCD102A)
LDI_set_LCD_module_type(LDI_LCD102A_RGB);
#elif (SMDK6410_LCD_MODULE == LCD_MODULE_UT_LCD102B)
LDI_set_LCD_module_type(LDI_LCD102B_RGB);
#elif (SMDK6410_LCD_MODULE == LCD_MODULE_UT_LCD104C)
LDI_set_LCD_module_type(LDI_LCD104C_RGB);
#elif (SMDK6410_LCD_MODULE == LCD_MODULE_VGA6448)
LDI_set_LCD_module_type(LDI_VGA6448_RGB);
#elif (SMDK6410_LCD_MODULE == LCD_MODULE_VGA8060)
LDI_set_LCD_module_type(LDI_VGA8060_RGB);
#else
EdbgOutputDebugString("[Eboot:ERR] InitializeDisplay() : Unknown Module Type [%d]\r\n", SMDK6410_LCD_MODULE);
#endif
// Get RGB Interface Information from LDI Library
LDI_fill_output_device_information(&RGBDevInfo);
// Setup Output Device Information
Disp_set_output_device_information(&RGBDevInfo);
// Initialize Display Controller
Disp_initialize_output_interface(DISP_VIDOUT_RGBIF);
#if (LCD_BPP == 16)
Disp_set_window_mode(DISP_WIN1_DMA, DISP_16BPP_565, LCD_WIDTH, LCD_HEIGHT, 0, 0);
#elif (LCD_BPP == 32) // XRGB format (RGB888)
Disp_set_window_mode(DISP_WIN1_DMA, DISP_24BPP_888, LCD_WIDTH, LCD_HEIGHT, 0, 0);
#else
EdbgOutputDebugString("[Eboot:ERR] InitializeDisplay() : Unknown Color Depth %d bpp\r\n", LCD_BPP);
#endif
Disp_set_framebuffer(DISP_WIN1, EBOOT_FRAMEBUFFER_PA_START);
Disp_window_onfoff(DISP_WIN1, DISP_WINDOW_ON);
// Initialize LCD Module
LDI_initialize_LCD_module();
// Video Output Enable
Disp_envid_onoff(DISP_ENVID_ON);
// Fill Framebuffer
#if(SMDK6410_LCD_MODULE == LCD_MODULE_UT_LCD35A)
memcpy((void *)EBOOT_FRAMEBUFFER_UA_START, (void *)InitialImage_rgb16_320x240, 320*240*2);
#elif (LCD_BPP == 16)
{
int i;
unsigned short *pFB;
pFB = (unsigned short *)EBOOT_FRAMEBUFFER_UA_START;
for (i=0; i *pFB++ = 0x0000;//0x001F; // Blue
DisprogressBar();
}
#elif (LCD_BPP == 32)
{
int i;
unsigned int *pFB;
pFB = (unsigned int *)EBOOT_FRAMEBUFFER_UA_START;
for (i=0; i *pFB++ = 0x000000FF; // Blue
}
#endif
// TODO:
// Backlight Power On
//Set PWM GPIO to control Back-light Regulator Shotdown Pin (GPF[15])
// fusq 20090618 : disable buzzer when boot
// pGPIOReg->GPFDAT |= (1<<15);
// pGPIOReg->GPFCON = (pGPIOReg->GPFCON & ~(3<<30)) | (1<<30); // set GPF[15] as Output
// Display control by GPE0
pGPIOReg->GPEPUD &= ~(0x3); // Pull-Up/Down Disable
pGPIOReg->GPECON &= ~(0xf); // GPE0 -> Output
pGPIOReg->GPECON |= 0x1;
pGPIOReg->GPEDAT &= ~(0x1);
pGPIOReg->GPEDAT |= 0x1;
EdbgOutputDebugString("[Eboot] --InitializeDisplay()\r\n");
}
{
tDevInfo RGBDevInfo;
volatile S3C6410_GPIO_REG *pGPIOReg = (S3C6410_GPIO_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_GPIO, FALSE);
volatile S3C6410_DISPLAY_REG *pDispReg = (S3C6410_DISPLAY_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_DISPLAY, FALSE);
volatile S3C6410_SPI_REG *pSPIReg = (S3C6410_SPI_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_SPI0, FALSE);
volatile S3C6410_MSMIF_REG *pMSMIFReg = (S3C6410_MSMIF_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_MSMIF_SFR, FALSE);
volatile S3C6410_SYSCON_REG *pSysConReg = (S3C6410_SYSCON_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_SYSCON, FALSE);
EdbgOutputDebugString("[Eboot] ++InitializeDisplay()\r\n");
// Initialize Display Power Gating
if(!(pSysConReg->BLK_PWR_STAT & (1<<4))) {
pSysConReg->NORMAL_CFG |= (1<<14);
while(!(pSysConReg->BLK_PWR_STAT & (1<<4)));
}
//denis_wei add to turn on the backlight 2009-09-28
pGPIOReg->GPFCON &= ~(0x03<<28); // Set GPF14 to OUTPUT mode.
pGPIOReg->GPFCON |= (0x1 << 28);
pGPIOReg->GPFDAT |= (1<<14);
//add end 2009-09-28
// Initialize Virtual Address
LDI_initialize_register_address((void *)pSPIReg, (void *)pDispReg, (void *)pGPIOReg);
Disp_initialize_register_address((void *)pDispReg, (void *)pMSMIFReg, (void *)pGPIOReg);
//gao0131
// Set LCD Module Type
#if (SMDK6410_LCD_MODULE == LCD_MODULE_UT_LCD35A)
LDI_set_LCD_module_type(LDI_LCD35A_RGB);
#elif (SMDK6410_LCD_MODULE == LCD_MODULE_UT_LCD43D)
LDI_set_LCD_module_type(LDI_LCD43D_RGB);
#elif (SMDK6410_LCD_MODULE == LCD_MODULE_UT_LCD7B)
LDI_set_LCD_module_type(LDI_LCD7B_RGB);
#elif (SMDK6410_LCD_MODULE == LCD_MODULE_UT_LCD102A)
LDI_set_LCD_module_type(LDI_LCD102A_RGB);
#elif (SMDK6410_LCD_MODULE == LCD_MODULE_UT_LCD102B)
LDI_set_LCD_module_type(LDI_LCD102B_RGB);
#elif (SMDK6410_LCD_MODULE == LCD_MODULE_UT_LCD104C)
LDI_set_LCD_module_type(LDI_LCD104C_RGB);
#elif (SMDK6410_LCD_MODULE == LCD_MODULE_VGA6448)
LDI_set_LCD_module_type(LDI_VGA6448_RGB);
#elif (SMDK6410_LCD_MODULE == LCD_MODULE_VGA8060)
LDI_set_LCD_module_type(LDI_VGA8060_RGB);
#else
EdbgOutputDebugString("[Eboot:ERR] InitializeDisplay() : Unknown Module Type [%d]\r\n", SMDK6410_LCD_MODULE);
#endif
// Get RGB Interface Information from LDI Library
LDI_fill_output_device_information(&RGBDevInfo);
// Setup Output Device Information
Disp_set_output_device_information(&RGBDevInfo);
// Initialize Display Controller
Disp_initialize_output_interface(DISP_VIDOUT_RGBIF);
#if (LCD_BPP == 16)
Disp_set_window_mode(DISP_WIN1_DMA, DISP_16BPP_565, LCD_WIDTH, LCD_HEIGHT, 0, 0);
#elif (LCD_BPP == 32) // XRGB format (RGB888)
Disp_set_window_mode(DISP_WIN1_DMA, DISP_24BPP_888, LCD_WIDTH, LCD_HEIGHT, 0, 0);
#else
EdbgOutputDebugString("[Eboot:ERR] InitializeDisplay() : Unknown Color Depth %d bpp\r\n", LCD_BPP);
#endif
Disp_set_framebuffer(DISP_WIN1, EBOOT_FRAMEBUFFER_PA_START);
Disp_window_onfoff(DISP_WIN1, DISP_WINDOW_ON);
// Initialize LCD Module
LDI_initialize_LCD_module();
// Video Output Enable
Disp_envid_onoff(DISP_ENVID_ON);
// Fill Framebuffer
#if(SMDK6410_LCD_MODULE == LCD_MODULE_UT_LCD35A)
memcpy((void *)EBOOT_FRAMEBUFFER_UA_START, (void *)InitialImage_rgb16_320x240, 320*240*2);
#elif (LCD_BPP == 16)
{
int i;
unsigned short *pFB;
pFB = (unsigned short *)EBOOT_FRAMEBUFFER_UA_START;
for (i=0; i
DisprogressBar();
}
#elif (LCD_BPP == 32)
{
int i;
unsigned int *pFB;
pFB = (unsigned int *)EBOOT_FRAMEBUFFER_UA_START;
for (i=0; i
}
#endif
// TODO:
// Backlight Power On
//Set PWM GPIO to control Back-light Regulator Shotdown Pin (GPF[15])
// fusq 20090618 : disable buzzer when boot
// pGPIOReg->GPFDAT |= (1<<15);
// pGPIOReg->GPFCON = (pGPIOReg->GPFCON & ~(3<<30)) | (1<<30); // set GPF[15] as Output
// Display control by GPE0
pGPIOReg->GPEPUD &= ~(0x3); // Pull-Up/Down Disable
pGPIOReg->GPECON &= ~(0xf); // GPE0 -> Output
pGPIOReg->GPECON |= 0x1;
pGPIOReg->GPEDAT &= ~(0x1);
pGPIOReg->GPEDAT |= 0x1;
EdbgOutputDebugString("[Eboot] --InitializeDisplay()\r\n");
}
开始先声明了一个
tDevInfo
的结构体变量,
tDevInfo
的定义在文件
S 3c 6410_display_con.h
中,主要定义了一些属性变量,如下:
typedef struct _tDevInfo
{
DISP_VIDOUT_MODE VideoOutMode;
DISP_RGBIFOUT_MODE RGBOutMode;
unsigned int uiWidth;
unsigned int uiHeight;
unsigned int VBPD_Value;
unsigned int VFPD_Value;
unsigned int VSPW_Value;
unsigned int HBPD_Value;
unsigned int HFPD_Value;
unsigned int HSPW_Value;
unsigned int VCLK_Polarity;
unsigned int HSYNC_Polarity;
unsigned int VSYNC_Polarity;
unsigned int VDEN_Polarity;
unsigned int PNR_Mode;
unsigned int VCLK_Source;
unsigned int Frame_Rate;
unsigned int VCLK_Direction;
//unsigned int VCLK_Value;
} tDevInfo;
{
DISP_VIDOUT_MODE VideoOutMode;
DISP_RGBIFOUT_MODE RGBOutMode;
unsigned int uiWidth;
unsigned int uiHeight;
unsigned int VBPD_Value;
unsigned int VFPD_Value;
unsigned int VSPW_Value;
unsigned int HBPD_Value;
unsigned int HFPD_Value;
unsigned int HSPW_Value;
unsigned int VCLK_Polarity;
unsigned int HSYNC_Polarity;
unsigned int VSYNC_Polarity;
unsigned int VDEN_Polarity;
unsigned int PNR_Mode;
unsigned int VCLK_Source;
unsigned int Frame_Rate;
unsigned int VCLK_Direction;
//unsigned int VCLK_Value;
} tDevInfo;
1718
到
1723
行定义一些关于寄存器的变量,以便对相关寄存器进行设置。
1728
到
1731
行主要是对电源模块的设置,
BLK_PWR_STAT
是块电源的状态寄存器,第
4
位为
1
表示块
F
电源准备就绪,而
NORMAL_CFG
用来激活块
F
电源。
1733
到
1735
行设置
GPF14
为输出模式,而且输出高电平,这样是为了打开背景光,这个设置于硬件连接有关,要看背景光开启脚连接到了
CPU
的哪个
IO
口上。
1740
和
1741
两行的功能类型,
LDI_initialize_register_address
函数定义在文件
S 3c 6410_ldi.c
中,
Disp_initialize_register_address
函数定义在文件
S 3c 6410_display_con.c
中。这两个函数主要是用全局变量记录下这几个寄存器的相关设置。
1744
到
1762
行是用来判断
LCD
模块的类型的,也就是
3.5
寸还是
4.3
寸等。
1765
行的
LDI_fill_output_device_information
函数在,根据前面选择的
LCD
模块类型,填充结构体
RGBDevInfo
的内容。
1767
行的
Disp_set_output_device_information
函数在文件
S 3c 6410_display_con.h
中,将结构体
RGBDevInfo
的内容设置记录到全局变量
g_DevInfoRGB
中。
1771
行的
Disp_initialize_output_interface
函数在文件
S 3c 6410_display_con.h
中,按视频或图像输出模式为
DISP_VIDOUT_RGBIF
对
IO
端口和视频控制寄存器以及视频时序控制寄存器进行设置。
1773
到
1779
行的
Disp_set_window_mode
函数在文件
S 3c 6410_display_con.h
中,对相应窗口格式进行初始化。
1781
行的
Disp_set_framebuffer
函数在文件
S 3c 6410_display_con.h
中,主要对源图像缓冲区地址进行设置。
1782
行的
Disp_window_onfoff
函数在文件
S 3c 6410_display_con.h
中,用于使能相应窗口的视频输出和
VIDEO
控制信号。
1785
行的
LDI_initialize_LCD_module
函数在文件
S 3c 6410_ldi.c
中,用来初始化
LCD
。
1788
行的
Disp_envid_onoff
函数在文件
S 3c 6410_display_con.h
中,使能视频输出。
1791
到
1851
行用来填充源图像缓冲区的内容。其中
DisprogressBar
函数在文件
main.c
中,用来显示处理的进度条。
1863
到
1868
行通过对端口
GPE0
的输出来控制显示器。
二、
OALArgsInit
函数
该函数用来设置一个数据结构,该数据结构承载了
BootLoader
和操作系统之间的共享信息,比如
IP
地址、子网掩码以及用户在
Bootloader
的选项菜单中作出的选择,这些从
BootLoader
共享给操作系统使用的数据也称为启动参数。其实这些启动参数用
BootLoader
共享给操作系统的
OAL
模块的,所以共享哪些参数都是由
OEM
用户自己开发的,内容也不是通用的。
下面是该函数的实现内容:
VOID OALArgsInit(BSP_ARGS* pArgs)
{
int i;
OALMSG(OAL_FUNC, (TEXT("+OALArgsInit()\r\n")));
// Check the BSP Args area
//
if ((pArgs->header.signature == OAL_ARGS_SIGNATURE)
|| (pArgs->header.oalVersion == OAL_ARGS_VERSION)
|| (pArgs->header.bspVersion == BSP_ARGS_VERSION))
{
OALMSG(OAL_INFO, (TEXT("Arguments area has some values. Do not Initialize\r\n")));
OALMSG(OAL_VERBOSE, (TEXT("pArgs :0x%x\r\n"), pArgs));
for(i=0;i {
OALMSG(OAL_VERBOSE, (TEXT("0x%02x "),*((UINT8*)pArgs+i)));
}
}
else
{
volatile S3C6410_SYSCON_REG *pSysConReg;
DWORD count, code, j;
UCHAR d;
pSysConReg = (S3C6410_SYSCON_REG *)OALPAtoUA(S3C6410_BASE_REG_PA_SYSCON);
memset(pArgs, 0x0, sizeof(BSP_ARGS));
// Setup header
pArgs->header.signature = OAL_ARGS_SIGNATURE;
pArgs->header.oalVersion = OAL_ARGS_VERSION;
pArgs->header.bspVersion = BSP_ARGS_VERSION;
//Set-up device ID for SMDK6410
count = sizeof(BSP_DEVICE_PREFIX) - 1; // BSP_DEVICE_PREFIX = "SMDK6410" defined in bsp_cfg.h
if (count > sizeof(pArgs->deviceId)/2) count = sizeof(pArgs->deviceId)/2;
memcpy(pArgs->deviceId, BSP_DEVICE_PREFIX, count);
code = pSysConReg->SYS_ID;
OALMSG(TRUE, (TEXT("SocID:0x%x\n"),code, sizeof(pArgs->deviceId)));
// Convert it to hex number
// 36410101 -> extract 6410101, means 6410 EVT1
for (j = 28; j >= 0 && count < sizeof(pArgs->deviceId); j -= 4)
{
d = (UCHAR)((code >> j) & 0xF);
pArgs->deviceId[count++] = ((d < 10) ? ('0' + d) : ('A' + d - 10));
}
// End string will be "SMDK6410641010x"
while (count < sizeof(pArgs->deviceId)) pArgs->deviceId[count++] = '\0';
count = 0;
// Set-up dummy uuid for SMDK6410.
// Actually, S3C6410 does not provide UUID for each chip
// So on S3C6410 EVT1, uuid will be 3641010136410101
for(j=60; j> 0 && count < sizeof(pArgs->uuid); j -=4)
{
d = (UCHAR)(((code >> (j%32))) & 0xF);
pArgs->uuid[count++] = d < 10 ? '0' + d : 'A' + d - 10;
}
// Can Add code for cleanboot, hiveclean, formatpartion
OALMSG(TRUE, (TEXT("Arguments area is initialized\r\n")));
}
OALMSG(TRUE, (TEXT("-OALArgsInit()\r\n")));
return;
}
{
int i;
OALMSG(OAL_FUNC, (TEXT("+OALArgsInit()\r\n")));
// Check the BSP Args area
//
if ((pArgs->header.signature == OAL_ARGS_SIGNATURE)
|| (pArgs->header.oalVersion == OAL_ARGS_VERSION)
|| (pArgs->header.bspVersion == BSP_ARGS_VERSION))
{
OALMSG(OAL_INFO, (TEXT("Arguments area has some values. Do not Initialize\r\n")));
OALMSG(OAL_VERBOSE, (TEXT("pArgs :0x%x\r\n"), pArgs));
for(i=0;i
OALMSG(OAL_VERBOSE, (TEXT("0x%02x "),*((UINT8*)pArgs+i)));
}
}
else
{
volatile S3C6410_SYSCON_REG *pSysConReg;
DWORD count, code, j;
UCHAR d;
pSysConReg = (S3C6410_SYSCON_REG *)OALPAtoUA(S3C6410_BASE_REG_PA_SYSCON);
memset(pArgs, 0x0, sizeof(BSP_ARGS));
// Setup header
pArgs->header.signature = OAL_ARGS_SIGNATURE;
pArgs->header.oalVersion = OAL_ARGS_VERSION;
pArgs->header.bspVersion = BSP_ARGS_VERSION;
//Set-up device ID for SMDK6410
count = sizeof(BSP_DEVICE_PREFIX) - 1; // BSP_DEVICE_PREFIX = "SMDK6410" defined in bsp_cfg.h
if (count > sizeof(pArgs->deviceId)/2) count = sizeof(pArgs->deviceId)/2;
memcpy(pArgs->deviceId, BSP_DEVICE_PREFIX, count);
code = pSysConReg->SYS_ID;
OALMSG(TRUE, (TEXT("SocID:0x%x\n"),code, sizeof(pArgs->deviceId)));
// Convert it to hex number
// 36410101 -> extract 6410101, means 6410 EVT1
for (j = 28; j >= 0 && count < sizeof(pArgs->deviceId); j -= 4)
{
d = (UCHAR)((code >> j) & 0xF);
pArgs->deviceId[count++] = ((d < 10) ? ('0' + d) : ('A' + d - 10));
}
// End string will be "SMDK6410641010x"
while (count < sizeof(pArgs->deviceId)) pArgs->deviceId[count++] = '\0';
count = 0;
// Set-up dummy uuid for SMDK6410.
// Actually, S3C6410 does not provide UUID for each chip
// So on S3C6410 EVT1, uuid will be 3641010136410101
for(j=60; j> 0 && count < sizeof(pArgs->uuid); j -=4)
{
d = (UCHAR)(((code >> (j%32))) & 0xF);
pArgs->uuid[count++] = d < 10 ? '0' + d : 'A' + d - 10;
}
// Can Add code for cleanboot, hiveclean, formatpartion
OALMSG(TRUE, (TEXT("Arguments area is initialized\r\n")));
}
OALMSG(TRUE, (TEXT("-OALArgsInit()\r\n")));
return;
}
首先看输入参数
pBSPArgs
是一个宏,定义在文件
\WINCE600\PLATFORM\\SRC\BOOTLOADER\EBOOT\loader.h
中,如下
#define pBSPArgs ((BSP_ARGS *)IMAGE_SHARE_ARGS_UA_START)
该宏代表的是一个内存地址,实际上一块
RAM
内存空间的指针,所指向的内存就是用来专门存储共享启动参数的。
在文件
\WINCE600\PLATFORM\\SRC\INC\Bsp_args.h
中给出了结构体
BSP_ARGS
的定义,如下:
typedef struct
{
OAL_ARGS_HEADER header;
UINT8 deviceId[16]; // Device identification
OAL_KITL_ARGS kitl;
UINT8 uuid[16];
BOOL bUpdateMode; // TRUE = Enter update mode on reboot.
BOOL bHiveCleanFlag; // TRUE = Clean hive at boot
BOOL bCleanBootFlag; // TRUE = Clear RAM, user objectstore at boot
BOOL bFormatPartFlag; // TRUE = Format partion when mounted at boot
DWORD nfsblk; // for NAND Lock Tight
HANDLE g_SDCardDetectEvent; //For USB MSF , check SD Card insert & remove.
DWORD g_SDCardState; //For USB MSF , check SD Card insert & remove.
} BSP_ARGS;
{
OAL_ARGS_HEADER header;
UINT8 deviceId[16]; // Device identification
OAL_KITL_ARGS kitl;
UINT8 uuid[16];
BOOL bUpdateMode; // TRUE = Enter update mode on reboot.
BOOL bHiveCleanFlag; // TRUE = Clean hive at boot
BOOL bCleanBootFlag; // TRUE = Clear RAM, user objectstore at boot
BOOL bFormatPartFlag; // TRUE = Format partion when mounted at boot
DWORD nfsblk; // for NAND Lock Tight
HANDLE g_SDCardDetectEvent; //For USB MSF , check SD Card insert & remove.
DWORD g_SDCardState; //For USB MSF , check SD Card insert & remove.
} BSP_ARGS;
header
成员是启动参数的头信息,定义在文件
\WINCE600\PLATFORM\COMMON\SRC\INC\oal_args.h
中,由于指示
pBSPArgs
内存区域是否包含有效的共享数据、版本及如何使用其中的信息。
OALArgsInit
函数开始先判断共享的启动参数是否有效,即如果版本号发生变化意味着启动参数的结构体定义发生了变化,需要重新填充启动参数的内容。
deviceId
成员和
kitl
成员用于
BootLoader
向
OAL
传递用户对
KITL
的选项设置参数。
deviceID
是
16
字节的设备名字字符串,标识用于做
KITL
传输功能的端口外设。
kitl
成员用于存放
KITL
端口外设在目标系统的硬件位置和软件配置信息。
OALArgsInit
函数的
54
到
71
行用于设置
deviceID
成员的值。
uuid
成员是
16
字节的
CPU
芯片的虚拟
ID
字符串。
OALArgsInit
函数的
73
到
84
行就是用来填充
uuid
字符串的。
该函数是eboot里面最为复杂的函数,里面有一些关于nand的操作还有些没弄清楚,等以后弄明白了再写!