当前位置: 首页 > news >正文

温州做网站就来温州易富网络企业推广方式优选隐迅推

温州做网站就来温州易富网络,企业推广方式优选隐迅推,手机cpu性能增强软件,做窗帘的效果图网站在Linux移植之make uImage编译过程分析中已经提到了uImage是一个压缩的包并且内含压缩程序#xff0c;可以进行自解压。自解压完成之后内核代码从物理地址为0x30008000处开始运行。下面分析在进入C之前内核做的一些工作#xff0c;以下是内核启动过程中打印出来的信息#x…在Linux移植之make uImage编译过程分析中已经提到了uImage是一个压缩的包并且内含压缩程序可以进行自解压。自解压完成之后内核代码从物理地址为0x30008000处开始运行。下面分析在进入C之前内核做的一些工作以下是内核启动过程中打印出来的信息其中Uncompressing Linux就是在自解压代码。make uImage编译的最后也给出了链接脚本arch/arm/kernel/vmlinux.lds以及链接的顺序arch/arm/kernel/head.o 是第一个。   分析arch/arm/kernel/vmlinux.lds可以知道程序入口的地址是stext并且是.text.head段 277 OUTPUT_ARCH(arm) 278 ENTRY(stext)291 . (0xc0000000) 0x00008000; 292 293 .text.head : { 294 _stext .; 295 _sinittext .; 296 *(.text.head) 297 } 打开arch/arm/kernel/head.s。可见内核运行的第一条代码就是第79行的代码从这条开始分析首先将CPU设置为管理模式并且关闭所有中断然后获得CPU的id。 76 .section .text.head, ax //.text.head段 77 .type stext, %function 78 ENTRY(stext) //入口地址stext 79 msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE ensure svc mode//确保进入了管理模式 80 and irqs disabled //并且禁止中断 81 mrc p15, 0, r9, c0, c0 get processor id //获得处理器的CPU id并且存入 r9中 82 bl __lookup_processor_type r5procinfo r9cpuid //调用函数输入参数r9cpuid。返回值r5procinfo 83 movs r10, r5 invalid processor (r50)?//如果不支持当前CPU则r50 84 beq __error_p yes, error p //如果r50则打印错误 85 bl __lookup_machine_type r5machinfo //调用函数r5返回值machinfo 86 movs r8, r5 invalid machine (r50)? //如果不支持当前单板则返回r50 87 beq __error_a yes, error a //如果r50则打印错误 88 bl __create_page_tables//创建一级页表以建立虚拟地址到物理地址的映射关系后面再研究 接着调用__lookup_processor_type它位于arch\arm\kernel\head-common.S。它的功能是比较当前CPU的id与内核支持的CPU的id是否相符合。这段代码在.proc.info.init段中从__proc_info_begin开始到__proc_info_end结束寻找符合当前CPU的ID号的proc_info_list结构 145 .type __lookup_processor_type, %function 146 __lookup_processor_type: 147 adr r3, 3f //r3 第178行代码的物理地址 148 ldmda r3, {r5 - r7} //将r3地址开始的3个地址的内容赋给 r5、r6、r7 ;r5__proc_info_begin,r6__proc_info_end 149 sub r3, r3, r7 get offset between virtphys//r3r3-r7即物理地址与虚拟地址的差值 150 add r5, r5, r3 convert virt addresses to//r5__proc_info_begind对应的物理地址 151 add r6, r6, r3 physical address space //r6__proc_info_end对应的物理地址 152 1: ldmia r5, {r3, r4} value, mask//r3、r4等于proc_info_list结构中的cpu_val、cpu_mask 153 and r4, r4, r9 mask wanted bits//r4r4r9cpu_mask传入的cpuid 154 teq r3, r4 //比较 155 beq 2f //如果相等则找到对应的proc_info_list结构跳到160行 156 add r5, r5, #PROC_INFO_SZ sizeof(proc_info_list)//r5指向下一个proc_info_list结构 157 cmp r5, r6 //是否已经比较完所有proc_info_list 158 blo 1b //没有则继续比较 159 mov r5, #0 unknown processor//比较完毕但是没有找到匹配的proc_info_list结构r50 160 2: mov pc, lr//返回返回的值为r5proc_info_list176 .long __proc_info_begin 177 .long __proc_info_end 178 3: .long .//.表示当前这条代码链接后的虚拟地址 179 .long __arch_info_begin 180 .long __arch_info_end 其中__proc_info_begin、__proc_info_end被定义在arch\arm\kernel\vmlinux.lds中它的意思是内核源码中有被定义为.proc.info.init的内容它的起始地址是__proc_info_begin结束地址为__proc_info_end。 299 .init : { /* Init code and data */ 230 *(.init.text) 231 _einittext .; 232 __proc_info_begin .; 233 *(.proc.info.init) 234 __proc_info_end .; 接着看到proc_info_list结构的内容它被定义在include\asm-arm\Procinfo.h中 29 struct proc_info_list { 30 unsigned int cpu_val; 31 unsigned int cpu_mask; 32 unsigned long __cpu_mm_mmu_flags; /* used by head.S */ 33 unsigned long __cpu_io_mmu_flags; /* used by head.S */ 34 unsigned long __cpu_flush; /* used by head.S */ 35 const char *arch_name; 36 const char *elf_name; 37 unsigned int elf_hwcap; 38 const char *cpu_name; 39 struct processor *proc; 40 struct cpu_tlb_fns *tlb; 41 struct cpu_user_fns *user; 42 struct cpu_cache_fns *cache; 43 }; 接着找到对于当前内核支持的proc_info_list 定义它在arch\arm\mm\proc-arm920.S 中。对于S3C2410、S3C2440芯片来说CPU ID都是0x41129200。cpu_val的值为0x41009200、cpu_mask的值为0xff00fff0刚好匹配。 .section .proc.info.init, #alloc, #execinstr448 .type __arm920_proc_info,#object 449 __arm920_proc_info: 450 .long 0x41009200//cpu_val值 451 .long 0xff00fff0//cpu_mask值 452 .long PMD_TYPE_SECT | \ 453 PMD_SECT_BUFFERABLE | \ 454 PMD_SECT_CACHEABLE | \ 455 PMD_BIT4 | \ 456 PMD_SECT_AP_WRITE | \ 457 PMD_SECT_AP_READ 458 .long PMD_TYPE_SECT | \ 459 PMD_BIT4 | \ 460 PMD_SECT_AP_WRITE | \ 461 PMD_SECT_AP_READ 462 b __arm920_setup 463 .long cpu_arch_name 464 .long cpu_elf_name 465 .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB 466 .long cpu_arm920_name 467 .long arm920_processor_functions 468 .long v4wbi_tlb_fns 469 .long v4wb_user_fns 470 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH 471 .long arm920_cache_fns 472 #else 473 .long v4wt_cache_fns 474 #endif 475 .size __arm920_proc_info, . - __arm920_proc_info 继续回到arch/arm/kernel/head.s往下分析看到第83行调用完__lookup_processor_type后r5的值变为执向找到的proc_info_list 结构的地址。所以第83行与第84行比较r5是否为0如果为0说明没有找到符合当前CPU的ID号则打印错误。接着到85行调用__lookup_machine_type它同样位于arch\arm\kernel\head-common.S中,它的功能是比较当前单板的id与内核支持的单板的id是否相符合。这段代码在.arch.info.init段中从__arch_info_begin开始到__arch_info_end结束寻找符合当前单板的ID号的machine_desc结构 176 .long __proc_info_begin 177 .long __proc_info_end 178 3: .long .//.表示当前这条代码链接后的虚拟地址 179 .long __arch_info_begin 180 .long __arch_info_end193 .type __lookup_machine_type, %function 194 __lookup_machine_type: 195 adr r3, 3b //r3第178行的物理地址 196 ldmia r3, {r4, r5, r6} //r4r3。r5__proc_info_endr6__proc_info_begin取得的是虚拟地址 197 sub r3, r3, r4 get offset between virtphys//r3r3-r4取得物理地址与虚拟地址的偏差 198 add r5, r5, r3 convert virt addresses to//r5r5r3取得物理地址__proc_info_end 199 add r6, r6, r3 physical address space //r6r6r3取得物理地址__proc_info_begin 200 1: ldr r3, [r5, #MACHINFO_TYPE] get machine type //r3取得单板的编号 201 teq r3, r1 matches loader number?//比较r3与r1是否相等即linux是否支持uboot传入的单板 202 beq 2f found //如果相等则跳到207行找到支持的单板返回 203 add r5, r5, #SIZEOF_MACHINE_DESC next machine_desc//r5执向下一个machine_desc结构 204 cmp r5, r6 //是否已经比较完machine_desc结构? 205 blo 1b //如果没有比较完则跳到200行继续比较 206 mov r5, #0 unknown machine //如果所有machine_desc都比较完了r50 207 2: mov pc, lr //返回 其中__arch_info_begin、__arch_info_end被定义在arch\arm\kernel\vmlinux.lds中它的意思是内核源码中有被定义为.arch.info.init的内容它的起始地址是__arch_info_begin结束地址为__arch_info_end。 305 __arch_info_begin .; 306 *(.arch.info.init) 307 __arch_info_end .; 接着看到machine_desc结构的内容它被定义在include\asm-arm\mach\Arch.h 中 17 struct machine_desc { 18 /* 19 * Note! The first four elements are used 20 * by assembler code in head-armv.S 21 */ 22 unsigned int nr; /* architecture number */ //单板的编号是从内核传过来的编号 r1 23 unsigned int phys_io; /* start of physical io */ 24 unsigned int io_pg_offst; /* byte offset for io 25 * page tabe entry */ 26 27 const char *name; /* architecture name */ 28 unsigned long boot_params; /* tagged list *///boo传过来的tag标记的位置也是从内核传过来的 r2 29 30 unsigned int video_start; /* start of video RAM */ 31 unsigned int video_end; /* end of video RAM */ 32 33 unsigned int reserve_lp0 :1; /* never has lp0 */ 34 unsigned int reserve_lp1 :1; /* never has lp1 */ 35 unsigned int reserve_lp2 :1; /* never has lp2 */ 36 unsigned int soft_reboot :1; /* soft reboot */ 37 void (*fixup)(struct machine_desc *, 38 struct tag *, char **, 39 struct meminfo *); 40 void (*map_io)(void);/* IO mapping function *///IO映射函数移植时需要关注 41 void (*init_irq)(void); 42 struct sys_timer *timer; /* system tick timer */ 43 void (*init_machine)(void); 44 }; 接着需要找到对于当前内核支持的machine_desc定义在include\asm-arm\mach\Arch.h 中有如下宏定义它表示在.arch.info.init段存入一个machine_desc 的结构体名称为 __mach_desc_type结构体内.nr、.name初始化为MACH_TYPE_type、_name 50 #define MACHINE_START(_type,_name) \ 51 static const struct machine_desc __mach_desc_##_type \ 52 __used \ 53 __attribute__((__section__(.arch.info.init))) { \ 54 .nr MACH_TYPE_##_type, \ 55 .name _name, 56 57 #define MACHINE_END \ 58 }; 接着找调用MACHINE_START这个宏的文件在arch\arm\mach-s3c2440\Mach-smdk2440.c 找到了所以单板的ID为MACH_TYPE_S3C2440它被定义在include\asm-arm\Mach-types.h中 #define MACH_TYPE_S3C2440              362。与UBOOT传入的参数相符合。 339 MACHINE_START(S3C2440, SMDK2440) 340 /* Maintainer: Ben Dooks benfluff.org */ 341 .phys_io S3C2410_PA_UART, 342 .io_pg_offst (((u32)S3C24XX_VA_UART) 18) 0xfffc, 343 .boot_params S3C2410_SDRAM_PA 0x100, 344 345 .init_irq s3c24xx_init_irq, 346 .map_io smdk2440_map_io, 347 .init_machine smdk2440_machine_init, 348 .timer s3c24xx_timer, 349 MACHINE_END 继续来看MACHINE_START(S3C2440, SMDK2440)这个宏在里面有许多和开发板相关的设置比如说smdk2440_map_io它被定义在arch\arm\mach-s3c2440\Mach-smdk2440.c中在Linux移植之移植步骤中提到过想要移植成功必须修改327行代码将晶振的设置改为12000000。还有其它的一些配置就不一一列举了。 324 static void __init smdk2440_map_io(void) 325 { 326 s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc)); 327 s3c24xx_init_clocks(12000000);//根据开发板合适的晶振配置 328 s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs)); 329 } 回到arch/arm/kernel/head.s接着往下看86、87行判断__lookup_machine_type是否成功找到支持单板的machine_desc结构如果没找到则打印错误88行是用来创建一级页表以建立虚拟地址到物理地址的映射关系这里不详细分析。 继续往下看看到100行其中r10的值为__arm920_proc_info所在地址PROCINFO_INITFUNC为proc_info_list结构体的偏移量具体为__cpu_flush对应到__arm920_proc_info结构体内pc的值就是b __arm920_setup这条语句所在地址即执行b __arm920_setup这条指令__arm920_setup做一些MMU相关的初始化在arch\arm\mm\proc-arm920.S中这里不做细究。 97 ldr r13, __switch_data address to jump to after//r13是堆栈寄存器sp 98 mmu has been enabled 99 adr lr, __enable_mmu return (PIC) address //100行设置完成之后在使能MMU 100 add pc, r10, #PROCINFO_INITFUNC//调用__arm920_setup函数应该跟MMU相关后面再研究 b __arm920_setup执行完毕返回之后执行的是arch/arm/kernel/head.s下的__enable_mmu 。 152 .type __enable_mmu, %function 153 __enable_mmu: ..... 174 b __turn_mmu_on187 .align 5 188 .type __turn_mmu_on, %function 189 __turn_mmu_on: 190 mov r0, r0 191 mrc p15, 0, r3, c0, c0, 0 read id reg 192 mov r3, r3 193 mov r3, r3 194 mov pc, r13//设置完MMU之后跳转到__switch_data执行 __enable_mmu 执行完之后进入__switch_data执行注意这时候的运行地址已经是初始化MMU之后的虚拟地址了。从15-24行可以看出pc__mmap_switched__mmap_switched的主要工作是将processor_id与__machine_arch_type初始化为当前MCU的编号与单板的编号 14 .type __switch_data, %object 15 __switch_data: 16 .long __mmap_switched 17 .long __data_loc r4 18 .long __data_start r5 19 .long __bss_start r6 20 .long _end r7 21 .long processor_id r4//之前找到的符合当前MCU的__arm920_proc_info结构体 22 .long __machine_arch_type r5//之前找到的符合单板的__mach_desc_S3C2440结构体 23 .long cr_alignment r6 24 .long init_thread_union THREAD_START_SP sp 25 26 /* 27 * The following fragment of code is executed with the MMU on in MMU mode, 28 * and uses absolute addresses; this is not position independent. 29 * 30 * r0 cp#15 control register 31 * r1 machine ID 32 * r9 processor ID 33 */ 34 .type __mmap_switched, %function 35 __mmap_switched://虚拟地址已经可以使用 36 adr r3, __switch_data 4//r3__data_loc所在的地址 37 38 ldmia r3!, {r4, r5, r6, r7}//r4__data_loc所在地址r5__data_start所在地址依次类推 r3__switch_data4*4 39 cmp r4, r5 Copy data segment if needed //检查是否有__data_loc段r4r5说明没有__data_loc 40 1: cmpne r5, r6 41 ldrne fp, [r4], #4 42 strne fp, [r5], #4 43 bne 1b 44 45 mov fp, #0 Clear BSS (and zero fp)//清0BSS段 46 1: cmp r6, r7 47 strcc fp, [r6],#4 48 bcc 1b 49 50 ldmia r3, {r4, r5, r6, sp}//r4processor_id、r5__machine_arch_type、r6cr_alignment、spinit_thread_union THREAD_START_SP 51 str r9, [r4] Save processor ID//processor_idr9 proc_info_list.cpu_val 0x41009200 52 str r1, [r5] Save machine type//__machine_arch_typer1 machine_desc .nr MACH_TYPE_S3C2440 362 53 bic r4, r0, #CR_A Clear A bit 54 stmia r6, {r0, r4} Save control register values 55 b start_kernel//跳转到start_kernel C函数 最终执行b start_kernel跳到C函数这是第二阶段的内容。  转载于:https://www.cnblogs.com/andyfly/p/9404198.html
http://wiki.neutronadmin.com/news/47964/

相关文章:

  • 四川石油天然气建设工程有限责任公司网站只做同城交易的网站
  • 网站推广软文范文自助建站平台便宜
  • 河南网站设计微信网站入口
  • 南昌网站建设开发团队电商app开发哪家公司最好
  • 铁岭网站制作网站建设 知乎
  • 做直播网站找哪个网站做视频网站视频的软件
  • 网站建设是前端吗网站建设公司成都
  • 浙江市建设网站找人做公司网站
  • 婴儿衣服做的网站好网站开发和运行 法律
  • 建设网站教程视频视频老板网人才招聘
  • 做网站的公司哪家好如何用域名访问网址
  • 淘宝客网站备案信息六安商务网站建设电话
  • 中国城乡住房建设厅网站wordpress生成tags页面
  • 成都个人网站984网站建设项目
  • 专门做衣服的网站uniapp开源商城源码
  • 中建西部建设西南有限公司网站nas服务器可以做网站吗
  • 手机网站 图片自适应目前做系统比较好的网站
  • 图片网站怎么做排名昆明网站建设织梦
  • 企业建网站的步骤iis网站权限
  • 常平做网站费用
  • 教育培训机构招生网站建设三线建设网站
  • 网站建设get你推广淘特一个新人多少钱
  • 扬州建设教育信息网站微信app下载最新版本
  • 网站建设的技术亮点汉阳做网站
  • 浦东新区专业网站建设小程序推广赚佣金平台
  • 定制网站开发多少钱织梦网站内部优化
  • 网站建设维护方案最新手机发布会
  • 论坛网站免费建设模板下载安装大数据培训班出来能就业吗
  • 网站没有备案用什么cdnwordpress添加爬虫数据
  • 仟亿家设计软件好吗亿家搜索排名优化网站排名优化