ImageVerifierCode 换一换
格式:DOC , 页数:79 ,大小:1.84MB ,
资源ID:9997722      下载积分:16 金币
验证码下载
登录下载
邮箱/手机:
图形码:
验证码: 获取验证码
温馨提示:
支付成功后,系统会自动生成账号(用户名为邮箱或者手机号,密码是验证码),方便下次登录下载和查询订单;
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

开通VIP
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.zixin.com.cn/docdown/9997722.html】到电脑端继续下载(重复下载【60天内】不扣币)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

开通VIP折扣优惠下载文档

            查看会员权益                  [ 下载后找不到文档?]

填表反馈(24小时):  下载求助     关注领币    退款申请

开具发票请登录PC端进行申请。


权利声明

1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:4009-655-100;投诉/维权电话:18658249818。

注意事项

本文(嵌入式系统开发基础—基于ARM微处理器和Linux操作系统的课后答案.doc)为本站上传会员【精****】主动上传,咨信网仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知咨信网(发送邮件至1219186828@qq.com、拔打电话4009-655-100或【 微信客服】、【 QQ客服】),核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载【60天内】不扣币。 服务填表

嵌入式系统开发基础—基于ARM微处理器和Linux操作系统的课后答案.doc

1、嵌入式系统开发基础—基于ARM微处理器和Linux操作系统的课后答案(全面完整版) (可以直接使用,可编辑 全面完整版资料,欢迎下载) 1-1 什么是嵌入式系统?嵌入式系统和普通计算机系统的区别是什么?举例说明。 答: 问题一:嵌入式系统是以应用为中心,以计算机为基础,其软硬件可裁剪配置,对功能、可靠性、成本、体积、功耗有严格约束的一种专用计算机系统。 问题二: 比较项目 嵌入式系统 普通计算机系统 引导代码 BootLoader引导,针对不同电路进行移植 主板的BIOS引导 OS WindowsCE、VxWorks、Linux等,需要移植 Windows、Linu

2、x,不移植 驱动程序 每个设备都必须针对电路板进行开发 OS中含有大多数,直接下载 协议栈 移植 OS或者第三方供应商提供 开发环境 借助服务器进行交叉编译 在本机可开发调试 仿真器 需要 不需要 1-2 简述嵌入式系统的构成 答: 硬件 微处理器 嵌入式系统的控制核心 外围电路 嵌入式系统的内存、I/O端口、复位电路、电源等 外设 USB、LCD、键盘等 软件 设备驱动接口 负责嵌入式系统与外设的信息交互 实时操作系统 包括与硬件相关的底层软件、系统内核、设备驱动接口、通信协议、图形界面、标准化浏览器等 可编程应用接口 为编制应用程

3、序提供各种编程接口库 应用软件 1-3 答:R13:也记作SP,在ARM指令集中虽然没有强制,但是通常用于堆栈指针SP;在Thumb指令集中强制其作为堆栈指针。 R14:也记作程序连接寄存器LR(Link Register),用于保存子程序调用或异常中断处理返回时程序的返回地址。 R15:也记作程序计数器PC,用于标示下一条将要执行的指令地址。 CPSR:程序状态寄存器,包含条件标识位、中断标识位、当前处理器模式等状态和控制位。 SPSR:备份的程序状态寄存器。在异常中断处理过程中,用于保存被中断处理程序的执行现场和处理器状态。 1-4 答:(1)复位异常中断:当

4、系统上电、复位、软件复位时产生该类型中断。 (2)未定义指令异常中断:当ARM处理器或系统中的协处理器认为当前指令未定义时,产生该中断。通常利用该中断模拟浮点向量运算。 (3)软件中断:可用于用户模式下特权操作的调用,既可以是系统功能,也可以是用户自定义的功能。 (4)指令预取中止异常中断:如果处理器预取的指令地址不存在,或者该地址不允许当前指令访问,产生该类型的中断。 (5)数据访问中止异常中断:如果数据访问的目标地址不存在,或者该地址不允许当前指令访问,则产生该中断。 (6)外部中断:当处理器的外部中断请求引脚有效,而且CPSR的I控制位被清除时,产生该类型的中断

5、7)快速外部中断:当处理器的快速中断请求引脚有效,而且CPSR的F控制位被清除时,产生该中断。 1-5 答:(1)ADR R0, TABLE (2) ADR R1, DATA LDR R0, [R1] (3) LDR R0, =DATA (4) TABLE EQU 800 MOV R0, #TABLE (5) TABLE SPACE 20 1-6 答: R0=DATA1这组数据在存储器中所存放的起始地址,由编译器分配; R1=0x0C0D0E0F; R2=0xF; R3=0x8 ; [0x8 ]=R1 1-7 答: AREA

6、SWITCH, CODE, READONLY ENTRY AND R2, R0, 0x3 ;R2ß R0的低两位 MOV R2, R2, LSL #30 ;将低两位移动到高两位 BIC R0, R0, 0x3 ;将R0的低两位清0 AND R3, R1, 0xC0000000 ;R3ßR1的高两位 MOV R3, R3, LSR #30 ;将高两位移动到低两位 BIC R1, R1, 0xC0000000 ;将R1的高两位清0 ORR R0, R0,R3 ;R1的高两位写入到R0的低两位 ORR R

7、1, R1, R2 ;R0的低两位写入到R1的高两位 END 1-8 答: // main.c Include “stdio.h” extern int sum (int num[], int n); main(){ int array[10]={20, 30, 23, 5,15,64,6,15,72,73 }; int HE=sum(array, 10); printf(“The sum of array is %d”, HE); } //huibian.s AREA ASM, CODE, READONLY EXPORT sum sum

8、 MOV R2, #0 LOOP LDR R3, [R0], #4 ADD R2, R2, R3 SUB R1, R1, 1 CMP R1, 0 BNE LOOP MOV R0, R2 MOV PC, LR END 1-9 答:(1)要求很强的实时性,支持快速而明确的上下文切换 (2)具有高度的可裁剪性,支持动态链接,能够通过装卸某些模块来达到系统所需要的功能 (3)具有快速有效的中断和异常处理能力 (4)具有优化的浮点支持 (5)能够进行动态的内存管理 2-1 略。 2-2 略 2-3略

9、2-4按照要求完成以下操作。 (1)创建文件夹test。 mkdir test (2)进入test目录。 cd test (3)在test目录下用Vi编辑一个新文件test.c,其内容如下: #include intmain() { int a,i=0; a=0; while(i<20) { a=a+3; printf("the value of a=%d \n",a); sleep(1); i=i+1; return 0; } } vi test.c (4)保存退出test.c。 (5

10、按照下面的要求编译test.c。 使用gcc -o test.o test.c编译,生成test.o。 使用gcc -g -o gtest.o test.c编译,生成gtest.o。 比较gtest.o 与 test.o的大小,哪个大?为什么? gtest.o 比 test.o 大,因为前者加入了一些调试信息。 (6)执行gtest.o与test.o。 2-5使用GDB调试上面的程序gtest.o。 (1)进入GDB调试环境,读入调试程序。 gdb gtest.o (2)列出源文件内容。 list (3)在程序a=0;处设置一个断点。 breakpoint (

11、4)在程序printf("the value of a=%d \n",a);处设置一个断点。 (5)执行该程序。 run (6)查看变量a的值。 print a (7)查看变量a的类型。 (8)执行下一个源程序行,从而执行其整体中的一个函数。 (9)从断点开始继续执行到下一个断点。 (10)查看变量a的值,看看a是否有变化? (11)不停地执行continue,直到程序结束。 (12)退出GDB。 2-6根据要求编写Makefile文件。 五个文件分别是main.c、display1.h、display1.c、display2.h、display2.c,具体的代码

12、如下: #include "stdio.h" int main(int argc,char **argv) { display1 ("hello");   display2("hello"); } display1.h void display1 (char *print_str); display2.h void display2 (char *print_str); display1.c #include "display1.h" void display1(char *print_str) { printf("This is display1 prin

13、t %sn",print_str); } display2.c #include "display2.h" void display2 (char *print_str) { printf("This is display2 print %sn",print_str); } (1)如果上述文件在同一个目录,请编写Makefile文件。 (2)如果按照下面的目录结构存放文件,请编写Makefile文件。 |---bin 存放生成的可执行文件 |---obj 存放.o文件 |---include 存放display1.h和display2.h文件 |---sr

14、c 存放main.c、display1.c、display2.c和Makefile (3)如果按照下面的目录结构存放文件,请编写Makefile文件。 |---bin 存放生成的可执行文件 |---obj 存放.o文件 |---include 存放display1.h和display2.h文件 |---src 存放main.c和Makefile |---src/display1 存放display1.c和Makefile |---src/display2 存放display2.c和Makefile src下面的makefile SRC_DIR=. IN

15、C_DIR=../include OBJ_DIR=../obj BIN_DIR=../bin include $(SRC_DIR)/test/makefile include $(SRC_DIR)/test1/makefile display1下面的makefile all:$(OBJ_DIR)/display1.o $(OBJ_DIR)/display1.o gcc -o $(BIN_DIR)/display1 $^ display2下面的makefile $(OBJ_DIR)/display2.o:$(SRC_DIR)/display2/display.c g

16、cc -c $< -o $@ 3-1 答: 1.建立宿主机开发环境,包括操作系统及编译器等 2.配置宿主机相关服务及软件,如minicom、网络等 3.建立引导加载程序BootLoader 4.移植内核kernel 5.建立根文件系统root 6.建立应用程序的Flash磁盘分区 7.开发应用程序 8.烧写内核、根文件系统和应用程序 9.发布产品 3-2 答: Stage1: (1)硬件设备初始化。 (2)为加载BootLoader的Stage2准备RAM空间。 (3)复制BootLoader的Stage2到RAM空间中。 (4)设置好堆栈。堆栈指针的

17、设置是为执行C语言代码做好准备。 Stage2: (1)初始化本阶段要使用到的硬件设备。 (2)检测系统内存映射(Memory Map)。 (3)将内核映像和根文件系统映像从Flash存储器上读到RAM空间中。 (4)为内核设置启动参数。 (5)调用内核。 3-3 答: 1. 数据结构file_operations 2.设备注册:驱动程序模块通过函数register_chrdev来完成内核的注册。 3.设备卸载:驱动程序模块通过函数unregister_chrdev来完成内核的卸载。 4.打开/释放设备:驱动程序通过函数open来完成设备的打开。驱动程序通过函数relea

18、se来完成设备的释放 5.读写设备:read函数将数据从内核复制到应用程序空间,write函数则将数据从应用程序空间复制到内核。 6.读写以外的I/O操作:驱动程序模块通过ioctl函数来完成读写以外的I/O操作,如锁设备等 3-4 答: (1)register_chrdev(0,”demo”,&demo_fops); (2)mknod /dev/demo c 220 0 (3)insmod demo.o 4-1参见exam4-1 4-2参见exam4-2 4-3参见exam4-3 5-1 略 5-2 略 5-3 C:\Qt\>sqlite3 exam.db

19、 SQLite version 3.5.4 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite> create table book(ID Integer primarykey,Name varchar(20),Type varchar(10 ),Count Integer); sqlite> insert into book values(1,'SQLite3','Database',10); sqlite> insert into book values(2,'Qt4'

20、'GUI',20); sqlite> select * from book; 1|SQLite3|Database|10 2|Qt4|GUI|20 sqlite> 5-4 #include #include int main() { sqlite3 *db=NULL; int rc; char *Errormsg; int nrow; int ncol; char **Result; int i=0; rc=sqlite3_open("exam.db",&db); if(rc){ fp

21、rintf(stderr,"can't open database:%s\n", sqlite3_errmsg(db)); sqlite3_close(db); return 1; }else printf("open database successly!\n"); char *sql="create table book(ID Integer primary key,Name varchar(20),Type varchar(10),Count Integer)"; sqlite3_exec(db,sql,0,0,&Errormsg); s

22、ql="insert into book values(1,'SQLite3','Database',10)"; sqlite3_exec(db,sql,0,0,&Errormsg); sql="insert into book values(2,'Qt4','GUI',20);"; sqlite3_exec(db,sql,0,0,&Errormsg); sql="select * from book"; sqlite3_get_table(db,sql,&Result,&nrow,&ncol,&Errormsg); printf("row=%d colum

23、n=%d\n",nrow,ncol); printf("the result is:\n"); for( i=0;i<(nrow+1)*ncol;i++) printf("Result[%d]=%s\n",i,Result[i]); sqlite3_free(Errormsg); sqlite3_free_table(Result); sqlite3_close(db); return 0; } 5-5 参见案例 6-1略 6-2略 6-3参见exam6-3。 6-4参见案例 Linux内核构成 (国嵌) Linux/arch/

24、arm/boot/compressed/head.s 1.解压缩 2.初始化 3.启动应用程序 1 arch/arm/boot/compressed/Makefile arch/arm/boot/compressed/vmlinux.lds 2. arch/arm/kernel/vmlinux.lds Linux内核启动流程 (国嵌) arch/arm/boot/compressed/start.S(head.s—负责解压缩) Start: .type start,#function .r

25、ept 8 mov r0, r0 .endr b 1f .word 0x016f2818 @ Magic numbers to help the loader .word start @ absolute load/run zImage address .word _edata @ zImage end address

26、1: mov r7, r1 @ save architecture ID mov r8, r2 @ save atags pointer 这也标志着u-boot将系统完全的交给了OS,bootloader生命终止。之后代码在133行会读取cpsr并判断是否处理器处于supervisor模式——从u-boot进入kernel,系统已经处于SVC32模式;而利用angel进入则处于user模式,还需要额外两条指令。之后是再次确认中断关闭,并完成cpsr写入

27、 mrs r2, cpsr @ get current mode tst r2, #3 @ not user? bne not_angel mov r0, #0x17 @ angel_SWIreason_EnterSVC swi 0x123456 @ angel_SWI_ARM not_angel:

28、 mrs r2, cpsr @ turn off interrupts to orr r2, r2, #0xc0 @ prevent angel from running msr cpsr_c, r2 然后在LC0地址处将分段信息导入r0-r6、ip、sp等寄存器,并检查代码是否运行在与链接时相同的目标地址,以决定是否进行处理。由于现在很少有人不使用loader和tags,将zImage烧写到rom直接从0x0位置执行,所以这个处理是必须的(

29、但是zImage的头现在也保留了不用loader也可启动的能力)。arm架构下自解压头一般是链接在0x0地址而被加载到0x30008000运行,所以要修正这个变化。涉及到 r5寄存器存放的zImage基地址 r6和r12(即ip寄存器)存放的got(global offset table) r2和r3存放的bss段起止地址 sp栈指针地址 很简单,这些寄存器统统被加上一个你也能猜到的偏移地址 0x30008000。该地址是s3c2410相关的,其他的ARM处理器可以参考下表 PXA2xx是0xa0008000 IXP2x00和IXP4xx是0x00008000

30、 Freescale i.MX31/37是0x80008000 TI davinci DM64xx是0x80008000 TI omap系列是0x80008000 AT91RM/SAM92xx系列是0x20008000 Cirrus EP93xx是0x00008000 这些操作发生在代码172行开始的地方,下面只粘贴一部分 add r5, r5, r0 add r6, r6, r0 add ip, ip, r0 后面在211行进行bss段的清零

31、工作 not_relocated: mov r0, #0 1: str r0, [r2], #4 @ clear bss str r0, [r2], #4 str r0, [r2], #4 str r0, [r2], #4 cmp r2, r3 blo 1b 然后224行,打开cache,并为后面解压缩设置64KB的临时malloc空间

32、 bl cache_on mov r1, sp @ malloc space above stack add r2, sp, #0x10000 @ 64k max 接下来238行进行检查,确定内核解压缩后的Image目标地址是否会覆盖到zImage头,如果是则准备将zImage头转移到解压出来的内核后面 cmp r4, r2 bhs wont_overwr

33、ite sub r3, sp, r5 @ > compressed kernel size add r0, r4, r3, lsl #2 @ allow for 4x expansion cmp r0, r5 bls wont_overwrite mov r5, r2 @ decompress after malloc space mov

34、 r0, r5 mov r3, r7 bl decompress_kernel 真实情况——在大多数的应用中,内核编译都会把压缩的zImage和非压缩的Image链接到同样的地址,s3c2410平台下即是0x30008000。这样做的好处是,人们不用关心内核是Image还是zImage,放到这个位置执行就OK,所以在解压缩后zImage头必须为真正的内核让路。 在250行解压完毕,内核长度返回值存放在r0寄存器里。在内核末尾空出128字节的栈空间用,并且使其长度128字节对齐。 add

35、 r0, r0, #127 + 128 @ alignment + stack bic r0, r0, #127 @ align the kernel length 算出搬移代码的参数:计算内核末尾地址并存放于r1寄存器,需要搬移代码原来地址放在r2,需要搬移的长度放在r3。然后执行搬移,并设置好sp指针指向新的栈(原来的栈也会被内核覆盖掉) add r1, r5, r0 @ end of decompressed kernel adr

36、r2, reloc_start ldr r3, LC1 add r3, r2, r3 1: ldmia r2!, {r9 - r14} @ copy relocation code stmia r1!, {r9 - r14} ldmia r2!, {r9 - r14} stmia r1!, {r9 - r14} cmp

37、 r2, r3 blo 1b add sp, r1, #128 @ relocate the stack 搬移完成后刷新cache,因为代码地址变化了不能让cache再命中被内核覆盖的老地址。然后跳转到新的地址继续执行 bl cache_clean_flush add pc, r5, r0 @ call relocation code 注意——zImage在解压后的搬移和跳转会给gdb调试内核带

38、来麻烦。因为用来调试的符号表是在编译是生成的,并不知道以后会被搬移到何处去,只有在内核解压缩完成之后,根据计算出来的参数“告诉”调试器这个变化。以撰写本文时使用的zImage为例,内核自解压头重定向后,reloc_start地址由0x30008360变为0x30533e60。故我们要把vmlinux的符号表也相应的从0x30008000后移到0x30533b00开始,这样gdb就可以正确的对应源代码和机器指令。 随着头部代码移动到新的位置,不会再和内核的目标地址冲突,可以开始内核自身的搬移了。此时r0寄存器存放的是内核长度(严格的说是长度外加128Byte的栈),r4存放的是内核的目的地

39、址0x30008000,r5是目前内核存放地址,r6是CPU ID,r7是machine ID,r8是atags地址。代码从501行开始 reloc_start: add r9, r5, r0 sub r9, r9, #128 @ do not copy the stack debug_reloc_start mov r1, r4 1: .rept 4 ldmia

40、 r5!, {r0, r2, r3, r10 - r14} @ relocate kernel stmia r1!, {r0, r2, r3, r10 - r14} .endr cmp r5, r9 blo 1b add sp, r1, #128 @ relocate the stack 接下来在516行清除并关闭cache,清零r0,将machine ID存入r1,atags指针存入r2,再

41、跳入0x30008000执行真正的内核Image call_kernel: bl cache_clean_flush bl cache_off mov r0, #0 @ must be zero mov r1, r7 @ restore architecture number mov r2, r8 @ restore atags poi

42、nter mov pc, r4 @ call kernel 内核代码入口在arch/arm/kernel/head.S文件的83行。首先进入SVC32模式,并查询CPU ID,检查合法性 msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode @ and irqs disabled mrc p15, 0,

43、r9, c0, c0 @ get processor id bl __lookup_processor_type @ r5=procinfo r9=cpuid movs r10, r5 @ invalid processor (r5=0)? beq __error_p @ yes, error 'p' 接着在87行进一步查询machine ID并检查合法性 bl __lookup_m

44、achine_type @ r5=machinfo movs r8, r5 @ invalid machine (r5=0)? beq __error_a @ yes, error 'a' 其中__lookup_processor_type在linux-2.6.24-moko-linuxbj/arch/arm/kernel/head-common.S文件的149行,该函数首将标号3的实际地址加载到r3,然后将编译时生成的__pro

45、c_info_begin虚拟地址载入到r5,__proc_info_end虚拟地址载入到r6,标号3的虚拟地址载入到r7。由于adr伪指令和标号3的使用,以及__proc_info_begin等符号在linux-2.6.24-moko-linuxbj/arch/arm/kernel/vmlinux.lds而不是代码中被定义,此处代码不是非常直观,想弄清楚代码缘由的读者请耐心阅读这两个文件和adr伪指令的说明。 r3和r7分别存储的是同一位置标号3的物理地址(由于没有启用mmu,所以当前肯定是物理地址)和虚拟地址,所以儿者相减即得到虚拟地址和物理地址之间的offset。利用此offset,

46、将r5和r6中保存的虚拟地址转变为物理地址 __lookup_processor_type: adr r3, 3f ldmda r3, {r5 - r7} sub r3, r3, r7 @ get offset between virt&phys add r5, r5, r3 @ convert virt addresses to add r6, r6, r3 @ physical address space 然后从proc_info中读出内

47、核编译时写入的processor ID和之前从cpsr中读到的processor ID对比,查看代码和CPU硬件是否匹配(想在arm920t上运行为cortex-a8编译的内核?不让!)。如果编译了多种处理器支持,如versatile板,则会循环每种type依次检验,如果硬件读出的ID在内核中找不到匹配,则r5置0返回 1: ldmia r5, {r3, r4} @ value, mask and r4, r4, r9 @ mask wanted bits teq r3, r4 beq 2f add r5, r5, #PROC_INFO_SZ @ sizeof(pr

48、oc_info_list) cmp r5, r6 blo 1b mov r5, #0 @ unknown processor 2: mov pc, lr __lookup_machine_type在文件的197行,编码方法与检查processor ID完全一样,请参考前段 __lookup_machine_type: adr r3, 3b ldmia r3, {r4, r5, r6} sub r3, r3, r4 @ get offset between virt&phys add r5, r5, r3 @ convert virt add

49、resses to add r6, r6, r3 @ physical address space 1: ldr r3, [r5, #MACHINFO_TYPE] @ get machine type teq r3, r1 @ matches loader number? beq 2f @ found add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc cmp r5, r6 blo 1b mov r5, #0 @ unknown machine 2: mov pc, lr 代码回到he

50、ad.S第92行,检查atags合法性,然后创建初始页表 bl __vet_atags bl __create_page_tables 创建页表的代码在218行,首先将内核起始地址-0x4000到内核起始地址之间的16K存储器清0 __create_page_tables: pgtbl r4 @ page table address /* * Clear the 16K level 1 swapper page table */ mov r0, r4 mov r3, #0 add r6, r0, #0x4000 1: str r3,

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4009-655-100  投诉/维权电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服