arm+java+移植_ARM系统移植

u-boot一旦引导到内核,操作权限就会交给内核,那么所有的事情就和u-boot没有关系了,除了u-boot传递给内核的参数。

基地址+100 u-boot给内核的参数

基地址+4000 映射列表

基地址+8000 内核

内核的执行流程:

整个内核的入口:根据lds文件和编译到内核的源码文件共同决定。

arch/arm/kernel/head.s

safe_svcmode_maskall r9 确保处在SVC模式

mrc p15, 0, r9, c0, c0 读取cpu id cpu id在协处理器内部

bl __lookup_processor_type 判断内核是否支持本cpu

arch/arm/kernel/head-common.S

__lookup_processor_type:

adr r3, __lookup_processor_type_data 基于pc

154 ldmia r3, {r4 - r6}

155 sub r3, r3, r4 @ get offset between virt&phys 判断实际运行地址和规划地址的差值,为了找cpuid在内存上

156 add r5, r5, r3 @ convert virt addresses to

157 add r6, r6, r3 @ physical address space

1: ldmia r5, {r3, r4} @ value, mask

159 and r4, r4, r9 @ mask wanted bits

160 teq r3, r4

161 beq 2f

162 add r5, r5, #PROC_INFO_SZ (8) @ sizeof(proc_info_list)

163 cmp r5, r6

164 blo 1b

165 mov r5, #0 @ unknown processor

166 2: mov pc, lr

__lookup_processor_type_data

174 __lookup_processor_type_data:

175 .long . 利用一条语句,在不同地方(实际运行地址、连接规划地址)的不同,来计算实际运行地址和规划地址的差值

176 .long __proc_info_begin

177 .long __proc_info_end

178 .size __lookup_processor_type_data, . - __lookup_processor_type_data

bl __vet_atags 用来检测参数。

128 bl __create_page_tables 穿件映射列表,映射列表是(虚拟地址和物理地址之间的转换表)

ldr r13, =__mmap_switched 为跳到下一个阶段做准备

adr lr, BSYM(1f)

1: b __enable_mmu 打开mmu

b __turn_mmu_on

ENTRY(__turn_mmu_on)

464 mov r0, r0

465 instr_sync

466 mcr p15, 0, r0, c1, c0, 0 @ write control reg

467 mrc p15, 0, r3, c0, c0, 0 @ read id reg

468 instr_sync

469 mov r3, r3

470 mov r3, r13(=__mmap_switched )

471 mov pc, r3

pc ==__mmap_switched

472 __turn_mmu_on_end:

__mmap_switched :内核的第二阶段

mov fp, #0 @ Clear BSS (and zero fp)

91 1: cmp r6, r7

92 strcc fp, [r6],#4

93 bcc 1b

94

95 ARM( ldmia r3, {r4, r5, r6, r7, sp}) 设置堆栈

473 ENDPROC(__turn_mmu_on)

跳转到c语言:

stmneia r7, {r0, r4} @ Save control register values

104 b start_kernel

init/main.c

start_kernel()

setup_arch(&command_line); 会解析u-boot传递的参数。

mdesc = setup_machine_fdt(__atags_pointer) 解析设备树

mdesc = setup_machine_tags(__atags_pointer, __machine_arch_type); 检测本内核是或否支持板子

command_line :制定根文件系统

rest_init();

382 kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);

if (execute_command) {判断bootargs里面有init=“?”,如果有则执行,如果没有则去下面的路径上运行

865 ret = run_init_process(execute_command);

866 if (!ret)

867 return 0;

868 pr_err("Failed to execute %s (error %d). Attempting defaults...\n",

869 execute_command, ret);

870 }

871 if (!try_to_run_init_process("/sbin/init") ||

872 !try_to_run_init_process("/etc/init") ||

873 !try_to_run_init_process("/bin/init") ||

874 !try_to_run_init_process("/bin/sh"))

init进程的调用流程:

init/main.c

start_kernel()-----》 rest_init();----》kernel_init();---》》》

if (execute_command) {判断bootargs里面有init=“?”,如果有则执行,如果没有则去下面的路径上运行

865 ret = run_init_process(execute_command);

866 if (!ret)

867 return 0;

868 pr_err("Failed to execute %s (error %d). Attempting defaults...\n",

869 execute_command, ret);

870 }

871 if (!try_to_run_init_process("/sbin/init") ||

872 !try_to_run_init_process("/etc/init") ||

873 !try_to_run_init_process("/bin/init") ||

874 !try_to_run_init_process("/bin/sh"))

printk内核打印函数:可以分等级

内核调试:内核的错误有两种

panic错误:内核运行到不能再运行的地方出错,是内核设计者提前规定的一些错误点。现阶段主要造成的原因是,参数错误

oops错误:内核使用非法指针,会将错误的pc报出,可以根据addr2line来查找错误点。

根文件系统:第一个被挂载的文件系统。

sys(文件系统) 用来显示所有的设备文件

proc(文件系统) 又来显示所有的内核信息

tmp 基于内存的文件夹,主要用来进行记录日志

dev 基于内存的文件夹,用来管理所有的设备节点

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值