嵌入式Linux開發(fā)環(huán)境的搭建之:U-Boot移植
2.U-Boot重要代碼
(1)cpu/arm920t/start.S
這是U-Boot的起始位置。在這個文件中設(shè)置了處理器的狀態(tài)、初始化中斷向量和內(nèi)存時序等,從Flash中跳轉(zhuǎn)到定位好的內(nèi)存位置執(zhí)行。
.globl_start(起始位置:中斷向量設(shè)置)
_start:breset
ldrpc,_undefined_instruction
ldrpc,_software_interrupt
ldrpc,_prefetch_abort
ldrpc,_data_abort
ldrpc,_not_used
ldrpc,_irq
ldrpc,_fiq
_undefined_instruction:.wordundefined_instruction
_software_interrupt:.wordsoftware_interrupt
_prefetch_abort:.wordprefetch_abort
_data_abort:.worddata_abort
_not_used:.wordnot_used
_irq:.wordirq
_fiq:.wordfiq
_TEXT_BASE:(代碼段起始位置)
.wordTEXT_BASE
.globl_armboot_start
_armboot_start:
.word_start
/*
*Thesearedefinedintheboard-specificlinkerscript.
*/
.globl_bss_start(BSS段起始位置)
_bss_start:
.word__bss_start
.globl_bss_end
_bss_end:
.word_end
reset:(執(zhí)行入口)
/*
*setthecputoSVC32mode;使處理器進(jìn)入特權(quán)模式
*/
mrsr0,cpsr
bicr0,r0,#0x1f
orrr0,r0,#0xd3
msrcpsr,r0
relocate:(代碼的重置)/*relocateU-BoottoRAM*/
adrr0,_start/*r0-currentpositionofcode*/
ldrr1,_TEXT_BASE/*testifwerunfromflashorRAM*/
cmpr0,r1/*dontrelocduringdebug*/
beqstack_setup
ldrr2,_armboot_start
ldrr3,_bss_start
subr2,r3,r2/*r2-sizeofarmboot*/
addr2,r0,r2/*r2-sourceendaddress*/
copy_loop:(拷貝過程)
ldmiar0!,{r3-r10}/*copyfromsourceaddress[r0]*/
stmiar1!,{r3-r10}/*copytotargetaddress[r1]*/
cmpr0,r2/*untilsourceendaddreee[r2]*/
blecopy_loop
/*Setupthestack;設(shè)置堆棧*/
stack_setup:
ldrr0,_TEXT_BASE/*upper128KiB:relocateduboot*/
subr0,r0,#CFG_MALLOC_LEN/*mallocarea*/
subr0,r0,#CFG_GBL_DATA_SIZE/*bdinfo*/
clear_bss:(清空BSS段)
ldrr0,_bss_start/*findstartofbsssegment*/
ldrr1,_bss_end/*stophere*/
movr2,#0x00000000/*clear*/
clbss_l:strr2,[r0]/*clearloop...*/
addr0,r0,#4
cmpr0,r1
bneclbss_l
ldrpc,_start_armboot
_start_armboot:.wordstart_armboot
(2)interrupts.c
這個文件是處理中斷的,如打開和關(guān)閉中斷等。
#ifdefCONFIG_USE_IRQ
/*enableIRQinterrupts;中斷使能函數(shù)*/
voidenable_interrupts(void)
{
unsignedlongtemp;
__asm____volatile__(mrs%0,cpsrn
bic%0,%0,#0x80n
msrcpsr_c,%0
:=r(temp)
:
:memory);
}
/*
*disableIRQ/FIQinterrupts;中斷屏蔽函數(shù)
*returnstrueifinterruptshadbeenenabledbeforewedisabledthem
*/
intdisable_interrupts(void)
{
unsignedlongold,temp;
__asm____volatile__(mrs%0,cpsrn
orr%1,%0,#0xc0n
msrcpsr_c,%1
:=r(old),=r(temp)
:
:memory);
return(old0x80)==0;
}
#endif
voidshow_regs(structpt_regs*regs)
{
unsignedlongflags;
constchar*processor_modes[]={
USER_26,FIQ_26,IRQ_26,SVC_26,
UK4_26,UK5_26,UK6_26,UK7_26,
UK8_26,UK9_26,UK10_26,UK11_26,
UK12_26,UK13_26,UK14_26,UK15_26,
USER_32,FIQ_32,IRQ_32,SVC_32,
UK4_32,UK5_32,UK6_32,ABT_32,
UK8_32,UK9_32,UK10_32,UND_32,
UK12_32,UK13_32,UK14_32,SYS_32,
};
…
}
/*在U-Boot啟動模式下,在原則上要禁止中斷處理,所以如果發(fā)生中斷,當(dāng)作出錯處理*/
voiddo_fiq(structpt_regs*pt_regs)
{
printf(fastinterruptrequestn);
show_regs(pt_regs);
bad_mode();
}
voiddo_irq(structpt_regs*pt_regs)
{
printf(interruptrequestn);
show_regs(pt_regs);
bad_mode();
}
(3)cpu.c
這個文件是對處理器進(jìn)行操作,如下所示:
intcpu_init(void)
{
/*
*setupupstacksifnecessary;設(shè)置需要的堆棧
*/
#ifdefCONFIG_USE_IRQ
DECLARE_GLOBAL_DATA_PTR;
IRQ_STACK_START=_armboot_start-CFG_MALLOC_LEN-CFG_GBL_DATA_SIZE-4;
FIQ_STACK_START=IRQ_STACK_START-CONFIG_STACKSIZE_IRQ;
#endif
return0;
}
intcleanup_before_linux(void)/*準(zhǔn)備加載linux*/
{
/*
*thisfunctioniscalledjustbeforewecalllinux
*itpreparestheprocessorforlinux
*
*weturnoffcachesetc...
*/
unsignedlongi;
disable_interrupts();
/*turnoffI/D-cache:關(guān)閉cache*/
asm(mrcp15,0,%0,c1,c0,0:=r(i));
i=~(C1_DC|C1_IC);
asm(mcrp15,0,%0,c1,c0,0::r(i));
/*flushI/D-cache*/
i=0;
asm(mcrp15,0,%0,c7,c7,0::r(i));
return(0);
}
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
.=0x00000000;
.=ALIGN(4);
.text:
{
cpu/arm920t/start.o(.text)
*(.text)
}
.=ALIGN(4);
.rodata:{*(.rodata)}
.=ALIGN(4);
.data:{*(.data)}
.=ALIGN(4);
.got:{*(.got)}
__u_boot_cmd_start=.;
.u_boot_cmd:{*(.u_boot_cmd)}
__u_boot_cmd_end=.;
.=ALIGN(4);
__bss_start=.;
.bss:{*(.bss)}
_end=.;
}
c語言相關(guān)文章:c語言教程
linux相關(guān)文章:linux教程
評論