文档库 最新最全的文档下载
当前位置:文档库 › 嵌入式linux启动代码详解

嵌入式linux启动代码详解

嵌入式linux启动代码详解
嵌入式linux启动代码详解

1、程序入口

? 初始化程序中必须指明入口地址,当处理器复位(仿真时,装载image文件)后PC要找到入口开始执行代码,当各

种异常(或中断)产生时也要找到各个异常的入口开始执行代码。

? AREA Init,CODE,READONL Y

? ENTRY

? 这里使用AREA伪操作定义一个代码段Init,使用ENTRY伪操作定义程序的入口。ENTRY 只是定义一个普通的入口

点,且在程序中可以多处定义,它告知链接器,不要在执行优化链接的过程中把这些输入段作为不使用的段删除

掉,如果要使它作为整个映像文件(或称整个程序)的唯一的入口点,还需要设置链接器中的相关选项。使用

CodeWarrior for ARM Developer Suite环境打开一个工程项目文件,在Edit->Debug Setting->ARM Linker-

>Option->Image entry point项可以指定映像的入口,它指定的是一个地址,通常我们将它和RO BASE设在相同

的地址,或是空着为系统默认设置。在Edit->Debug Setting->ARM Linker->Layout->Place at beginning of

image项中有Object/Symbol和Section,其中Object/Symbol指定目标文件,这里要写入启动代码的目标文件名,

如2410init.o。Section指定输入的段名,这里是Init。这样当编译、链接后,映像文件就有了唯一的程序入口点。

?ASSERT :DEF:ENDIAN_CHANGE

?[ ENDIAN_CHANGE

?ASSERT :DEF:ENTRY_BUS_WIDTH

?[ ENTRY_BUS_WIDTH=32

? b ChangeBigEndian ;DCD 0xea000007

?]

?[ ENTRY_BUS_WIDTH=16

?andeq r14,r7,r0,lsl #20 ;DCD 0x0007ea00

?]

?[ ENTRY_BUS_WIDTH=8

?streq r0,[r0,-r10,ror #1] ;DCD 0x070000ea

?]

?|

? b ResetHandler

?]

?这段程序的开始使用ASSERT伪操作判断ENDIAN_CHANGE是否被定义,如果没有定义,ASSERT伪操作将报告

错误类型,并终止汇编。ENDIAN_CHANGE是在option.s文件中定义的,读者可以用鼠标点击2410init.s文件的编

辑器左上角h标记(如图 5.2所示)打开option.s文件查看,另外它还定义了ENTRY_BUS_WIDTH,如下:

?GBLL ENDIAN_CHANGE

?ENDIAN_CHANGE SETL {FALSE}

?GBLA ENTRY_BUS_WIDTH

?ENTRY_BUS_WIDTH SETA 16

?图5.2 打开option.s文件由ENDIAN_CHANGE和ENTRY_BUS_WIDTH的定义可知,IF 伪操作的逻辑表达式为

FALSE,上述的一堆程序也可以只看成是:

? b ResetHandler

2.看门狗及中断的禁止

? ResetHandler

? ldr r0,=WTCON ;watch dog disable

? ldr r1,=0x0

? str r1,[r0]

? ldr r0,=INTMSK

? ldr r1,=0xffffffff ;all interrupt disable

? str r1,[r0]

? ldr r0,=INTSUBMSK

? ldr r1,=0x7ff ;all sub interrupt disable,

2002/04/10

? str r1,[r0]

3.测试LED的显示

? [ {FALSE}

? ; rGPFDAT= (rGPFDAT& ~(0xf<<4)) | ((~data & 0xf)<<4);

? ; Led_Display

? ldr r0,=GPFCON

? ldr r1,=0x5500

? str r1,[r0]

? ldr r0,=GPFDAT

? ldr r1,=0x10

? str r1,[r0]

? ]

4、系统时钟初始化

? ;To reduce PLL lock time, adjust the LOCKTIME register.

? ldr r0,=LOCKTIME

? ldr r1,=0xffffff

? str r1,[r0]

? LOCKTIME为PLL锁定时间计数寄存器(PLL lock time count register)。当重新设定分频值时,PLL进入锁定,输出稳

定频率的时钟需要一定的时间。S3C2410A用户手册上给出的值必须大于150us,即(1/Fin)*n>150us,Fin为外部时钟

源频率12MHz,n为U--_LTIME或M_LTIME,所以n>150us*12MHz=1800,此处将LOCKTIME=0xffffff,即U_LTIME和

M_LTIME都设成最大的0xfff,以远远满足锁定要求(0xfff =4096>1800)。

? [ PLL_ON_START

? ;Configure MPLL

? ldr r0,=MPLLCON

? ldr r1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV) ;Fin=12MHz,Fout=50MHz

? str r1,[r0]

? ]

? MPLLCON为主时钟锁相环控制寄存器,用于设置MPLL的分频系数。MPLL的输出频率Fout=(m*Fin)/(p*2s),其中

m=(M_MDIV+8),p=(M_PDIV+2),s=M_SDIV。M_MDIV、M_PDIV、M_SDIV都在options.s 文件中定义,另外该文件还

定义了PLL_ON_START变量及逻辑初值,以确定该段代码是否有效,定义如下:

? GBLL PLL_ON_START

? PLL_ON_START SETL {TRUE}

? ……

? GBL A FCLK

? FCLK SETA 50000000

? ……

? [ FCLK = 50000000

? M_MDIV EQU 0x5c ;Fin=12.0MHz Fout=50.0MHz

? M_PDIVEQU 0x4

? M_SDIVEQU 0x2

? ]

? 由于外接时钟为12MHz,由前述公式得MPLL的输出频率Fout为50MHz。

5、关闭低功耗模式

? ;Check if the boot is caused by the wake-up from POWER_OFF mode.

? ld r r1,=GSTATUS2

? ldr r0,[r1]

? tst r0,#0x2

? ;In case of the wake-up from POWER_OFF mode, go to

POWER_OFF_WAKEUP handler.

? bne W AKEUP_POWER_OFF

? GSTATUS2为复位状态寄存器,bit0、bit1、bit2分别对应上电复位、掉电模式

(POWER_OFF)复位和看门狗复位。该段程序判断bit2以确定处理器是否从掉电模

式唤醒,如果是从掉电模式唤醒则跳转到掉电唤醒处理程序。

6、初始化内存控制器

? 1》参数配置

? ;BANK0CON

? B0_Tacs EQU 0x0 ;0clk

? B0_Tcos EQU 0x0 ;0clk

? B0_Tacc EQU 0x7 ;14clk

? B0_Tcoh EQU 0x0 ;0clk

? B0_Tah EQU 0x0 ;0clk

? B0_Tacp EQU 0x0

? B0_PMC EQU 0x0 ;normal

? ;Bank 6 parameter

? B6_MT EQU 0x3 ;SDRAM

? ;B6_Trcd EQU 0x0 ;2clk

? B6_Trcd EQU 0x1 ;3clk

? B6_SCAN EQU 0x1 ;9bit

? ……

? ;REFRESH parameter

? REFEN EQU 0x1 ;Refresh enable

? TREFMD EQU 0x0 ;CBR(CAS before RAS)/Auto refresh

? Trp EQU 0x0 ;2clk

? Trc EQU 0x3 ;7clk

? Tchr EQU 0x2 ;3clk

? REFCNT EQU 1113 ;perio d=15.6us, HCLK=60Mhz, (2048+1-15.6*60)

? END

? 该部分的详细内容请参考memcfg.s文件,它直观的定义了内存控制器相关特殊寄存器的所有功能位的具体数值,当

读者初次扩展一个外设或希望提高某个外设的读写速度时,就可以修改该文件的这些具体时序参数。

? 2》功能寄存器数值表的定义

? SMRDA TA DATA

? DCD

(0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_ BWSCON<<20

)+(B6_BWSCON<<24)+(B7_BWSCON<<28))

? DC D

((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+( B0_PMC))

;GCS0

? DCD

((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+( B1_PMC))

;GCS1

? DCD

((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+( B2_PMC))

;GCS2

? DCD

((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+( B3_PMC))

;GCS3

? DCD

((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+( B4_PMC))

;GCS4

? DCD

((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(

B5_PMC))

;GCS5

? DCD ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)) ;GCS6

? DCD ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) ;GCS7

? DCD ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)

? DCD 0x32 ;SCLK power saving mode, BANKSIZE 128M/128M

? DCD 0x30 ;MRSR6 CL=3clk

? DCD 0x30 ;MRSR7

? 这段程序的开始使用DA TA伪操作指明SMRDATA标号处为一段数据,而非代码。接下来就都用DCD分配一个字

的内存单元,且初始化成由memcfg.s文件中定义的参数运算得出的各寄存器值,共13个字(52字节)数据。

? 3》功能寄存器初始化

? ;Set memory control registers

? ldr r0,=SMRDATA

? ldr r1,=BWSCON ;BWSCON Address

? add r2, r0, #52 ;End address of SMRDATA

? 0

? ldr r3, [r0], #4

? str r3, [r1], #4

? cmp r2, r0

? bne %B0

? 这段代码就是将上节定义的功能寄存器数值表的数据依次传送给实践的内存

控制器的每个特殊功能寄存器,以达到对它们的初始化目的。

7、堆栈初始化

? 1》堆栈地址区间定义

? ;Start address of each stacks,

? _STACK_BASEADDRESS EQU 0x33ff8000

? ……

? ;The location of stacks

? UserStackEQU (_STACK_BASEADDRESS-0x3800) ;0x33ff4800 ~

? SVCStack EQU (_STACK_BASEADDRESS-0x2800) ;0x33ff5800 ~

? UndefStackEQU (_STACK_BASEADDRESS-0x2400) ;0x33ff5c00 ~

? AbortStackEQU (_STACK_BASEADDRESS-0x2000) ;0x33ff6000 ~

? IRQStack EQU (_STACK_BASEADDRESS-0x1000) ;0x33ff7000 ~

? FIQStack EQU (_STACK_BASEADDRESS-0x0) ;0x33ff8000 ~

? 堆栈基地址定义“_STACK_BASEADDRESS EQU 0x33ff8000”位于option.s文件,

而各种模式下的堆栈指针地址直接在2410init.s文件的开始处定义。0x33ff8000地址是

属于Bank6的64M SDRAM空间,如果读者系统的SDRAM不同需要重新修改该地址,

以指向有效的SDRAM地址空间。

2》各种模式的堆栈指针初始化

? ;Initialize stacks

? bl InitStacks

? ……

? ;function initializing stacks

? InitStacks

? mrs r0,cpsr

? bic r0,r0,#MODEMASK

? orr r1,r0,#UNDEFMODE|NOINT

? msr cpsr_cxsf,r1 ;UndefMode

? ldr sp,=UndefStack

? 程序先能过mrs指令将状态寄存器值读取到r0,然后将r0对应的处理器模式位

修改成未定义指令中止模式,再写回状态寄存器使处理器真正切换到未定义

指令中止模式,这也就是所谓的“读出-修改-写回”的方式来修改状态寄存器的

内容。最后将该模式的规模指针sp指向UndefStack定义的地址。下述其它模

式的操作方法也是相同的。

8、中断向量表初始化

? 1》中断入口

? AREA Init,CODE,READONL Y

? ENTRY

? b ResetHandler

? b HandlerUndef ;handler for Undefined mode

? b HandlerSWI ;handler for SWI interrupt

? b HandlerPabort ;handler for PAbort

? b HandlerDabort ;hand ler for DAbort

? b . ;reserved

? b HandlerIRQ ;handler for IRQ interrupt

? b HandlerFIQ ;handler for FIQ interrupt

? 这部分是位于0x0地址开始的连续32字节的各个中断(也称异常)的入口,每个中断占用4字节的存储空间,对于S3C2410A这些中断入口地址是固定和唯一的,类似于51等系列单片机的中断入口。由于4字节只能放置一条ARM指令,所以总是一条跳转指令使程序跳转到存储器的其它地方再去作进一步处理。

2》中断服务程序入口地址表

? _ISR_STARTADDRESS EQU 0x33ffff00

? ……

? 该处是在option.s文件中定义的用以保存中断服务程序入口地址的内存表的基地址。? AREA RamData, DATA, READWRITE

? ^ _ISR_STARTADDRESS

? HandleReset # 4

? HandleUndef # 4

? HandleSWI # 4

? HandlePabort # 4

? HandleDabort # 4

? Hand leReserved# 4

? HandleIRQ # 4

? HandleFIQ # 4

? ;Don't use the label 'IntVectorTable',

? ;The value of IntVectorTableis different with the address you think it may be.

? ;IntVectorTable

? HandleEINT0 # 4

? HandleEINT1 # 4

? ……

? HandleRTC # 4

? HandleADC # 4

? 该处是在2410init.s文件中定义的,先用AREA伪操作定义可读写的数据段,又用MAP(^)伪操作定义首

地址为0x33ffff00(_ISR_STARTADDRESS)的结构化内存表,用FIELD(#)定义内存表中的数据域。

其它指令往往将通过引用FIELD前的标号(如:HandleIR、HandleFIQ、HandleEINT0等)等来写入和读

出对应的中

? 写入和读出对应的中断服务程序的入口地址,如下:

? ; Setup IRQ handler

? ldr r0,=HandleIRQ ;Thi s routine is needed

? ldr r1,=IsrIRQ ;if there isn't 'subs pc,lr,#4' at 0x18, 0x1c

? str r1,[r0]

? 该处将IRQ中断处理程序的IsrIRQ标号地址保存到内存表中的HandleIR数据域中。

? HandlerIRQ

? sub sp,sp,#4 ;decrement sp(tostore jump address)

? stmfdsp!,{r0} ;PUSH the work register to stack(lrdoes'tpush because itreturn

? to original address)

? ldr r0,=HandleIRQ;load the address of HandleXXXto r0

? ldr r0,[r0] ;load the contents(serviceroutine start address) of HandleXXX

? str r0,[sp,#4] ;store the contents(ISR) of HandleXXXto stack

? ldmfds p!,{r0,pc} ;POP the work register and pc(jumpto ISR)

? 该处是从IRQ中断入口(0x18)跳转执行的程序,它从内存表的HandleIRQ数据域中取IRQ 中断

处理程序入口地址(IsrIRQ)给PC,实现进入IsrIRQ程序执行目的。

图5.4 中断源的INTOFFSET偏移值

? ……

? #define _ISR_STARTADDRESS 0x33ffff00

? ……

? 该处是在option.h文件中定义的用以保存中断服务程序地址的内存表的基地址。它要和

汇编文件中的_ISR_STARTADDRESS值一样,因为它们代表的是同一个表,自然也就

是同一个物理地址,只是他们一个在汇编文件中使用,一个在C文件中使用而已。

? #define pISR_RESET (*(unsigned *)(_ISR_STARTADDRESS+0x0))

? #define pISR_UNDEF (*(unsigned *)(_ISR_STARTADDRESS+0x4))

? #define pISR_SWI (*(unsigned *)(_ISR_STARTADDRESS+0x8))

? #define pISR_PABORT (*(unsigned *)(_ISR_ST ARTADDRESS+0xc))

? #define pISR_DABORT (*(unsigned *)(_ISR_STARTADDRESS+0x10))

? #define pISR_RESERVED(*(unsigned *)(_ISR_STARTADDRESS+0x14))

? #define pISR_IRQ (*(unsigned *)(_ISR_STARTADDRESS+0x18))

? #define pISR_FIQ (*(unsigned *)(_ISR_STARTADDRESS+0x1c))

? #define pISR_EINT0 (*(unsigned *)(_ISR_STARTADDRESS+0x20))

? #define pISR_EINT1 (*(unsigned *)(_ISR_STARTADDRESS+0x24))

? ……

? #define pISR_RTC (*(unsigned *)(_ISR_STARTADDRESS+0x98))

? #define pISR_ADC (*(unsigned *)(_ISR_STARTADDRESS+0x9c))

? 该处是在2410addr.h文件中定义的,它同样和汇编文件(2410init.s)的用以保存中断服

务程序入口地址的内存表是同一个。通常在中断初始化程序中,将中断服务程序的入口地址对它们进行初始化,如下:

? pISR_UNDEF= (unsigned)HaltUndef;

? pISR_SWI = (unsigned)HaltSwi;

? pISR_PABORT= (unsigned)HaltPabort;

? pISR_DABORT= (unsigned)HaltDabort;

? ……

? pISR_FIQ = (U32)T0Int; //Timer0 FIQ interrupt

? pISR_TIMER1 = (U32)T1Int; //Timer1 Interrupt

? 等号右边都为各中断服务函数,如:

? void HaltUndef(void){

? Uart_Printf("Undefinedinstruction exception.\n");

? while(1);

? }

? ……

? static void __irqT0Int(void) { //FIQ

? ClearPendin g(BIT_TIMER0);

? fiqCnt0 += 1;

? }

3》中断服务程序的寻找过程

? HandlerFIQ HANDLER HandleFIQ

? HandlerIRQ HANDLER HandleIRQ

? HandlerUndef HANDLER HandleUndef

? HandlerSWI HANDLER HandleSWI

? HandlerDabortHANDLER HandleDabort

? HandlerPabortHANDLER HandlePabort

? ……

? MACRO

? $HandlerLabelHANDLER $HandleLabel

? $HandlerLabel

? sub sp,sp,#4 ;decrement sp(tostore jump address)

? stmfdsp!,{r0} ;PUSH the work register to stack(lrdoes't

push because it return to original address)

? ldr r0,=$HandleLabel;loadthe address of Han dleXXXto r0

? ldr r0,[r0] ;load the contents(serviceroutine start address)

of HandleXXX

? str r0,[sp,#4] ;store the contents(ISR) of HandleXXXto stack

? ldmfdsp!,{r0,pc} ;POP the work register and pc(jumpto ISR)

? MEND

?由于各个中断都有相同的处理代码,所以这里引用了MACRO宏定义,此时各个中断只需书写宏定义的名称HANDLER(该部分内容的开始处,如:HandlerFIQ HANDLER HandleFIQ)就可展开宏定义体的代码。当宏定义展开时,$HandlerLabel标号会被替换成HandlerFIQ(或HandlerIRQ、HandlerUndef

等),而$HandleLabel也会被替换成HandleFIQ(或HandleIRQ、HandleUndef

等)。下述为s3c2410init.s.list文件中,FIQ中断展开的宏代码:

?229 00000124 HandlerFIQHANDLER HandleFIQ

?65 00000124

?66 00000124 HandlerFIQ

?67 00000124 E24DD004 sub sp,sp,#4 ;decrement sp(tostore jump address)

?68 00000128 E92D0001 stmfdsp!,{r0} ;PUSH the work register to stack(lr

does'tpush because it return to original address)

?69 0000012C E59F01C0 ldrr0,=HandleFIQ;load the address of HandleXXX

to r0

?70 00000130 E5900000 ldrr0,[r0] ;load the contents(serviceroutine start

address) of HandleXXX

?71 00000134 E58D0004 strr0,[sp,#4] ;store the contents(ISR) of

HandleXXXto stack

?72 00000138 E8BD8001 ldmfdsp!,{r0,pc} ;POP the work register and

pc(jumpto ISR)

?。

4》外围设备IRQ中断服务程序的寻找过程

? ; Setup IRQ handler

? ldr r0,=HandleIRQ ;This routine is needed

? ldr r1,=IsrIRQ ;if there isn't 'subs pc,lr,#4' at 0x18, 0x1c

? str r1,[r0]

? 这部分代码是将IsrIRQ标号地址保存在中断服务程序入口地址表的HandleIRQ数据域,所以当产生IRQ中断后,PC先指向

IRQ的中断入口0x18地址处,执行“b HandlerIRQ”跳转指后使PC进入“HandlerIRQ HANDLER

HandleIRQ”,该宏展开后与FIQ的执行过程类似,最后PC跳转到HandleIRQ数据域的中断服务程序IsrIRQ,IsrIRQ程序如

下:

? IsrIRQ

? sub sp,sp,#4 ;reserved for PC

? stmfd sp!,{r8-r9}

? ldr r9,=INTOFFSET

? ldr r9,[r9]

? ldr r8,=HandleEINT0

? add r8,r8,r9,lsl #2

? ldr r8,[r8]

? str r8,[sp,#8]

? ldmfd sp!,{r8-r9,pc}

? 假设IRQ模式的SP= 0x33FF7000,执行“sub sp,sp,#4”之后SP=0x33FF6FFC;“stmfdsp!,{ r8-r9} ”指令为SP先递减1

(即减1个字,4字节)变成0x33FF6FF8,然后将r9传给SP指向的地址,之后SP再递减,r8再传给SP指向的地址,所以执

行完该指令后,SP=0x33FF6FF4,0x33FF6FF8保存r9的内容,0x33FF6FF4保存r8的内容;“ldr r9,=INTOFFSET”

指令将INTOFFSET(Indicate the IRQ interrupt request source,它指示着是哪个中断源产生中断,读者要查看

S3C2410A用户手册中该寄存器的表格,列出了中断源对应的OFFSET值)寄存器地址传给r9;“ldr r9,[r9]”指令将r9的

内容传给r9,即将INTOFFSET寄存器的值传给r9;“ldr r8,=HandleEINT0”指令将中断服务程序入口地址表的

HandleIRQ地址(0x33FFFF20)传给r8;“addr8,r8,r9,lsl #2 ”指令将r9左移2位(即r9乘以4)再加上r8原先的内容再传给

r8。r9为何要左移2位呢?是因为每个中断源在表中都占用4字节的地址,而在INTOFFSET 中的偏移值只有1,具体中断源对

着的INTOFFSET值请参考图5.4所示;“ldr r8,[r8]”指令将r8的内容传给r8,即将保存在表中的产生中断的中断源的中

断处理函数入口地址传给r8;“str r8,[sp,#8]”指令将r8值传给SP+8,即传给0x33FF6FFC,SP保持不变,此时

0x33FF6FFC保存着中断处理函数的入口地址;“ldmfdsp!,{r8-r9,pc} ”指令将SP指向的地址(0x33FF6FF4)内容传给r8后递

增1字,再将SP指向的地址(0x33FF6FF8)内容传给r9后递增1字,再将SP指向的地址(0x33FF6FFC)内容传给PC后递

增1字,此时SP= 0x33FF7000,PC指向产生中断的中断源服务程序执行。

9、映像文件运行域的初始化

? 映像文件的详细信息请参考《ARM Linux入门与实践》一书,这里我们分析一下具体的代码。

? IMPORT |Imag e$$RO$$Limit| ; End of ROM code (=start of ROM data)

? IMPORT |Image$$RW$$Base| ; Base of RAM to initialise

? IMPORT |Image$$ZI$$Base| ; Base and limit of area

? IMPORT |Image$$ZI$$Limit| ; to zero initialize

? ……

? ;Copy and paste RW data/zero initialized data

? ldr r0, =|Image$$RO$$Limit| ; Get pointer to ROM data

? ldr r1, =|Image$$RW$$Base| ; and RAM copy

? ldr r3, =|Image$$ZI$$Base|

? ;Zero init base => top of initialiseddata

? cmp r0, r1 ; Check that they are different

? beq %F2

? 1

? cmp r1, r3 ; Cop y init data

? ldrcc r2, [r0], #4 ;--> LDRCC r2, [r0] + ADD r0, r0, #4

? strcc r2, [r1], #4 ;--> STRCC r2, [r1] + ADD r1, r1, #4

? bcc %B1

? 2

? ldr r1, =|Image$$ZI$$Limit| ; Top of zero init segment

? mov r2, #0

? 3

? cmp r3, r1 ; Zero init

? strcc r2, [r3], #4

? bcc %B3

? 开始是引入外部符号|Image$$RO$$Limit|等,它们是链接器生成的符号;读取RO段结束地址、RW段起始地址和ZI段起

始地址;比较RO段结束地址是否等于RW段的起始地址,如果相等就跳过RW段数据的拷贝。

? 下图是代码在0x0地址开始运行时的映像装载情况,此时代码必须小于BootSRAM的4K Byte容量或者是在NOR Flash上

运行。

另外一种比较常见的情况是映像文件被装载到SDRAM的0x30000000起始地址(或之后的地址)运行,如图所示

五、启动代码测试实例

? 注:由于时间有限,感兴趣的朋友可以自行参考<ARM Linux入门与

实践>一书及光盘的测试程序,或者向阿南索要.

? 1.启动过程的分析(以LED控制实验为例)

? 2.中断处理过程分析(以KEY中断实验实例)

解析基于ARM9 的Linux 内存映射

摘要:本文针对市场上流行的嵌入式ARM9 处理器,分析其MMU 功能单元以及其SOC 平台在LINUX 内核中的实现地址映射过程。总结内核建立虚拟内存的一般过程和基本思想。关键词:嵌入式,ARM,LINUX,内存映射

中图分类号:TP399

1.引言

ARM9 是16/32 位RISC 嵌入式微处理器,主要面向手持设备以及高性价比,低功耗的

运用,是ARM7 之后的性能更强,运用更广的嵌入式处理器。两者相比,ARM9 有很多优点,比如:支持更高的主频,指令周期的改进,3 级流水线增加到了5 级,增加存储器管理单元等。其中ARM9 特有的存储器管理单元(MMU,Memory Management Unit)是一个非常重要的特性。

同时高性能操作系统(OS)就需要MMU 来实现物理地址和虚拟地址的转换、内存存取权

限控制等内存管理功能。因此ARM7 一般是使用UCLINUX 等没有内存管理的OS,而ARM9 就可以直接使用LINUX 内核。下面我以基于ARM9 的片上系统s3c2410 和linux2.6.16 内核

来深入解析内存映射的基本原理和过程。

2.ARM MMU 存储器管理单元

MMU 是处理器用来实现物理地址到虚拟地址映射的硬件单元。在ARM9 的体系结构中

把MMU 作为协处理器来实现,即通过协处理器CP15 管理ARM 的MMU。ARM 的MMU 中除了实现虚拟虚拟地址的映射、访问权限外,还包括了对高速缓存和写缓冲的管理。

当ARM 要访问存储器时,MMU 先查找TLB(Translation Lookaside Buffer,旁路转换

缓冲)中的虚拟地址表。如果TLB 中没有虚拟地址的入口,则转换表遍历硬件会从存放在内存的转换表中获得转换和访问器权限。一旦取到,这些信息将被放到TLB 中,这时访问存储器的TLB 入口就拿到了。在TLB 中其实包含了以下信息:1、控制决定是否使用高速缓冲2、访问权限信息3、在有cache 的系统中,如果cache 没有命中,那么物理地址作为线

性获取(line fetch)硬件的输入地址。如果命中了cache 那么数据直接从cache 中得到,物理地址被忽略。ARM 的工作流程可用下图表示:

由此,我们可以看到这种机制是纯粹的高速硬件操作,并不需要操作系统来完成。操作

系统只要提供内存转换表就可以了,但是需要符合一定的格式。

ARM9 的MMU 映射表分为两种,一级页表的变换和二级页表变换。两者的不同之处就

是实现的变换地址空间大小不同。一级页表变换支持1 M 大小的存储空间的映射,而二级可以支持64 kB,4 kB 和1 kB 大小地址空间的映射。在LINUX 中最终使用了1 M 一级页表

和4 kB 的二级页表。

3.内核中地址转换表建立过程

地址转换表建立是和内核的启动一起完成的,按照我对启动过程代码的分析,页表的建

立也可以分为三个阶段:

第一阶段是发生在内核解压缩,自引导时,也就内核镜像zimage 的文件头部分。相关

代码从某种意义上来讲不属于内核,它是BSP 代码中的一部分,是需要根据不同的架构来分别实现的。对于我们这里的S3C2410 来说,主要过程在/arch/arm/boot/compressed/head.S 的__setup_mmu[2]中实现。通过平面映射的方式建立了256M 空间节描述表。但是,这个映射表是临时的,是为了提高内核解压缩时的速度而实现的。在解压缩结束之后,进入内核代码之前,MMU 功能就被关闭了,随之的映射表也被废弃不用。重要代码分析如下:

/*主要关注__setup_mmu */

cache_on: mov r3, #8 @ 打开高速缓存

b call_cache_fn @ call_cache_fn 中应该添加s3c2410 的功能代码

__setup_mmu: sub r3, r4, #16384 @ MMU 映射页表大小16K,r4 是内核地址

bic r3, r3, #0xff @ 保证MMU 一级页表16KB 对齐

bic r3, r3, #0x3f00

/*

* 初始化页表, 为ram 空间开启高速缓存和写缓存

*/

mov r0, r3

mov r9, r0, lsr #18

mov r9, r9, lsl #18 @ 内存映射表的起始地址

add r10, r9, #0x10000000 @ 映射256M 的内存空间

mov r1, #0x12

orr r1, r1, #3 << 10

add r2, r3, #16384

1: cmp r1, r9 @ if virt > start of RAM

orrhs r1, r1, #0x0c @ 开启高速缓存和写缓存

cmp r1, r10 @ if virt > end of RAM

bichs r1, r1, #0x0c @ 关闭高速缓存和写缓存

str r1, [r0], #4 @ 1:1

add r1, r1, #1048576 @ 1M

teq r0, r2

bne 1b

这样形成了一个平面映射的第一级页表,占用16KB 的空间。有些情况下内核是在XIP 的https://www.wendangku.net/doc/f614966050.html,

-3-

flash 中运行的,那么也就需要按照上面的原理,从0x0 地址开始映射flash 的空间,并开启对应的缓冲。

最后当decompress_kernel 函数实现内核的解压缩之后,那么内核启动的第一阶段工作

就完成了。接下来就准备启动真正的内核,但是内核启动时必须要先关闭MMU,以至于刚才的第一阶段映射表不能使用了。

第二阶段是的页表创建是非常关键的。同样也是使用汇编语言来实现,具体文件路径为:

/arch/arm/kernel/head.S。在代码,有个函数__create_page_tables,这就是创建MMU 映射表,开启MMU 做准备的重要动作,代码分析如下:

/* /arch/arm/kernel/head.S */

__create_page_tables:

pgtbl r4 @ 页表的起始地址0x30008000 –0x4000,16KB 对齐

mov r0, r4 @ 清除原来的第一级页表,赋零

mov r3, #0

add r6, r0, #0x4000 @ r6 = 0x30004000

1: str r3, [r0], #4

str r3, [r0], #4

str r3, [r0], #4

str r3, [r0], #4

teq r0, r6

bne 1b

/*映射1M 空间,使得虚拟地址=物理地址*/

ldr r7, [r10, #PROCINFO_MMUFLAGS] @ PROCINFO_MMUFLAGS = 8, r10 =

proc_info

mov r6, pc, lsr #20 @ 当前运行的内核(1M 对齐)地址

orr r3, r7, r6, lsl #20 @ r3 中保存内核起始地址描述符

str r3, [r4, r6, lsl #2] @ r3 保存到对应的转换表地址

/*映射连续4M 的3G 以上内核空间*/

add r0, r4, #(TEXTADDR & 0xff000000) >> 18 @ 3G 地址对应的转换表地址

str r3, [r0, #(TEXTADDR & 0x00f00000) >> 18]! @ 0M

add r3, r3, #1 << 20

str r3, [r0, #4]! @ 1MB

add r3, r3, #1 << 20

str r3, [r0, #4]! @ 2MB

add r3, r3, #1 << 20

str r3, [r0, #4] @ 3MB

/*映射内存起始的1M 空间,以防这段内存中保存了启动参数*/

add r0, r4, #PAGE_OFFSET >> 18 @

orr r6, r7, #PHYS_OFFSET @ PHYS_OFFSET = 0x30000000, r7 = 110000011110B

str r6, [r0]

https://www.wendangku.net/doc/f614966050.html,

-4-

这是真正意义上的第一次建立被内核所用的节转换表,经过上述代码实现,所建立的节转换表对应内容:

表1 初始映射表

转换表物理地址数据

0x30005C00 0x30000C1E

0x30007000 0x30000C1E

0x30007004 0x30100C1E

0x30007008 0x30200C1E

0x3000700c 0x30300C1E

如上表中黑体字所示,这里有个比较特殊的地方,有一节空间进行了两次映射:一个是和物理地址相同的映射;一个是映射到0xC0000000 以上的空间。这是因为按照LINUX 内存空间划分的惯例,3G(0xc0000000)以上的空间作为内核空间,其他的作为用户内存空间。所以这样映射后,只要在前1M 的程序之内的空间开启MMU,并且使用地址跳转指令就可以使内核跑到0xC0000000 以上的空间运行了。但是这个映射表还不是最终系统使用的映射表。第三阶段是创建更高级别的映射关系和映射方法,主要和架构相关。不同的架构有不同

的映射方法,比如ARM 就是二级映射的方法实现地址映射,但是必须按照LINUX 的三级映射模型[3]PGD、PMD、PTE 来实现。从内核代码上来看,内核启动的过程中主要有两个函

数比较重要:

(1)start_kernel->setup_arch->paging_init->bootmem_init->bootmem_init_node->create_mapping

(2) start_kernel->setup_arch->paging_init->devicemaps_init

(3) start_kernel->trap_init

函数一:重新建立了一级映射表,添加了对内存空间的二级映射,同时建立了bootmem 这个内存管理器。函数二:在再bootmem 的帮助下实现了平台部分设备IO 地址的映射。函数三:则是完成了中断矢量的映射。

这样就完成了关于平台的基本映射。但是,地址映射远远没有结束,驱动需要地址空间映射,

用户程序需要地址空间映射等,这些就靠内核的整个内存管理模块来实现了。按照一般的ARM 平台的映射习惯最后得到的映射如下:

表2 最终映射表

开始结束作用

ffff8000 ffffffff copy_user_page / clear_user_page 使用,一般给

SA11xx 和Xscale 用来设置minicache 映射

ffff1000 ffff7fff 保留

ffff0000 ffff0fff CPU 中断向量表

ffc00000 fffeffff DMA 映射空间,根函数dma_alloc_xxx,动态使用

ff000000 ffbfffff 保留给未来DMA 扩展映射使用

VMALLOC_END feffffff VMALLOC_END 对于s3c2410 来说,等于

0xE0000000

VMALLOC_START VMALLOC_END-1 vmalloc() / ioremap()函数动态使用这个空间

PAGE_OFFSET high_memory-1 PAGE_OFFSET=0xC0000000,一般这里是1 比1 的映射https://www.wendangku.net/doc/f614966050.html,

-5-

了平台的内存空间。

TASK_SIZE PAGE_OFFSET-1 TASK_SIZE=0xbf000000,内核模块动态占用的空间00001000 TASK_SIZE-1 mmap()系统调用为用户线程映射的空间

00000000 00000fff 当没有中断地址转换时使用。对于本系统则无用。

以上是在内核启动不同阶段的页表操作过程,到此为止,内核基本完成了映射表的配置。

这个映射表不是固定不变的映射表,随着内核的运行而改变。这样才能够实现操作系统的内存管理,端口映射管理功能,比如:相同物理地址的重复映射,外设IO 口管理等。好在LINUX 提供进行内存管理操作的方法。

4.内核提供的地址映射接口

在参看S3C2410BSP 的代码中,可以发现一对很重要的宏MACHINE_START 和MACHINE_END。他们是为S3C2410 平台初始化一个结构体struct machine_desc 信息,并把它放入内核的https://www.wendangku.net/doc/f614966050.html,.init 段。

其中有map_io 是结构体中的一个重要成员,在内核启动的过程中就是执行了map_io

也就是这里定义的smdk2410_map_io。

/* linux/arch/arm/mach-s3c2410/mach-smdk2410.c 端口映射设置*/

static void __init smdk2410_map_io(void)

{

s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc));

s3c24xx_init_clocks(0);

s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));

s3c24xx_set_board(&smdk2410_board);

//一下可以插入自定义的函数,用于初始化硬件资源的映射

}

MACHINE_START(SMDK2410, "SMDK2410")

.map_io = smdk2410_map_io,

MACHINE_END

有时候在smdk2410_iodesc 中设置映射,显得不灵活。如果平台改变了,那么就要修改

其中的参数,这样就不利于BSP 的通用。因此,LINUX 提供灵活的接口,使得在使用端口的时候才进行映射。主要有这样几个接口:__virt_to_phys(x) ,__phys_to_virt(x) ,

__phys_to_pfn(paddr),__pfn_to_phys(pfn),ioremap,remap。

linux内核启动 Android系统启动过程详解

linux内核启动+Android系统启动过程详解 第一部分:汇编部分 Linux启动之 linux-rk3288-tchip/kernel/arch/arm/boot/compressed/ head.S分析这段代码是linux boot后执行的第一个程序,完成的主要工作是解压内核,然后跳转到相关执行地址。这部分代码在做驱动开发时不需要改动,但分析其执行流程对是理解android的第一步 开头有一段宏定义这是gnu arm汇编的宏定义。关于GUN 的汇编和其他编译器,在指令语法上有很大差别,具体可查询相关GUN汇编语法了解 另外此段代码必须不能包括重定位部分。因为这时一开始必须要立即运行的。所谓重定位,比如当编译时某个文件用到外部符号是用动态链接库的方式,那么该文件生成的目标文件将包含重定位信息,在加载时需要重定位该符号,否则执行时将因找不到地址而出错 #ifdef DEBUG//开始是调试用,主要是一些打印输出函数,不用关心 #if defined(CONFIG_DEBUG_ICEDCC)

……具体代码略 #endif 宏定义结束之后定义了一个段, .section ".start", #alloc, #execinstr 这个段的段名是 .start,#alloc表示Section contains allocated data, #execinstr表示Section contains executable instructions. 生成最终映像时,这段代码会放在最开头 .align start: .type start,#function /*.type指定start这个符号是函数类型*/ .rept 8 mov r0, r0 //将此命令重复8次,相当于nop,这里是为中断向量保存空间 .endr b 1f .word 0x016f2818 @ Magic numbers to help the loader

什么是嵌入式linux系统

什么是嵌入式linux系统? 一、什么是嵌入式linux? Linux从1991年问世到现在,短短的十几年时间已经发展成为功能强大、设计完善的操作系统之一,不仅可以与各种传统的商业操作系统分庭抗争,在新兴的嵌入式操作系统领域内也获得了飞速发展。嵌入式Linux(Embedded Linux)是指对标准Linux经过小型化裁剪处理之后,能够固化在容量只有几K或者几M字节的存储器芯片或者单片机中,适合于特定嵌入式应用场合的专用Linux操作系统。嵌入式Linux既继承了intelnet上无限的开放原代码资源,又具有嵌入式操作系统的特性。 二、嵌入式Linux的特点版权费:免费; 购买费用:媒介成本; 技术支持:全世界的自由软件开发者提供支持; 网络特性:免费而且性能优异; 软件移植:容易,代码开放,有许多应用软件支持; 应用产品开发周期:短,新产品上市迅速,因为有许多公开的代码可以参考和移植; 实时性能:RT_Linux,hardhat Linux 等嵌入式Linux支持实时性能; 稳定性:好; 安全性:好。 三、嵌入式Linux的市场前景和商业机会 嵌入式Linux有巨大的市场前景和商业机会,出现了大量的专业公司和产品,如Montavista、Lineo、Emi等。有行业协会,如Embedded Linux Consortum等。得到世界著名计算机公司和oem板级厂商的支持,例如IBM、Motorola、Intel等。传统的嵌入式系统厂商也采用了Linux策略如Lynxworks 、Windriver、QNX等。还有intelnet上的大量嵌入式Linux 爱好者的支持。嵌入式Linux支持几乎所有的嵌入式cpu和被移植到几乎所有的嵌入式oem板。 四、嵌入式Linux的应用领域嵌入式Linux的应用领域非常广泛,主要的应用领域有,信息家电:PDA,STB-Set-stopbox,Digital Telephone,Answering Machine,Screen Phone、数据网络:Ethernet switches,Router,Bridge,Hub,Remote access servers,ATM,Frame relay、远程通信、医疗电子、交通运输、计算机外设、工业控制、航空领域等。 五、嵌入式linux的优势嵌入式Linux的开发和研究是操作系统领域中的一个热点,目前已经开发成功的嵌入式系统中,大约有一半使用的是Linux。Linux之所以能在嵌入式系统市场上取得如此辉煌的成果,与其

linux启动顺序讲解

一、简单介绍RHEL开机时的先后顺序 BIOS —> MBR —> Kernel —> init 1、当电脑一打开电源时电脑就会进入BIOS(BIOS的工作主要是检测一些硬件设备); 2、检测完后会进入MBR也就是boot loader(MBR位于硬盘的第一个扇区总共512bytes,其中前446bytes里面的编码是在选择引导分区也就是决定要由哪个分区来引导); 3、载入系统的Kernel(核心),在Kernel里主要是载入电脑设备的驱动程序,以便可以控制电脑上的设备,并且以只读方式来挂载根目录,也就是一开始只能读取到根目录所对应的那个分区,所以/etc、/bin、/sbin、/dev、/lib这五个目录必须同根目录在一个分区中; 4、最后启动init这个程序,所以init这个程序的进程编号为1,是Linux中第一个执行的程序; init这个程序会根据Run level来执行以下这些程序: ·/etc/rc.d/rc.sysinit; ·/etc/rc.d/rc 和etc/rc.d/rc?.d/ ·/etc/rc.d/rc.local ·如果有适当的图形界面管理程序 二、BIOS初始化时主要的三个任务 BIOS(B asic I nput/O utput S ystem) 1、电脑周边设备的检测,加电自检POST (Power on self test); 2、BIOS会选择要由哪一个设备来开机,例如:软盘启动、光盘启动、网络启动、最常见的从硬盘启动; 3、选择好由哪个设备开机后,就开始读取这个设备的MBR 引导扇区; 三、介绍Boot Loader中的主要工作 1、Boot Loader可以安装在两个地方: ·安装在硬盘的MBR中; ·当有时候MBR中被其他开机管理程序占用就可以将Boot Loader 安装在硬盘中的其中一个分区的引导扇区上,; 2、Boot Loader的程序码分为两个阶段: (1)Boot Loader第一阶段的程序码非常小,只有446bytes,可以存入在MBR或是某一个分区的引导扇区里, (2)Boot Loader第一阶段的程序码是从boot 分区来载入的,就是说Boot Loader 第二阶段程序码存放在/boot 这个分区中; 3、下面来看三个Boot Loader 的开机流程范例,如在一块硬盘中安装了两个系统分别为:windows 2003 和Red hat linux 当电脑开机后,会先载入MBR通过第一阶段程序码来载入第二阶段程序码,进入GRUB开机菜单这里选择哪个系统就会载入相应的核心;

嵌入式Linux系统期末考试简答题、运用题

简答题与应用题 什么是嵌入式系统?主要有什么特点? 以应用为中心,以计算机技术为基础的, 并且软件硬件是可剪裁的, 能满足应用系统对功能、 可靠性、成本、 体积、功耗等指标的严格要求的专用计算机系统。他可以实现对其他设备的控制、监视或者管理等功能。 与通用的 计算机系统相比,特点为: (1) (2) (5) 嵌入式系统通常由嵌入式处理机、嵌入式外围设备、嵌入式操作系统和嵌入式应用软件等几大部分组成。 4、什么是Linux ?什么是嵌入式 Linux ? 答:严格来讲,Linux 是指由Linux 本人维护并不断更新的内核 。 一个嵌入式Linux 系统指的是一个基于 Linux 内核的,但不包含有关这个内核的任何专业的库或是用户工具 的嵌入式系统。 Linux 内核构建嵌入式操作系统有什么优势(优良特性)? 程度代码是可以获取的,可靠度高; 有完整的源码,软件丰富并且免费; 得到众多硬件生产家的广泛支持;包括 cpu 、计算机外 围设备 完善的通信协议、软件标准和文件管理机制; 提供完全免费且优秀的开发工具; 广泛的社群支持 无需购买lice nee ,是免费的; 不依赖特定厂商、供应商; 成本相对低廉。 6、 RTOS (嵌入式操作系统)强调的实时是什么概念?与中断的关系? 答:实时指的是特定操作所消耗的时间(以及空间)的上限是可预知的。操作系统能够在规定响应时间内完成客 户服务程序。中断程序响应中断并完成 是在固定时间内。 7、什么是实时LinUX ?涉及到哪些软硬件内容? 答:实时LinUX ( RT-Linux )通过在Linux 内核与硬件中断之间增加一个精巧的可抢先的实时内核 ,把标准的Linux 内核作为实时内核的一个进程与用户进程一起调度 ,标准的Linux 内核的优先级最低,可以被实时进程抢断。 正 常的Linux 进程仍可以在Linux 内核上运行,这样既可以使用标准分时操作系统即 Linux 的各种服务,又能提 供低延时的实时环境。它在硬件上涉及到硬件中断,软件上涉及到对高优先级的实时硬件中断的快速响应。 能在规定的时间内完成对突发事件的处理的 Linux 系统; 软件:中断服务程序、进程调度程序,硬件:嵌入式系统所采用的中断管理硬件。 8、试简要说明Linux 内核构成,并简要说明各部分的功能? 答: MMU :内存管理单元,完成地址映射(应用虚拟地址方式) VFS :虚拟文件管理系统,提供了统一管理计算机资源的途径。使统一规范计算机资源的使用格式成为可能,方 1、 答: 面向特定应用,一般都有实时要求; 集先进性的计算机技术、半导体工艺、电子技术和通信网络技术于一体的并且在不断创新的知识集 成系统; 嵌入式系统是和具体应用对象有机结合在一起,因而其升级换代也是和具体的产品同步进行的。 嵌入式系统的软 硬件设计着重于高效率性。在最大限度满足应用需求的前提下,降低成本是必须要 考虑的主要问题。 嵌入式系统软件一般都固化在存储器芯片中。 (3) (4) 5、 用 答:( 1) (2) (3) (4) (5) (6) (7) (8) () 2、 答: 3、嵌入式操作系统的作用是什么?

嵌入式Linux系统开发教程很完整的习题答案资料

参考答案 第一章 一、填空题。 1、嵌入式系统主要融合了计算机软硬件技术、通信技术和微电子技术,它是将计算机直接嵌入到应用系统中,利用计算机的高速处理能力以实现某些特定的功能。 2、目前国内对嵌入式系统普遍认同的定义是:以应用为中心、以计算机技术为基础、软硬件可裁剪、适应应用系统对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统。 3、嵌入式系统一般由嵌入式计算机和执行部件组成,其中嵌入式计算机主要由四个部分组成,它们分别是:硬件层、中间层、系统软件层以及应用软件层。 4、嵌入式处理器目前主要有ARM、MIPS、Power PC、68K等,其中arm处理器有三大特点:体积小、低功耗、的成本和高性能,16/32位双指令集,全球合作伙伴众多。 5、常见的嵌入式操作系统有:Linux、Vxworks、WinCE、Palm、uc/OS-II和eCOS。 6、嵌入式系统开发的一般流程主要包括系统需求分析、体系结构设计、软硬件及机械系统设计、系统集成、系统测试,最后得到最终产品。 二、选择题 1、嵌入式系统中硬件层主要包含了嵌入式系统重要的硬件设备:、存储器(SDRAM、ROM等)、设备I/O接口等。(A) A、嵌入式处理器 B、嵌入式控制器 C、单片机 D、集成芯片 2、20世纪90年代以后,随着系统应用对实时性要求的提高,系统软件规模不断上升,实时核逐渐发展为,并作为一种软件平台逐步成为目前国际嵌入式系统的主流。(D) A、分时多任务操作系统 B、多任务操作系统 C、实时操作系统 D、实时多任务操作系统 3、由于其高可靠性,在美国的火星表面登陆的火星探测器上也使用的嵌入式操作系统是。(B) A、Palm B、VxWorks C、Linux D、WinCE [在此处键入]

怎样执行在Linux上运行应用程序

如何执行在Linux上运行的应用程序 关键字:Linux 先决条件 要充分理解本文,必须具备Windows 环境下桌面应用程序的工作经验,我认为读者对如何使用Linux 桌面有一个基本的了解。使用一个运行的Linux 计算来机探讨本文的概念和示例是很有帮助的。 概述 有时候第一次在Linux 上运行一个应用程序需要一点额外工作。有些应用程序,比如服务器服务,可能无法安装为服务,因此您需要从命令行启动这些应用程序。对于启动这些应用程序的用户帐户而言,需要在应用程序文件中设置执行许可标志(x)。 运行用户空间应用程序 Linux 在内核空间或用户空间运行进程。用户空间是操作系统的区域,应用程序通常在此运行。简单地说,每个用户帐户有其自己的用户空间,应用程序在这个领域内运行。 默认情况下,只有root 用户有权访问内核空间。root 用户是Linux 中的超级用户,相当于Windows 中的管理员帐户。在root 用户帐户下运行应用程序可能会引起安全风险,是不可取的。 很多服务器服务需要root 权限启动服务。然而,服务启动后,root 帐户通常会将其移至服务帐户。严格地说,Linux 中的服务帐户才是标准的用户帐户。主要区别是服务帐户仅用于运行一个服务,而不是为任何实际登录的用户准备的。 设置权限 您可以使用chmod 命令在一个文件中设置执行权限。在Linux 中,umask 设置通常用来防止下载的文件被执行,也有充分的理由相信,因为它有助于维护Linux 计算机的安全性。 大多数Linux 发行版具有一个值为022 的umask 设置,这意味着,默认情况下一个新文件权限设置为644.权限的数字表示形式采用读(4)、写(2)、执行(1) 的格式。因此,默认权限为644 的应用程序下载意味着文件所有者有读写权限,而组用户和其他用户只有读权限。 例如,为每个人赋予一个文件的执行权限,使用chmod a+x 命令。a 表示所有人,加号(+) 表示添加,而x 表示执行。同样地,如果应用程序是一个服务器服务,您应该确保只有授权帐户才有权执行此服务。 如果一个应用程序能够在标准用户帐户权限下运行,但只有特定组中的用户才需要使用它,您可以将该组所有者权限设置为可执行,然后将这些用户添加到该组中。 更具体地说,您可以在一个可执行文件中设置访问控制列表(ACL) 权限,赋予特定用户或组权限来运行该应用程序。使用setfacl 实用工具设置ACL 权限。 对于这些需要以root 用户启动进程的应用程序,比如服务器服务,您有几个选择。总结了允许用户执行需要root 权限的服务器服务的各种选项。 选项描述 作为root 用户不推荐用于服务器服务。当用户已经知道root 密码而且应用程序泄露不是首要关注问题时,可用于应用程序。 SetUID 由于安全问题,不推荐使用。SetUID 允许标准用户以另一个用户方式,比如root 用户,执行一个文件。 sudo 很常用,并且被认为是一个很好的实践。sudo 授予一个用户或组成员权限以执行可能额外需要root 权限的文件。该用户不需要知道root 密码。 带有文件权限的标准用户帐户在一个文件上为用户所有者、组所有者或其他人(所有人)

嵌入式Linux系统

10-1 嵌入式Linux系统概述 嵌入式系统是以应用为中心,以计算机技术为基础,软硬件可裁剪,适用于应用系统,对功能、可靠性、成本、体积、功耗等方面有特殊要求的专用计算机系统。 Linux在所有的操作系统中,Linux 是一个发展最快、应用最为广泛的操作系统。 所谓嵌入式Linux,是指Linux 在嵌入式系统中应用,而不是什么嵌入式功能。实际上,嵌入式Linux 和Linux 是同一件事。 10-2 Linux启动过程综述 一. Bootloader 二.Kernel引导入口 三.核心数据结构初始化--内核引导第一部分 四.外设初始化--内核引导第二部分 五.init进程和inittab引导指令 六.rc启动脚本 七.getty和login 八.bash 附:XDM方式登录 Bootloader 简单地说,BootLoader就是在操作系统内核运行之前运行的一段小程序。通过这段小程序,我们可以初始化硬件设备、建立内存空间映射图,从而将系统的软硬件环境带到一个合适状态,以便为最终调用操作系统内核准备好正确的环境。在嵌入式系统中,通常并没有像BIOS那样的固件程序(注,有的嵌入式CPU也会内嵌一段短小的启动程序),因此整个系统的加载启动任务就完全由BootLoader来完成。 在Alpha/AXP平台上引导Linux通常有两种方法,一种是由MILO及其他类似的引导程序引导,另一种是由Firmware直接引导。MILO功能与i386平台的LILO相近,但内置有基本的磁盘驱动程序(如IDE、SCSI等),以及常见的文件系统驱动程序(如ext2,iso9660等),firmware有ARC、SRM两种形式,ARC具有类BIOS界面,甚至还有多重引导的设置;而SRM

嵌入式Linux应用软件开发流程

从软件工程的角度来说,嵌入式应用软件也有一定的生命周期,如要进行需求分析、系统设计、代码编写、调试和维护等工作,软件工程的许多理论对它也是适用的。 但和其他通用软件相比,它的开发有许多独特之处: ·在需求分析时,必须考虑硬件性能的影响,具体功能必须考虑由何种硬件实现。 ·在系统设计阶段,重点考虑的是任务的划分及其接口,而不是模块的划分。模块划分则放在了任务的设计阶段。 ·在调试时采用交叉调试方式。 ·软件调试完毕固化到嵌入式系统中后,它的后期维护工作较少。 下面主要介绍分析和设计阶段的步骤与原则: 1、需求分析 对需求加以分析产生需求说明,需求说明过程给出系统功能需求,它包括:·系统所有实现的功能 ·系统的输入、输出 ·系统的外部接口需求(如用户界面) ·它的性能以及诸如文件/数据库安全等其他要求 在实时系统中,常用状态变迁图来描述系统。在设计状态图时,应对系统运行过程进行详细考虑,尽量在状态图中列出所有系统状态,包括许多用户无需知道的内部状态,对许多异常也应有相应处理。 此外,应清楚地说明人机接口,即操作员与系统间地相互作用。对于比较复杂地系统,形成一本操作手册是必要的,为用户提供使用该系统的操作步骤。为使系统说明更清楚,可以将状态变迁图与操作手册脚本结合起来。

在对需求进行分析,了解系统所要实现的功能的基础上,系统开发选用何种硬件、软件平台就可以确定了。 对于硬件平台,要考虑的是微处理器的处理速度、内存空间的大小、外部扩展设备是否满足功能要求等。如微处理器对外部事件的响应速度是否满足系统的实时性要求,它的稳定性如何,内存空间是否满足操作系统及应用软件的运行要求,对于要求网络功能的系统,是否扩展有以太网接口等。 对于软件平台而言,操作系统是否支持实时性及支持的程度、对多任务的管理能力是否支持前面选中的微处理器、网络功能是否满足系统要求以及开发环境是否完善等都是必须考虑的。 当然,不管选用何种软硬件平台,成本因素都是要考虑的,嵌入式Linux 正是在这方面具有突出的优势。 2、任务和模块划分 在进行需求分析和明确系统功能后,就可以对系统进行任务划分。任务是代码运行的一个映象,是无限循环的一段代码。从系统的角度来看,任务是嵌入式系统中竞争系统资源的最小运行单元,任务可以使用或等待CPU、I/O设备和内存空间等系统资源。 在设计一个较为复杂的多任务应用系统时,进行合理的任务划分对系统的运行效率、实时性和吞吐量影响都极大。任务分解过细会不断地在各任务之间切换,而任务之间的通信量也会很大,这样将会大大地增加系统的开销,影响系统的效率。而任务分解过粗、不够彻底又会造成原本可以并行的操作只能按顺序串行执行,从而影响系统的吞吐量。为了达到系统效率和吞吐量之间的平衡折中,在划分任务时应在数据流图的基础上,遵循下列步骤和原则:

Linux2 进程的启动方式

Linux2 进程的启动方式 程序或者命令的执行实际上是通过进程实现的。通常情况下,程序或者命令是保存在硬盘上的,当在命令行中输入一个可执行程序的文件名或者命令并按下Enter 键后,系统内核就将该程序或者命令的相关代码加载到内存中开始执行。系统会为该程序或者命令创建一个或者多个相关的进程,通过进程完成特定的任务。启动进程的方式有两种,分别为前台启动方式和后台启动方式。 1.以前台方式启动进程 在终端窗口的命令行上输入一个Linux命令并按Enter键,就是以前台方式启动了一个进程。例如,在终端窗口上执行“find /-name myfile.txt”命令,就以前台方式启动了一个进程,在该进程还未执行完时,可按下Ctrl+z组合键将该进程暂时挂起,然后使用ps命令查看该进程的有关信息,如图5-1所示。 图5-1 以前台方式启动进程 2.以后台方式启动进程 要在命令行上以后台方式启动进程,需要在执行的命令后添加一个“&”。例如,在终端窗口的命令行上输入命令“find / -name myfile2.txt &”并按下Enter键后将从后台启动一个进程。启动后,系统会显示如下所示的信息: 这里的数字2表示该进程是运行于后台的第2个进程,数字3516是该进程的PID(即进程标识码,用于惟一地标识一个进程)。 然后,出现了shell提示符,这表示已返回到前台。这时,执行ps命令将能够看到现在在系统中有两个由find命令引起的进程,它们的标识号是不同的,因而是两个不同的进程,其中,PID为3385的进程就是刚才被挂起的进程。 如果执行jobs命令可以查看当前控制台中的后台进程,如图5-2所示,可以看到当前在后台有两个进程,其中一个处于运行(Running)状态,另一个,即被挂起的进程处于停止(Stopped)状态。等过一段时间后再使用ps命令进行查看,会发现PID为3516的进程已经结束了,而PID为3385的进程还存在。

基于嵌入式linux的bsp概念与开发

引言 Linux诞生于1991年,芬兰学生LinuSTorvaldS是Linux操作系统的缔造者,与传统的操作系统不同,Linux操作系统的开发一开始就在FSF(自由软件基金会组织)的GPL(GNU Public License)的版本控制之下,Linux内核的所有源代码都采取了开放源代码的方式。Linux具有相当多的优点。 BSP(Board Support Packet——板级支持包)是介于底层硬件和上层软件之间的底层软件开发包,其主要功能为屏蔽硬件,提供操作系统的引导及硬件驱动。Linux操作系统目前已发展为主流操作系统之一,并且还在不断的壮大和发展。 最新的2.6版内核增加了很多新特性为嵌入式应用提供广泛的支持,使得它不仅可以应用于大型系统,还可以应用于像PDA这类超小型系统中。随着Linux系统在嵌入式领域的广泛应用,对它的研究也在逐渐成为热点并且走向成熟。 在嵌入式系统开发过程中,板级支持包(BSP,BoardSuport Package)的开发已成为非常重要的环节。本文以Linux系统上的BSP技术为研究内容,讨论了BSP的基本概念和设计思想,特别针对Linux系统上BSP的层次结构、各功能模块的实现技术做了详细分析。 通过分析PC机的BIOS技术阐述了嵌入式系统中板级初始化流程和技术重点,并从源代码分析入手详细分析了PC机GURB引导程序设计技术,提出了嵌入式系统上BootLoader的程序结构和设计思想。 嵌入式操作系统对设备驱动程序的管理技术是BSP设计的重要组成部分。本文对比了Linux2.4和Linux2.6的设备驱动程序框架,同时结合大量源代码的研读,对Linux2.6内核的统一设备模型进行了深入的研究,剖析了内核对象机制的主要数据结构及驱动程序设计框架,理解了该模型对设备类的抽象机制,并在实际的项目实践中,结合所作的研究工作,圆满完成了基于ARM+Linux开发平台的BSP开发任务。 最后对本文研究工作进行了总结,并对下一步工作进行了展望。

嵌入式LINUX系统的实现

嵌入式LI N UX系统的实现 检修厂 王小康 摘 要 嵌入式系统正变得越来越流行。被广泛地应用在各种网络设备、控制设备以及个人的数字工具如PDA中。文章论述了作者在嵌入式操作系统领域里所做的研究和实践工作,主要的工作围绕着将L i nux改造成嵌入式操作系统所进行的具体工作展开,包括单板配置代码,系统的引导与修改,核心映象定制与修改和调试工作。 1 引言 在当今数字信息技术、网络技术高速发展与发达的后PC时代,嵌入式系统无处不在,并将不断涌现出新的嵌入式应用系统。传统的操作系统软件[1][2]很难有效地支持嵌入式应用系统的快速开发,因而研究与开发嵌入式操作系统,对有效的支持广大的嵌入式应用系统开发具有重大意义,是十分必要的。L i n ux正在向嵌入式领域的各个方面进军,在不久的将来,我们可以发现嵌入式L i n ux的广泛的应用:各种车载嵌入式设备(GPS,电子地图)、消费电子设备、手持电脑(H PC,PDA)、蜂窝电话、Internet接入设备、工控设备以及各种网络的基础设施(网管设备,路由,网关,交换器,HUB等)[3]。 本文是围绕着嵌入式L i n ux系统的实现展开的。首先介绍嵌入式L i n ux系统的硬件结构和软件结构;然后对基于L i n ux的嵌入式实时操作系统的实现过程进行详细的阐述;最后是简短的总结。 2 嵌入式L inux系统的硬件结构 嵌入式L i n ux系统硬件系统是个微形化的专用PC,它包括系统主机扳、通讯接口板、图象处理和显示板、输入控制板以及存储板等。主机板可采用嵌入式X86CPU系列,图象处理和显示板能支持MPEG数字解压缩和电视终端显示,输入控制包括遥控键盘、遥控器和其他一些输入设备接口,存储板主要 要求。 7 设计报警和连锁保护系统 报警系统的作用在于及时提醒操作人员密切注意监视生产状况,以便采取措施减少事故的发生,连锁保护系统是指当生产出现严重事故时,为保证设备和人身的安全,使各个设备按一定次序紧急停下来。在焙烧炉的炉顶温度控制中,根据工艺要求,一个高限报警温度为480度;三个连锁保护温度设定,一个超高限报警温度自动连锁烧嘴,引起烧嘴自动熄火,从而立即引起调节阀的自动关闭,防止煤气流入焙烧炉,一个低限位报警温度用来连锁模式的切换,使模式从酸模式自动切换到水模式,另一个超低限位报警温度用来连锁三个喷枪,使得三个喷枪自动从焙烧炉提升出来,从而保护喷枪。 8 控制系统的调试和运行状况 控制系统安装完成后,应随生产过程进行试运行,按控制要求检查和调整各控制仪表和设备的工作状况,包括调节器的P、I等参数整定,依次将全部控制系统投入运行,在从投入运行到现在有半年多的时间了,发现焙烧炉的炉顶温度控制效果好,系统运行比较稳定。 20

linux grub 引导启动过程详解

linux grub 引导启动过程详解 2008-01-08 17:18 这几天看了很多文档,算是对linux的启动过程有了比较细致的了解. 网上有很多文章谈到这方面的内容,但总觉得没有一篇完全的解析linux启动的 细节,下面是我小弟在学习的过程中总结出来的一些东东.这个是完整的linux启动过程, 不涉及内核,但是我觉得比较详细哦. (由于本人比较懒,这一段是从网上抄的) 机器加电启动后,BIOS开始检测系统参数,如内存的大小,日期和时间,磁盘 设备以及这些磁盘设备用来引导的顺序,通常情况下,BIOS都是被配置成首先检查 软驱或者光驱(或两者都检查),然后再尝试从硬盘引导。如果在这些可移动的设 备中,没有找到可引导的介质,那么BIOS通常是转向第一块硬盘最初的几个扇区, 寻找用于装载操作系统的指令。装载操作系统的这个程序就是boot loader. linux里面的boot loader通常是lilo或者grub,从Red Hat Linux 7.2起,GRUB( GRand Unified Bootloader)取代LILO成为了默认的启动装载程序。那么启动的时候grub是如何被载入的呢 grub有几个重要的文件,stage1,stage2,有的时候需要stage1.5.这些文件一般都 在/boot/grub文件夹下面.grub被载入通常包括以下几个步骤: 1. 装载基本的引导装载程序(stage1),stage1很小,网上说是512字节,但是在我的系统上用du -b /boot/grub/stage1 显示的是1024个字节,不知道是不是grub版本不同的缘故还是我理解有误.stage1通常位于主引导扇区里面,对于硬盘就是MBR了,stage1的主要功能就是装载第二引导程序(stage2).这主要是归结于在主引导扇区中没有足够的空间用于其他东西了,我用的是grub 0.93,stage2文件的大小是107520 bit. 2. 装载第二引导装载程序(stage2),这第二引导装载程序实际上是引出更高级的功能, 以允许用户装载入一个特定的操作系统。在GRUB中,这步是让用户显示一个菜单或是输入命令。由于stage2很大,所以它一般位于文件系统之中(通常是boot所在的根 分区). 上面还提到了stage1.5这个文件,它的作用是什么呢你到/boot/grub目录下看看, fat_stage_1.5 e2fs_stage_1.5 xfs_stage_1.5等等,很容易猜想stage1.5和文件系统 有关系.有时候基本引导装载程序(stage1)不能识别stage2所在的文件系统分区,那么这 时候就需要stage1.5来连接stage1和stage2了.因此对于不同的文件系统就会有不同的stage1.5.但是对于grub 0.93好像stage1.5并不是很重要,因为我试过了,在没有stage1.5 的情况下, 我把stage1安装在软盘的引导扇区内,然后把stage2放在格式化成ext2或者fat格式的软盘内,启动的时候照常引导,并不需要e2fs_stage_1.5或者fat_stage_1.5. 下面是我的试验: #mkfs.ext2 /dev/fd0 #mount -t ext2 /dev/fd0 /mnt/floppy #cd /mnt/floppy #mkdir boot #cd boot #mkdir grub (以上三步可用mkdir -p boot/grub命令完成) #cd grub #cp /boot/grub/{stage1,stage2,grub.conf} ./ #cd; umount /mnt/floppy

嵌入式LINUX开发工具选择

嵌入式Linux具有稳定、可伸缩及开放源代码等特点,可兼容多 种处理器和主机,广泛适用于各种产品和应用。但是,交叉编译、 设备驱动程序开发/调试,以及更小尺寸等要求对嵌入式Linux开 发者来说都是严峻的挑战。为应对这些挑战,针对嵌入式Linux开 发的专用工具应运而生,而且发展十分迅猛。 但是,许多这类开发工具都不兼容非X86平台,而且也没有很好 地实现归档备案或集成。在其它开发环境下,组件间的高度集成并 没有完全兑现。因此,要想完全从这些免费的软件组件开始创建 一个完整的跨平台开发环境,开发者应意识到这将需要大量的调 研、实施、培训和维护方面的工作。 Linux 是少数既可以在嵌入式设备上运行也可作为开发环境的操 作系统之一。这一特性可让开发者在转向此开发系统之前于常用硬 件(比如X86桌面系统)之上开发、调试和测试应用程序和库,因 此可减少对标准参考平台和指令集仿真器的依赖。这一技术仅适用于应用程序和库,但不适用于设备驱动程序,因为后者的开发依赖于 Linux架构。 开放源代码团体及一些软件供应商可提供设备驱动程序开发工具。由于设备驱动程序比标准应用程序距离硬件更近,因此它们的开发比较困难。所幸的是,Linux 桌面系统可以利用一些Windows及其它操作系统所没有的工具。有足够经验开发设备驱动程序的开发人员可能已经习惯将Linux作为他们的桌面开发系统了。 Linux的快速发展及其桌面方案的不断涌现提出了一个重要问题:所选择的工具方案怎样在不同的Linux分布式系统上运行?它们依赖于主机平台的软件配置吗? 有些Linux工具提供独立于主机平台的开发环境,包括一系列可支持开发工具的应用软件、库和实用程序。这一方法几乎将开发环境与主机配置完全隔离开来,因此主机可以是任何Linux分布式系统,而且任何更新和修改都不会影响开发环境的功能。 这种方法的主要缺点是对存储空间的要求有所增加――约200MB,因为它自己实际上相当于一个微型Linux分布式系统。 可用的工具 一个嵌入式Linux产品的开发需要几个阶段,包括为目标板配置和构建基本Linux OS;调试应用程序、库、内核及设备驱动程序/内核模块;出货前最终方案的优化、测试和验证。 有数百种开放源代码开发工具可供选择。只要开发者原意花时间和精力去调研、实施和维护一系列各不相同的工具,总能找出一个完整的解决方案,完成几乎任何开发任务。

Linux启动过程详解

深入浅出:Linux的启动流程刨析 Linux的启动过程,是一个Linuxer必须要熟练掌握的。通过系统的启动过程,可以更深入的理解Linux,假如Linux系统出问题的话,可以通过启动过程来分析原因,解决问题。而且,在掌握了Linux的启动流程后,还可以借助宿主机来打造自己的Linux。 下面是我画的一张简单的Linux启动流程图 在了解启动流程之前,我们应该先知道系统的几个重要脚本和配置文件,他们对应的路径为: 1、/sbin/init 2、/etc/inittab 3、/etc/rc.d/rc.sysinit 4、/etc/rc.d/rcN.d //这是几个文件夹N代表数字1,2,3,4.. 5、/etc/fstab 1、关于/sbin/init与/etc/inittab 关于/sbin/init ,它是一个二进制可执行文件,为系统的初始化程序,而/etc/inittab是它的配置文件,我们可以通过/etc/inittab来一睹它的功能,里面的内容是一种固定的文本格式,id:runlevels:action:process 我们来通过它的内容来学习它之前,先了解写运行级别的分类(0-6): 0:关机half

1:单用户模式singel user 2:多用户模式multi user ,不提供nfs服务without nfs 3:完全多用户字符模式full multiuser text mod 4:系统预留officially undefined 5:图形登录界面graphical login 6:重启reboot id:3:initdefault: //这里定义linux的启动时的运行级别,可以看到我的主机的启动级别是3 # System initialization. si::sysinit:/etc/rc.d/rc.sysinit //紧接着,运行系统第一个脚本/etc/rc.d/rc/sysinit //它的action:sysyinit指的是定义系统初始化过程 l0:0:wait:/etc/rc.d/rc 0 l1:1:wait:/etc/rc.d/rc 1 l2:2:wait:/etc/rc.d/rc 2 //然后就是加载服务了,他们被定义在/etc/rc.d/rcN.d l3:3:wait:/etc/rc.d/rc 3 //action:waite 这个进程在在对应级别启动一次,知道它结束为止,我的系统启动级别为3,所有执行rc 3对应的服务 l4:4:wait:/etc/rc.d/rc 4 l5:5:wait:/etc/rc.d/rc 5 l6:6:wait:/etc/rc.d/rc 6 ca::ctrlaltdel:/sbin/shutdown -t3 -r now //这里定义了一个组合快捷键,熟悉吧,没错就是重启,你可以把它注释掉不用 pf::powerfail:/sbin/shutdown -f -h +2 "Power Failure; System Shutting Down"//这里定义了ups电源,powerfail 指的是如果突然断电,它对应的process命令是,提示用户系统电源失效,将要关机,提醒用户把数据都存储好 pr:12345:powerokwait:/sbin/shutdown -c "Power Restored; Shutdown Cancelled"//这里的action,powerokwaite,指的是系统恢复供电,关机取消...

 1:2345:respawn:/sbin/mingetty tty1 //开启终端,在系统准备工作做好后,就会启动出6个终端,tty1~6 mingetyy就是终端的执行命令 2:2345:respawn:/sbin/mingetty tty2 //可以看到他们对应的级别是2345,你也可以注释

基于嵌入式Linux的汉字输入法

基于嵌入式Linux的汉字输入法 An Approach to Chinese Input based on Embedded Linux Abstract: The Chinese input problem is essential to an embedded system. An approach to on-line recognition of handwritten Chinese stroke is proposed., including its realization in embedded system. Keywords: handwritten Chinese character recognition; on-line recognition; dynamic recognition; embedded system 摘要:汉字输入法是嵌入式系统输入的一项重要技术,它的功能与性能直接影响到嵌入式系统在中国的推广与应用。主要研究了联机汉字手写体输入法,以及在嵌入式系统中实现汉字手写体输入法。 关键词:手写体识别;联机识别;动态识别;嵌入式系统; .1 引言 在信息时代,嵌入式系统如个人数字助理(PDA)、JAVA手机、人工智能电器等已广泛渗入人们的日常工作和生活中。由于受到键盘大小和按键数目的限制,汉字输入是影响嵌入式系统使用的重要因素。具有强烈人性化的手写汉字输入是解决嵌入式系统汉字输入问题的最佳方法之一。随着硬件成本的降低和汉字手写体识别技术的提高,汉字手写识别在嵌入式系统的应用将会日益广泛。 嵌入式系统是硬件资源受限系统,所以汉字手写体识别应考虑到嵌入式系统这个特点。其中比较重要的是,嵌入式系统的硬件配置低,除了考虑汉字识别的识别率外,还必须考虑输入的速度。手写汉字的输入时间包括书写时间和识别时间两部分,一般以前者所耗时间较多。当前市面上融合嵌入式手写汉字输入法的产品如PDA、智能手机、智能数码相机等几乎都在整个汉字书写完毕后才出现识别结果,所以即使系统的识别速度很快,也需要把整个汉字写完,因此整体的输入速度始终没有质的提高。针对上述问题,本文提出了一种基于汉字笔顺的联机动态手写汉字识别方法,在人们书写汉字的过程中,对其已经书写的部分汉字笔划进行动态识别,预测其想要书写的汉字并输出给用户选择,并且集成弹性网格特征法,以达到在保证识别率的前提下提高整体输入速度目的。本文主要进行以下几项工作:

嵌入式Linux系统开发教程很完整的习题答案

嵌入式Linux系统开发教程很完整的习题答案

参考答案 第一章 一、填空题。 1、嵌入式系统主要融合了计算机软硬件技术、通信技术和微电子技术,它是将计算机直接嵌入到应用系统中,利用计算机的高速处理能力以实现某些特定的功能。 2、目前国内对嵌入式系统普遍认同的定义是:以应用为中心、以计算机技术为基础、软硬件可裁剪、适应应用系统对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统。 3、嵌入式系统一般由嵌入式计算机和执行部件组成,其中嵌入式计算机主要由四个部分组成,它们分别是:硬件层、中间层、系统软件层以及应用软件层。 4、嵌入式处理器目前主要有ARM、MIPS、Power PC、68K等,其中arm处理器有三大特点:体积小、低功耗、的成本和高性能,16/32位双指令集,全球合作伙伴众多。 5、常见的嵌入式操作系统有:Linux、Vxworks、WinCE、Palm、uc/OS-II和eCOS。 6、嵌入式系统开发的一般流程主要包括系统需求分析、体系结构设计、软硬件及机械系统设计、系统集成、系统测试,最后得到最终产品。 二、选择题 1、嵌入式系统中硬件层主要包含了嵌入式系统重要的硬件设备:、存储器(SDRAM、ROM等)、设备I/O接口等。(A) A、嵌入式处理器 B、嵌入式控制器 C、单片机 D、集成芯片 2、20世纪90年代以后,随着系统应用对实时性要求的提高,系统软件规模不断上升,实时核逐渐发展为,并作为一种软件平台逐步成为目前国际嵌入式系统的主流。(D) A、分时多任务操作系统 B、多任务操作系统 C、实时操作系统 D、实时多任务操作系统 3、由于其高可靠性,在美国的火星表面登陆的火星探测器上也使用的嵌入式操作系统是。(B) A、Palm B、VxWorks C、Linux D、WinCE [在此处键入]

基于嵌入式Linux系统的3G4G路由器设计

[导读] 3G的接人技术已经从WCDMA/TD- SCDMA/CD-MA2000发展到HSDPA、HSUPA 以及HSPA+ ,并开始由3G 网络向4G网络过渡。 3G的接人技术已经从WCDMA/TD- SCDMA/CD-MA2000发展到HSDPA、HSUPA 以及HSPA+ ,并开始由3G 网络向4G网络过渡。目前HSDPA的接入带宽可以达到7.2 Mbps,HSPA+ 的接人带宽可以达到21 Mbps,而即将部署的LTE的网络带宽甚至达到了100 Mbps 。同时,由于接人移动互联网的智能终端的数量快速增长,人们对移动互联网的应用需求也日益增长。当人们面对几十兆带宽甚至是上百兆带宽时,必定存在带宽的过剩问题,即人们不需要在任何时刻都需要这么大的带宽,因而可以将过剩的用户带宽分配给更多的用户。 目前,WiFi技术能够支持IEEE的802.11b、802.11g和802.1ln标准,分别支持10 Mbps、54 Mbps和300 Mbps的无线传输速率。而在传输距离上,WiFi能够在几米到100m范围内实现完全覆盖。 本文正是基于3G/4G 不断增长的接入带宽以及WiFi技术的各项优点,提出了一种共享3G/4G 网络带宽的无线路由器设计方案。该方案首先利用嵌入式Linux系统,构建一个基于WiFi技术的无线局域网,智能终端等用户可以利用自带的WiFi功能接入该无线局域网,然后再将该无线局域网桥接至3G/4G网络中,从而实现各个智能终端设备对3G/4G网络带宽的共享。 1. 3G/4G路由器设计方案 本路由器的设计是基于三个模块来实现的,分别为3G模块、WiFi模块和Linux硬件平台,如图1所示。3G模块的功能是利用运营商的无线数据卡进行PPP拨号,使得路由器能通过运营商网络连接至互联网。WiFi模块的功能是使得无线网卡工作在AP(Access Point)模式,并配置动态主机配置协议的脚本文件,来建立一个2.4 GHz的WiFi无线局域网。Linux硬件平台模块的功能主要有两个方面,一方面要支持无线网卡和无线数据卡的驱动,另一方面要通过嵌入式Linux系统中的iptables数据包过滤系统将无线局域网和3G/4G网络连通。智能终端等设备通过WiFi信道接人到该路由器所提供的无线局域网中,分配到一个IP地址之后,则通过该无线局域网的网关进行数据包的接收和发送,而该网关则通过3G/4G模块上的网络拨号接口来接收和发送数据包至3G/4G 网络,从而实现了该路由器的设计方案。 图1 3G/4G路由器设计方案图 2. 3G/4G路由器硬件结构 根据3G/4G路由器设计方案,其硬件结构的三大模块分别采用深圳天谟公司生产的Devkit8500D评估板、华为公司的E392型无线上网卡和TP-Link公司的TL-WN821N型无线网卡。 Devkit8500D评估板的基本结构如图2所示。该硬件平台采用的是TI公司的DM3730微处理器。

相关文档
相关文档 最新文档