linux OBM分析

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-11of 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



<think>好的,我现在需要解决用户关于如何撤销失败的git apply或patch操作的问题,特别是处理Hunk FAILED的情况。用户之前执行了`patch -p1 < 0001-obm-ddr.patch`后出现失败,想知道如何撤销这些部分应用的修改,并正确处理这种情况。 首先,用户的问题涉及到两个不同的工具:git apply和传统的patch命令。根据之前的对话,用户可能混淆了这两个工具的使用和撤销方法。需要明确区分这两种情况。 根据用户提供的引用内容,引用[1]提到使用git am来应用补丁,并且如果失败可以用git am --abort。但用户现在用的是patch命令,而不是git am,所以需要调整建议。引用[2]和[3]提到了手动应用补丁后的处理方法,比如使用git commit -a或者手动解决冲突,但用户现在需要的是撤销操作,而不是提交。 接下来,用户提到使用`patch -p1 < 0001-obm-ddr.patch`后出现Hunk失败的情况。传统patch命令应用失败时,会生成.rej文件记录失败的hunk,而成功应用的修改会留在工作目录中。因此,撤销需要处理两部分:已应用的修改和.rej文件。 首先需要检查是否有.rej文件生成,这些文件需要手动删除。然后,需要撤销已成功应用的修改。用户可能没有使用git,所以需要给出不依赖git的解决方案,比如使用patch的逆操作,或者手动恢复备份文件。 但用户之前的问题中提到了git apply,所以可能用户现在是在git仓库中工作。如果是这样,可以利用git来撤销修改,比如使用git checkout -- .或者git reset --hard。但需要确认用户是否在git仓库中,否则这些命令不可用。 另外,引用[2]中提到使用git am --abort,但这仅适用于git am命令,而用户使用的是patch命令,所以不适用。需要明确区分不同命令的处理方式。 用户的需求是撤销部分失败的补丁应用,包括处理失败的hunk和已成功应用的修改。需要分步骤指导用户如何检查.rej文件,如何恢复原始文件,或者如何利用git来撤销修改。 可能的步骤包括: 1. 检查.rej文件,确定哪些部分失败。 2. 使用patch命令的逆操作(patch -R)来撤销已应用的修改,但需要注意这可能不完全可靠。 3. 如果使用git,可以通过git checkout或git reset来撤销所有修改。 4. 手动恢复备份文件(如果patch生成了.orig文件)。 还需要提醒用户,在使用patch命令时,最好先备份代码,或者使用版本控制工具如git来管理修改,以便更容易撤销。 此外,用户可能需要了解如何避免未来的patch应用问题,比如使用git am代替patch命令,或者处理换行符问题(如--keep-cr参数)。 需要确保回答结构清晰,分步骤说明不同情况下的处理方法,并引用提供的参考资料中的相关内容,比如引用[2]中提到的git am --abort和手动解决冲突的方法,但需要根据当前问题调整建议。 最后,生成相关问题,帮助用户进一步理解相关操作和解决方法。</think>### 分步解决方案:撤销失败的`patch`操作与处理Hunk冲突 --- #### **1. 理解两种补丁工具的区别** - **`git apply`**:直接修改工作区,与Git版本控制深度集成 - **`patch`命令**(如`patch -p1`):独立工具,可能生成`.rej`冲突文件和`.orig`备份文件 若执行`patch -p1 < 0001-obm-ddr.patch`出现`Hunk FAILED`,需通过以下步骤处理: --- #### **2. 手动撤销`patch`命令的修改** **步骤1:定位冲突残留文件** ```bash find . -name "*.rej" # 查找冲突片段记录文件 find . -name "*.orig" # 查找原始文件备份 ``` **步骤2:恢复原始文件** - **方法1:通过`.orig`文件回滚** ```bash for file in $(find . -name "*.orig"); do mv "${file%.orig}" "${file%.orig}.broken" # 重命名损坏文件 mv "$file" "${file%.orig}" # 恢复原始文件 done ``` - **方法2:反向应用补丁(需保留原补丁文件)** ```bash patch -p1 -R < 0001-obm-ddr.patch # 尝试逆向撤销补丁 ``` **步骤3:清理残留文件** ```bash rm -f *.rej *.orig *.broken ``` --- #### **3. 使用Git撤销修改(仅限Git仓库)** **若工作目录是Git仓库**,可快速回退: ```bash git checkout -- . # 撤销所有未暂存修改(包括补丁残留) git clean -fd # 删除未跟踪文件(如.rej/.orig) ``` --- #### **4. 处理`Hunk FAILED`的深度方案** **场景示例**:补丁中某hunk因代码上下文变化无法匹配 ```bash patching file src/main.c Hunk #1 FAILED at 23. 1 out of 1 hunk FAILED -- saving rejects to src/main.c.rej ``` **手动修复流程**: 1. **分析`.rej`文件** ```bash cat src/main.c.rej ``` - 输出包含**期望修改的代码块**和**目标行号** 2. **合并冲突** 用文本编辑器打开`src/main.c`,根据`.rej`内容手动调整代码 3. **验证修复** ```bash make test # 运行项目测试 git diff # 检查最终改动 ``` --- #### **5. 预防补丁失败的实践建议** - **优先使用`git am`代替`patch`** ```bash git am --keep-cr 0001-obm-ddr.patch # 自动生成提交并处理换行符[^1] ``` 若冲突可触发交互式解决流程,支持`git am --abort`一键回退[^1] - **检查补丁基线版本** 使用`git log -p`确认当前代码状态与补丁生成时的基线一致[^4] - **拆分复杂补丁** 若补丁包含多个逻辑变更,建议拆分为独立提交后再应用[^4] --- ### 关键命令对比 | 场景 | 传统`patch`命令 | Git集成方案 | |----------------------|-----------------------------------|---------------------------| | 应用补丁 | `patch -p1 < file.patch` | `git am --keep-cr file.patch` | | 撤销修改 | 手动处理`.rej`/`.orig` | `git am --abort` | | 保留提交信息 | 不支持 | 自动保留作者、日期等信息 | | 冲突解决 | 需手工比对文件 | `git mergetool`交互式解决 | --- ### 相关问题 1. **如何生成兼容性更好的补丁文件?** - 使用`git format-patch`代替`diff`,确保包含完整上下文信息[^1] - 示例: ```bash git format-patch -1 HEAD --stdout > mypatch.patch ``` 2. **`git am`冲突后如何继续?** - 手动解决冲突 → `git add`冲突文件 → `git am --continue` - 或放弃补丁:`git am --abort`[^1] 3. **如何处理Windows/Linux换行符差异?** - 在`git am`时始终添加`--keep-cr`参数[^1] - 配置Git全局设置: ```bash git config --global core.autocrlf input ```
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值