LK bootloaderWord文件下载.docx

上传人:b****4 文档编号:17386425 上传时间:2022-12-01 格式:DOCX 页数:15 大小:21.56KB
下载 相关 举报
LK bootloaderWord文件下载.docx_第1页
第1页 / 共15页
LK bootloaderWord文件下载.docx_第2页
第2页 / 共15页
LK bootloaderWord文件下载.docx_第3页
第3页 / 共15页
LK bootloaderWord文件下载.docx_第4页
第4页 / 共15页
LK bootloaderWord文件下载.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

LK bootloaderWord文件下载.docx

《LK bootloaderWord文件下载.docx》由会员分享,可在线阅读,更多相关《LK bootloaderWord文件下载.docx(15页珍藏版)》请在冰豆网上搜索。

LK bootloaderWord文件下载.docx

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

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1