1.c运行环境的初始化
来源:互联网 发布:linux tomcat启动很慢 编辑:程序博客网 时间:2024/05/22 06:33
1.c运行环境的初始化
源代码目录src/sandnix/kernel/hal/init/arch
这部分干的活可以归为以下几点
- 让cpu处在正确的工作模式.(bootloader不总是对的).
- 关中断(没中断向量/描述符表万一来了个中断乐子就大了).
- 开分页(不把代码跳到内核空间难道访问全局变量的时候挨个算偏移量?)
- 保存bootloader传来的信息(不保存启动参数,内存信息啥的咋办).
x86
.global _start.global gdt.global kernel_header.global tss_desc_table.section .data//GDT表gdt: SEGMENT_DESCRIPTOR 0, 0, 0descriptor_kernel_data: SEGMENT_DESCRIPTOR 0, 0xFFFFF, DA_DRW | DA_DPL0 | DA_32descriptor_kernel_code: SEGMENT_DESCRIPTOR 0, 0xFFFFF, DA_CR | DA_DPL0 | DA_32descriptor_user_data: SEGMENT_DESCRIPTOR 0, 0xFFFFF, DA_DRW | DA_DPL3 | DA_32descriptor_user_code: SEGMENT_DESCRIPTOR 0, 0xFFFFF, DA_CR | DA_DPL3 | DA_32tss_desc_table:.rept MAX_CPU_NUM SEGMENT_DESCRIPTOR 0, 0x67, DA_386TSS | DA_DPL0.endrgdt_end:gdtr_value: .word (gdt_end - gdt - 1)gdt_addr: .long gdt.section .text.align 8//描述内核映像信息的结构体,编译时由脚本填充kernel_header: //magic .long KERNEL_HEADER_MAGIC //code_start .long 0 //code_size .long 0 //data_start .long 0 //data_size .long 0 //header_size .long _kernel_header_end - kernel_header //checksum .long 0x100000000 - ((KERNEL_HEADER_MAGIC + (_kernel_header_end - kernel_header)) & 0xFFFFFFFF)_kernel_header_end: .long 0/* Step 1 : 检查引导协议类型.咋检查看multiboot2的文档 */#if BOOTLOADER == MULTIBOOT2 //EAX == Magic.EBX = Kernel parameters_start: cli //Check bootloader cmpl $0x36D76289, %eax je _BOOTLOADER_CHECKED //if(eax != 0x36D76289) { //不是的话就重启吧 movb $0xFE, %al outb %al, $0x64 hlt //}_BOOTLOADER_CHECKED: //对的话就把引导信息的地址压栈 pushl %ebx#endif/* Step 2 : 准备C的运行环境 */ //call/pop/sub组合计算偏移量,这招过去很多文件型病毒也爱用 call _ADDR_1_ADDR_1: popl %eax subl $_ADDR_1, %eax //eax = offset //Write gdt address movl $gdt, %edx addl %eax, %edx movl $gdt_addr, %ebx addl %eax, %ebx movl %edx, (%ebx) //Load GDT movl $gdtr_value, %ebx addl %eax, %ebx lgdt (%ebx) //Load segments movw $SELECTOR_U_DATA, %ax movw %ax, %ds movw %ax, %es movw %ax, %fs movw %ax, %gs //开分页,这个函数是mmu模块提供的,用c写的,访问个全局变量都要计算偏移,相当的蛋疼 call start_paging //跳到内核空间,顺便加载cs ljmpl $SELECTOR_K_CODE, $_KERNEL_MEM_KERNEL_MEM: //Reload stack //弹出引导信息 popl %edi movl $init_stack, %ebx addl $DEFAULT_STACK_SIZE, %ebx movl %ebx, %ebp movl %ebx, %esp //将刚才弹出的引导信息压栈,这样正好作为内核主函数的参数 push %edi //Reload GDT //Write gdt address movl $gdt, gdt_addr //Load GDT movl $gdtr_value, %eax lgdt (%eax) //FPU fninit movl $0x80010021, %eax movl %eax, %cr0/* Step 3 : Call c code. */ //调用主函数 call kinit
ARM
.global _start.global kernel_header.section .text.align 8//跟上面一样kernel_header: //magic .long KERNEL_HEADER_MAGIC //code_start .long 0 //code_size .long 0 //data_start .long 0 //data_size .long 0 //header_size .long _kernel_header_end - kernel_header //checksum .long 0x100000000 - ((KERNEL_HEADER_MAGIC + (_kernel_header_end - kernel_header)) & 0xFFFFFFFF)_kernel_header_end: .long 0_start: //保证处于SVC模式并且屏蔽掉IRQ和FIQ ldr r5, =0x000000D3 msr spsr, r5 msr cpsr, r5 //计算偏移,原理和X86的一样_offchk_addr: mov r5, pc sub r5, r5, #8 ldr r6, =_offchk_addr sub r5, r5, r6 //r5 = offset //加载内核栈 ldr sp, =init_stack add sp, sp, r5 ldr r6,=DEFAULT_STACK_SIZE add sp, sp, r6#if BOOTLOADER == UBOOT //把参数压栈 stmfd sp!, {r2}#endif //开分页 bl start_paging //重定位栈指针 sub sp, sp, r5 //把参数弹到r0 ldmfd sp!, {r0} //调用主函数 ldr r1, =kinit mov pc, r1
0 0
- 1.c运行环境的初始化
- 基于ARM的C语言运行环境初始化
- ARM汇编初始化C程序运行环境
- 初始化QML运行环境
- C++,编译初始化,运行初始化
- bootloader C语言环境的初始化
- tiny6410的C语言环境初始化
- C语言环境初始化
- 转载:2.6.4 初始化Postgres的运行环境
- 判断C运行时环境的程序
- 三十二.C语言环境初始化
- uboot-C语言环境初始化
- Java运行时环境初始化出现错误
- DroidPlugin源码分析插件运行环境初始化
- ATF(EL3级别运行环境初始化)
- ARM Linker的使用——应用程序运行环境的初始化
- bluetooth开发(四)------Bluez运行环境的创建与蓝牙的初始化
- Adobe flash cs5 的Java运行时环境初始化错误 完美解决方法
- 关于android应用图标在部分手机显示白色背景的探索
- nginx 支持.htaccess伪静态
- 这个博主的java web 和 java jsp 等等知识的总结很全面, mark
- Core Animation
- Android studio魅蓝note3/其他魅族手机真机调试
- 1.c运行环境的初始化
- java实现重建二叉树
- xml与对象的转换
- gradle文件配置签名apk
- BZOJ2208: [Jsoi2010]连通数 Tarjan缩点+Dfs
- iOS学习 委托和回调
- U盘格式小探究
- 内网穿透类型——对称型和非对称型
- 笔记摘抄_MD5加密