总体流程:
从链接文件看汇编函数的入口
链接的小知识
lk阶段会从boot image 解析出dtb数据,然后通过atag方式将dtb数据传递给了内核。
在mtk平台lk在向内核传递dtb数据前会修改部分dtb数据
MTK驱动(53)—平台DTS文件匹配过程
boot rom,cpu 内部rom代码
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/e26729be264fe54f4fe048c4ed946a1f.png)
Preloader: emmc等存储介质中
bootable/bootloader/preloader/platform/mt6580/link_descriptor.ld
入口函数**_start**
bootable/bootloader/preloader/platform/mt6580/src/init/init.s
resethandler:中的
bootable/bootloader/preloader/platform/mt6580/src/core/main.c
bldr_pre_process
bldr_handshake
bldr_load_images
bldr_post_process
bldr_jump
Little Kernel
bootable\bootloader\lk\arch\arm\rule.mk文件下相关部分
# potentially generated files that should be cleaned out with clean make rule
GENERATED += \
$(BUILDDIR)/system-onesegment.ld \
$(BUILDDIR)/system-twosegment.ld
# rules for generating the linker scripts
$(BUILDDIR)/trustzone-test-system-onesegment.ld: $(LOCAL_DIR)/trustzone-test-system-onesegment.ld $(LK_TOP_DIR)/target/$(TARGET)/rules.mk .FORCE
@echo generating $@
@$(MKDIR)
$(NOECHO)sed "s/%MEMBASE%/$(MEMBASE)/;s/%MEMSIZE%/$(MEMSIZE)/;s/%ROMLITE_PREFLASHED_DATA%/$(ROMLITE_PREFLASHED_DATA)/" < $< > $@
$(BUILDDIR)/trustzone-system-onesegment.ld: $(LOCAL_DIR)/trustzone-system-onesegment.ld $(LK_TOP_DIR)/target/$(TARGET)/rules.mk .FORCE
@echo generating $@
@$(MKDIR)
$(NOECHO)sed "s/%MEMBASE%/$(MEMBASE)/;s/%MEMSIZE%/$(MEMSIZE)/" < $< > $@
$(BUILDDIR)/system-onesegment.ld: $(LOCAL_DIR)/system-onesegment.ld $(LK_TOP_DIR)/target/$(TARGET)/rules.mk .FORCE
@echo generating $@
@$(MKDIR)
$(NOECHO)sed "s/%MEMBASE%/$(MEMBASE)/;s/%MEMSIZE%/$(MEMSIZE)/" < $< > $@
$(BUILDDIR)/system-twosegment.ld: $(LOCAL_DIR)/system-twosegment.ld $(LK_TOP_DIR)/target/$(TARGET)/rules.mk .FORCE
@echo generating $@
@$(MKDIR)
$(NOECHO)sed "s/%ROMBASE%/$(ROMBASE)/;s/%MEMBASE%/$(MEMBASE)/;s/%MEMSIZE%/$(MEMSIZE)/" < $< > $@
bootloader/lk/arch/arm/system-onesegment.ld
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start) /*跳入crt0.S文件执行代码*/
3.3 arch/arm/crt0.S
.section ".text.boot"
.globl _start
_start:
b reset
b arm_undefined
b arm_syscall
b arm_prefetch_abort
b arm_data_abort
b arm_reserved
b arm_irq
b arm_fiq
reset:
……
bl kmain
b
……
bootable/bootloader/lk/arch/arm/crt0.S
bootable/bootloader/lk/kernel/main.c
thread_init_early
arch_early_init
platform_early_init
call_constructors
bootstrap2
平台发现APP_START定义的有好多个,但只有mt_boot.c编译进系统了,刚只有mt_boot.c中的init指针函数mt_boot_init会被调用
接下来的流程为:
bootstrap2 -> apps_init -> mt_boot_init-》boot_linux_from_storage -》boot_linux
boot_linux
传了ATAGS参数
entry指向内核的入口地址
如下,向内核传了ATAGS结构的参数
其中ATAGS结构如下:
那如何自定义参数
如获取在lk里获取是否是非法设备,在target_atag_devinfo_data添加ATAG_DEVINFO_DATA 数据
wwc2_verify为为设备定义的检测方法,这样就可以将数据传给内核了
之前纠结ATAGS怎么存的设备树地址?
现在有了答案
在mt6580平台跑到boot_linux_fdt就跳到内核去了,因此tag所存的地址就是设备树的地址,__atags_pointer开始区域里存储的也是设备树的地址
在我们的平台还有一个方案是
也是用这个接口target_atag_devinfo_data
在boot_linux_fdt中获取 dtb并判断,再修改devinfo
然后内核驱动起来后
kernel-3.18/drivers/misc/mediatek/devinfo/v1/devinfo.c
再更新设备信息,上层通过/dev/devmap节点读取设备id判断是否合法
启动内核-kernel
内核的入口函数为:
在链接脚本 kernel-3.18/arch/arm/kernel/vmlinux.lds.S 中指定
符号stext是在arch/arm/kernel/head.S中定义的:
在后面跳转到__mmap_switched
kernel-3.18/arch/arm/kernel/head-common.S
进入内核时的传参: machtype = board_machtype() =
=
MACH_TYPE := mt6580
entry(0, machtype, tags);
r0 = cp#15 control register
r1 = machine ID
r2 = atags/dtb pointer
r9 = processor ID
因此**_machine_arch_type**存储了machine_arch_type
__atags_pointer存储了atags物理地址
检查是否是ATAG,只需要检测是否有ATAG_CORE
__create_page_tables创建一级页表
机器信息是编译到**.arch.info.init代码段的
上面检测到的与设备树root节点下的compatible**对比
设备树解析
setup_machine_tags传进来的__atags_pointer为物理地址
下面标注处为计算lk(物理地址)传到内核的起始虚拟地址(内核要用虚拟地址,因为使能了mmu)
从lk传来的物理地址为0x80000100 转换成虚拟地址为0xc0000100
parse_early_param
添加自定义atags并在内核在解析
android
note:
uart配置地方
mt6580里面开始有打印的是在bldr_pre_process-》platform_pre_init开始,前面设置波特率为921600
打印如下,下面乱码处也是有打印的,是非921600波特率的打印,应该是boot rom code的打印
platform_pre_init-》mt_pll_post_init,即开始是pll的打印,如下
�����������������������������������������������������������������������������������������������������������������������������AP_PLL_CON1= 0x3C3C23C0
AP_PLL_CON2= 0x4
CLKSQ_STB_CON0= 0x25002100
PLL_ISO_CON0= 0x202020
ARMPLL_CON0= 0x11
ARMPLL_CON1= 0x8009A000
ARMPLL_PWR_CON0= 0x5
MPLL_CON0= 0x8000011
MPLL_CON1= 0x800E7000
MPLL_PWR_CON0= 0x5
UPLL_CON0= 0x38000001
UPLL_CON1= 0x1000060
UPLL_PWR_CON0= 0x5DISP_CG_CON0= 0xFFFFFFFC,
DISP_CG_CON1= 0x0,
[PLF]Init PWRAP: OK(0)
[PLF]Init PMIC: OK(0)
[PLF]chip_ver[0]
bootmode显示问题
platform_init-》sw_env