当前位置: 首页 > 工具软件 > OBM > 使用案例 >

linux OBM分析

章岳
2023-12-01
marvell的bootloader是blob+OBM+bootROM,所以还得编译OBM。
下面就对OBM进行分析。
查看OBM/Build/obm_linux.mak 文件,找到需要编译的文件。
OBJS =           obm_startup.o           \
                $(DDROBJS)              \
                $(DOWNLOADOBJS)         \
                $(DFCOBJS)              \
                $(MAINOBJS)             \
                $(FLASHOBJS)            \
                $(MISCOBJS)             \
                $(PLATFORMOBJS)         \
                $(SECUREOBJS)           \
                $(DMAOBJS)              \
                $(ONENANDOBJS)          \
                $(MDOCOBJS)                      \
                $(TAVOROBJS)
可以看到首先需要的是 obm_startup.o
obm_startup.o: $(TOPDIR)/StartUp/obm_startup.S
        $(AS) $(INCLUDE_DIRS) "$(TOPDIR)/StartUp/obm_startup.S" -o "$(OUTDIR)/obm_startup.o"
而它需要StartUp/obm_startup.S,所以我们查看obm_startup.S这个文件。从__main入口
__main:
    @NOT SUPPORTED: ENTRY""
        B  ResetHandler                    //初始化中断,关闭MMU,刷新列表,堆栈
        B UndefinedHandler
        B SwiHandler
        B PrefetchHandler
        B AbortHandler
        NOP                             @ Reserved Vector
        B SaveProgramState               @ B IRQ Interrupt SaveProgramState
        B FiqHandler @ FIQ interrupts not anabled
        NOP
        .align 2
        .word   MajorMinor, Date, Processor
        NOP
        @ RESET entry point
ResetHandler之后,使能所有协处理器的寄存器,从 0x5c0127F0 保存版本。
初始化DDR,使能MMU,初始化PVCR(VCO寄存器,用于PLL),然后跳到DDRInit。
查看OBM/MHLV/DDR/ddr_init.S,
ldr     r2,     =PLATFORMCLOCKVALUE             //设置时钟,DDR读取速度
初始化DDR memory,
初始化SDRAM
    bl       xlli_Dmem_initP1                        @ init DDR-SDRAM (Part 1)
    ldr     r0,     =xlli_DMEMREGS_PHYSICAL_BASE    @ Dynamic Mem Controller base
    orr     r0, r0, #0x1
    bl      xlli_Rcomp                              @ Perform inital Rcomp calculation
    ldr     r0,     =xlli_DMEMREGS_PHYSICAL_BASE    @ Dynamic Mem Controller base
    ldr     r1,     =0x80000000                                @ DDR SDRAM base address
    bl       xlli_Dmem_initP2                        @ init DDR-SDRAM (Part 2)

@   Set up HCAL register with a preliminary value
@
    ldr     r1,     =xlli_DMEMREGS_PHYSICAL_BASE    @ Dynamic Memory Control Reg Base
    ldr     r2,     =0x90001102                     @ Preliminary value
    str     r2,     [r1, #xlli_DDR_HCAL_offset]     @ Write it out

    .ifdef xlli_stack_pointer     @ If stack pointer has been defined,
    ldmfd   sp!,    {r0-r11, pc}            @ Return to caller via the stack
    .else
    mov     pc,     lr                      @ Non stack return
    .endif
以上跳转的,都可以查看mini_xlli_lowlev_init.S文件找到。
地址参数查看xlli_board_defs.inc文件。
回到obm_startup.S文件,继续往下看,是判定是否休眠唤醒,主要看PSR(程序状态寄存器)。假如符合情况,就拷贝DKB到0x80000000。
后面可以在 Branch to OEM Boot Main program看到下面这段代码
LDR     r1, =ISRAMDateSpaceBase                 @ Restore platform configuration passed in by the BootROM
        LDR             r0, [r1]
        B                OBMBootMain
LOOPFOREVER:  B         LOOPFOREVER        

在OBM/MainProgram/obm.c查看
先看 void OBMBootMain(UINT_T PlatformSettings)

// Initialize any fuse information passed in by the BootROM
        Fuses.value = PlatformSettings;

        #if VERBOSE_DEBUG
        Fuses.bits.Download_Disable = 0;  //  allows ports to be enabled 
        #endif
        #if OBMTEST
         //Fuses.bits.PlatformState = 0x5;      // Default to CS2 Sibley
        Fuses.bits.PlatformState = 0x4;   // Default to NAND x16
        Fuses.bits.BootPlatformState = 0x9;
        #endif
结构体如下:
typedef union{
unsigned int value;
struct PLATFORM_FUSES bits;
}FUSE_SET, *pFUSE_SET;

struct PLATFORM_FUSES{
unsigned int DebugEn :1;      // Bit 0 of FMRD8
unsigned int PlatformState :4;    // Bit 1-4 of FMRD8
unsigned int Caddo_Disable :1;   // Bit 5 of FMRD8
unsigned int JTAG_Disable :1;  // Bit 6 of FMRD8
unsigned int Patching_Disable :1; // Bit 7 of FMRD8
unsigned int Patching_Revision :4; // Bit 8-11 of FMRD8
    unsigned int UARTPort           :1;     // 0 - FFUART, 1 - AltUART
    unsigned int USBPort            :1;     // 0 - DIFFUSB 1 - SEUSB
unsigned int CaddoDead :1; // 1 = Caddo did not come up.
unsigned int Resume :1; // 1 = resume from sleep in process
unsigned int USBWakeup :1; // 1 = USB wakeup from WSOTG
unsigned int PortEnabled :1; // 1 = Ports have been enabled
unsigned int DDRInitialized :1;   // If the BootROM already initializes the DDR
unsigned int Download_Disable :1; // Bit 19 of services FMRD2 - Used to be MH-TV if 1 disable ports
unsigned int SBE :1; // Bit 20 of services FMRD2
unsigned int SDE :1; // Bit 21 of services FMRD2
unsigned int BootPlatformState :4; // There are the bits the BootROM booted from
unsigned int res :6;
};
读取版本信息
Version = (UINT_T *) 0x5c0127F0;
if ( (*Version >> 16) ==  VERSION_2_XX)
        {
           LoadVersion2XXImage(Fuses, &pFlashProp[0]);

        }
使能中断,初始化端口
EnableIrqInterrupts();

对BootROM检测flashes
if ((Fuses.bits.PlatformState == 0)     && (Fuses.bits.BootPlatformState == 0))

按照TIM(Trusted Image Module)/ NTIM设置端口,或默认值
RetStatus.ErrorCode = InitTIMPort(&Fuses, &TIM_h);
if (RetStatus.ErrorCode == DownloadPortError)
                InitDefaultPort(&Fuses);

// TIM structure for use by DKB/OBM/BootROM
typedef struct
{
 pCTIM  pConsTIM; // Constant part
 pIMAGE_INFO pImg; // Pointer to Images
 pKEY_MOD pKey; // Pointer to Keys
 PUINT pReserved; // Pointer to Reserved Area
 pPLAT_DS       pTBTIM_DS; // Pointer to Digital Signature
} TIM, *pTIM;

imageInfo =  FindImageInTIM(&TIM_h, OSLOADERID);
if(imageInfo == NULL)
        {
                imageInfo = FindImageInTIM(&TIM_h, OBMIDENTIFIER);
                ImageID =  imageInfo->NextImageID;
                //update the imageInfo structure for the image being booted to
                imageInfo = FindImageInTIM(&TIM_h, ImageID);
                if(imageInfo == NULL)
                {
                        //if we cannot find an image to boot to, error out
                        OBMFinalize(ImageNotFound, &pFlashProp[0]);
                }
        }
        else
        {
           ImageID = OSLOADERID;
        }

读取DDR EMRS(拓展寄存器,用于初始化DLL)的值
iemrs = *gDDREMRSValue;
        for(i =0;i<32;i++){
                itemp = iemrs;
                itemp = itemp & 0x80000000;
                if(itemp)
                        stemp[i] = 0x31;
                else
                        stemp[i] = 0x30;
                iemrs = (iemrs<<1);
        }

装载映像
Retval =  CopyImageFlashToLocal(ImageID, &TIM_h, pFlashProp, NULL);

确认NTIM 或者TIM
Retval = ValidateCheckSum(TIMIDENTIFIER, &TIM_h, &pFlashProp[0]);
最后的处理:
Retval = PlatformOBMPostbootCode(&TIM_h, &pFlashProp[0]);
        if (Retval != NoError)
                OBMFinalize(Retval, &pFlashProp[0]);

        HandleDisconnect();
        ShutdownPort(FFUART_D);
        ShutdownPort(ALTUART_D);
        ShutdownPort(DIFF_USB_D);
        ShutdownPort(U2D_USB_D);
        DisableIrqInterrupts();            

    SaveParamsForEboot(Fuses);        //保存参数


    // TRANSFER CONTROL TO OS
        TransferControl(imageInfo->LoadAddr, 0, imageInfo->LoadAddr);
        _mod0();        //void _mod0(void) {while (1);}

1st step - Move Transfer Control to a Non-MMU translated area of the DDR
2nd Step - Turn OFF MMU, Flush TLB's
3nd Step - Copy the boot image to it's load address

回到obm_linux.mak文件中查看还需要编译DDR,Flash,Uart,USB,Boot保护等。
到此分析结束。


编译配置命令:
./configure --prefix=/home/wang/project/blob/bootloader/bin --with-board=littleton --host=arm-linux --with-linux-prefix=/home/wang/william/linux-2.6.25  --enable-xlli --enable-xllp --with-cpu-product-id=MonahansLV --with-commands=all --with-network=eth --with-nand-layout=comm_v75 --enable-xmodem  --enable-nand --enable-lcd
make -f obm_linux.mak



 类似资料: