LK bootloaderWord文件下载.docx
《LK bootloaderWord文件下载.docx》由会员分享,可在线阅读,更多相关《LK bootloaderWord文件下载.docx(15页珍藏版)》请在冰豆网上搜索。
dpc_init();
//initializekerneltimersdprintf(SPEW,"
initializingtimers/n"
timer_init();
#if(!
ENABLE_NANDWRITE)//createathreadtocompletesysteminitializationdprintf(SPEW,"
creatingbootstrapcompletionthread/n"
thread_resume(thread_create("
bootstrap2"
&
amp;
bootstrap2,NULL,DEFAULT_PRIORITY,DEFAULT_STACK_SIZE));
//enableinterruptsexit_critical_section();
//becometheidlethreadthread_become_idle();
#elsebootstrap_nandwrite();
#endif}
Ininclude/debug.h:
我们可以看到dprintf的第一个参数是代表debuglevel.
/*debuglevels*/#defineCRITICAL0#defineALWAYS0#defineINFO1#defineSPEW2
#definedprintf(level,x...)do{if((level)&
lt;
=DEBUGLEVEL){_dprintf(x);
}}while(0)
所以dprintf会依DEBUGLEVEL来判断是否输出信息.
来看第一个call的函数:
thread_init_early,defineinthread.c
voidthread_init_early(void){inti;
/*initializetherunqueues*/for(i=0;
i&
NUM_PRIORITIES;
i++)list_initialize(&
run_queue[i]);
/*initializethethreadlist*/list_initialize(&
thread_list);
/*createathreadtocoverthecurrentrunningstate*/thread_t*t=&
bootstrap_thread;
init_thread_struct(t,"
bootstrap"
/*halfconstructthisthread,sincewe'
realreadyrunning*/t-&
gt;
priority=HIGHEST_PRIORITY;
t-&
state=THREAD_RUNNING;
saved_critical_section_count=1;
list_add_head(&
thread_list,&
t-&
thread_list_node);
current_thread=t;
}
#defineNUM_PRIORITIES32ininclude/kernel/thread.h
list_initialize()definedininclude/list.h:
initializedalist
staticinlinevoidlist_initialize(structlist_node*list){list-&
prev=list-&
next=list;
run_queue是staticstructlist_noderun_queue[NUM_PRIORITIES]
thread_list是staticstructlist_nodethread_list
再来要call的函数是:
arch_early_init()definedinarch/arm/arch.c
voidarch_early_init(void){/*turnoffthecache*/arch_disable_cache(UCACHE);
/*setthevectorbasetoourexceptionvectorssowedontneedtodoublemapat0*/#ifARM_CPU_CORTEX_A8set_vector_base(MEMBASE);
#endif#ifARM_WITH_MMUarm_mmu_init();
platform_init_mmu_mappings();
#endif/*turnthecachebackon*/arch_enable_cache(UCACHE);
#ifARM_WITH_NEON/*enablecp10andcp11*/uint32_tval;
__asm__volatile("
mrcp15,0,%0,c1,c0,2"
:
"
=r"
(val));
val|=(3&
&
22)|(3&
20);
mcrp15,0,%0,c1,c0,2"
:
r"
/*setenablebitinfpexc*/val=(1&
30);
mcrp10,7,%0,c8,c0,0"
现代操作系统普遍采用虚拟内存管理(VirtualMemoryManagement)机制,这需要处理器中的MMU(MemoryManagementUnit,
内存管理单元)提供支持。
CPU执行单元发出的内存地址将被MMU截获,从CPU到MMU的地址称为虚拟地址(VirtualAddress,以下简称VA),而MMU将这个地
址翻译成另一个地址发到CPU芯片的外部地址引脚上,也就是将VA映射成PA
MMU将VA映射到PA是以页(Page)为单位的,32位处理器的页尺寸通常是4KB。
例如,MMU可以通过一个映射项将VA的一页
0xb7001000~0xb7001fff映射到PA的一页0x2000~0x2fff,如果CPU执行单元要访问虚拟地址0xb7001008,则实际访问到的物理地
址是0x2008。
物理内存中的页称为物理页面或者页帧(PageFrame)。
虚拟内存的哪个页面映射到物理内存的哪个页帧是通过页
表(PageTable)来描述的,页表保存在物理内存中,MMU会查找页表来确定一个VA应该映射到什么PA。
操作系统和MMU是这样配合的:
1.操作系统在初始化或分配、释放内存时会执行一些指令在物理内存中填写页表,然后用指令设置MMU,告诉MMU页表在物理内存中
的什么位置。
2.设置好之后,CPU每次执行访问内存的指令都会自动引发MMU做查表和地址转换操作,地址转换操作由硬件自动完成,不需要用指令
控制MMU去做。
MMU除了做地址转换之外,还提供内存保护机制。
各种体系结构都有用户模式(UserMode)和特权模式(PrivilegedMode)之分,
操作系统可以在页表中设置每个内存页面的访问权限,有些页面不允许访问,有些页面只有在CPU处于特权模式时才允许访问,有些页面
在用户模式和特权模式都可以访问,访问权限又分为可读、可写和可执行三种。
这样设定好之后,当CPU要访问一个VA时,MMU会检查
CPU当前处于用户模式还是特权模式,访问内存的目的是读数据、写数据还是取指令,如果和操作系统设定的页面权限相符,就允许访
问,把它转换成PA,否则不允许访问,产生一个异常(Exception)
常见的segmentationfault产生的原因:
用户程序要访问一段VA,经MMU检查后无权访问,MMU会产生异常,CPU从用户模式切换到特权模式,跳转到内核代码中执行异常服务程序.
内核就会把这个异常解释为segmentationfault,将引发异常的程序终止.
简单的讲一下NEON:
NEONtechnologycanacceleratemultimediaandsignalprocessingalgorithmssuchasvideoencode/decode,
2D/3Dgraphics,gaming,audioandspeechprocessing,imageprocessing,telephony,andsoundsynthesis.
platform_early_init()definedinplatform/&
your-platform&
/platform.c
voidplatform_early_init(void){uart_init();
platform_init_interrupts();
platform_init_timer();
uart_init.cdefinedinplatform/&
/uart.c所有用到的变数,也都定义在uart.c
voiduart_init(void){uwr(0x0A,UART_CR);
/*disableTXandRX*/uwr(0x30,UART_CR);
/*reseterrorstatus*/uwr(0x10,UART_CR);
/*resetreceiver*/uwr(0x20,UART_CR);
/*resettransmitter*/#ifPLATFORM_QSD8K/*TCXO*/uwr(0x06,UART_MREG);
uwr(0xF1,UART_NREG);
uwr(0x0F,UART_DREG);
uwr(0x1A,UART_MNDREG);
#else/*TCXO/4*/uwr(0xC0,UART_MREG);
uwr(0xAF,UART_NREG);
uwr(0x80,UART_DREG);
uwr(0x19,UART_MNDREG);
#endifuwr(0x10,UART_CR);
/*resetRX*/uwr(0x20,UART_CR);
/*resetTX*/uwr(0x30,UART_CR);
/*reseterrorstatus*/uwr(0x40,UART_CR);
/*resetRXbreak*/uwr(0x70,UART_CR);
/*rest?
*/uwr(0xD0,UART_CR);
/*reset*/uwr(0x7BF,UART_IPR);
/*staletimeout=630*bitrate*/uwr(0,UART_IMR);
uwr(115,UART_RFWR);
/*RXwatermark=58*2-1*/uwr(10,UART_TFWR);
/*TXwatermark*/uwr(0,UART_RFWR);
uwr(UART_CSR_115200,UART_CSR);
uwr(0,UART_IRDA);
uwr(0x1E,UART_HCR);
//uwr(0x7F4,UART_MR1);
/*RFS/CTS/500chrRFR*/uwr(16,UART_MR1);
uwr(0x34,UART_MR2);
/*8N1*/uwr(0x05,UART_CR);
/*enableTX&
RX*/uart_ready=1;
platform_init_interrupts:
definedinplatform/msm8x60/interrupts.c
voidplatform_init_interrupts(void){platform_gic_dist_init();
platform_gic_cpu_init();
GIC指的是GenericInterruptController.Thegic-cpuandgic-distaretwosubcomponentsofGIC.
Devicesarewiredtothegit-distwhichisinchargeofdistributinginterruptstothegic-cpu(percpuIRQIF).
platform_init_timer():
definedinplatform/&
/timer.c
voidplatform_init_timer(void){writel(0,DGT_ENABLE);
DGT:
DigitalGameTimer:
presentsthecountdownsoftwoplayers,itisalsocalledchesstimerorchessclock.
target_early_init():
definedintarget/init.c
/**defaultimplementationsoftheseroutines,ifthetargetcode*choosesnottoimplement.*/__WEAKvoidtarget_early_init(void){}__WEAKvoidtarget_init(void){}
call_constructors()isdefinedinkernel/main.c:
staticvoidcall_constructors(void){void**ctor;
ctor=&
__ctor_list;
while(ctor!
=&
__ctor_end){void(*func)(void);
func=(void(*)())*ctor;
func();
ctor++;
}}
heap_initisdefinedinlib/heap/heap.c:
voidheap_init(void){LTRACE_ENTRY;
//settheheaprangetheheap.base=(void*)HEAP_START;
theheap.len=HEAP_LEN;
LTRACEF("
base%psize%zdbytes/n"
theheap.base,theheap.len);
//initializethefreelistlist_initialize(&
theheap.free_list);
//createaninitialfreechunkheap_insert_free_chunk(heap_create_free_chunk(theheap.base,theheap.len));
//dumpheapinfo//heap_dump();
//dprintf(INFO,"
runningheaptests/n"
//heap_test();
thread_initisdefinedinkernel/thread.cbutnothingcoded,先记下.
voidthread_init(void){}
dpc_init()isdefinedinkernel/dpc.c:
voiddpc_init(void){event_init(&
dpc_event,false,0);
dpc"
dpc_thread_routine,NULL,DPC_PRIORITY,DEFAULT_STACK_SIZE));
dpc为DelayedProcedureCall延迟过程调用的缩写.
timer_init()isdefinedinkernel/timer.c:
voidtimer_init(void){list_initialize(&
timer_queue);
/*registerforaperiodictimertick*/platform_set_periodic_timer(timer_tick,NULL,10);
/*10ms*/}
执行thread_resume或是bootstrap_nandwrite
#if(!
#endif
Inkermel/main.c:
staticintbootstrap2(void*arg){dprintf(SPEW,"
topofbootstrap2()/n"
arch_init();
//initializetherestoftheplatformdprintf(SPEW,"
initializingplatform/n"
platform_init();
//initializethetargetdprintf(SPEW,"
initializingtarget/n"
target_init();
dprintf(SPEW,"
callingapps_init()/n"
apps_init();
return0;
}#if(ENABLE_NANDWRITE)voidbootstrap_nandwrite(void){dprintf(SPEW,"
callingnandwrite_init()/n"
nandwrite_init();
}#endif
continuetoseeapps_init():
app/app.c:
voidapps_init(void)
#include&
app.h&
#include