您尚未登录。

楼主 #1 2020-01-05 17:51:12

kekemuyu
会员
注册时间: 2018-12-13
已发帖子: 844
积分: 725

看f1c100s裸奔程序受到的启发

今天看了一下达克洛德的裸奔程序,突发奇想,既然能引导自己的程序,那也可以引导linux内核吧,这样bootloader可以小到几k吧

离线

楼主 #4 2020-01-05 20:44:21

kekemuyu
会员
注册时间: 2018-12-13
已发帖子: 844
积分: 725

Re: 看f1c100s裸奔程序受到的启发

直接启动?引导程序肯定打包进linux内核了,zlg的i.mx287开发板也有这样的方式。总之引导过程避免不了,从裸奔程序提炼出引导程序肯定比uboot小很多,这样引导程序的启动时间基本可以忽略。

离线

楼主 #6 2020-01-05 21:42:50

kekemuyu
会员
注册时间: 2018-12-13
已发帖子: 844
积分: 725

Re: 看f1c100s裸奔程序受到的启发

checkout 说:

把基本外设初始化好,再向内核传参就行,可以做到很小,启动时间主要是从flash加载内核到内存耗时比较长

需要传参吗?如何传参,不是有设备树吗?

离线

楼主 #8 2020-01-05 23:10:21

kekemuyu
会员
注册时间: 2018-12-13
已发帖子: 844
积分: 725

Re: 看f1c100s裸奔程序受到的启发

checkout 说:

需要传递一个tag列表或设备树地址给内核,简化的bootloader做到4kb以内都很正常

感谢回复,很有帮助。做一个简单的boot,从start.s文件中找到一段关键代码:

/* Initial system clock, ddr add uart */
	bl sys_clock_init
	bl sys_dram_init
	bl sys_uart_init

	/* Copyself to link address */
	adr r0, _start
	ldr r1, =_start
	cmp r0, r1
	beq 1f
	bl sys_copyself

这段代码几乎是核心引导了,加上copy linux内核代码应该就可以了,然后跳转到linux内核地址

最近编辑记录 kekemuyu (2020-01-05 23:15:40)

离线

楼主 #9 2020-01-05 23:18:19

kekemuyu
会员
注册时间: 2018-12-13
已发帖子: 844
积分: 725

Re: 看f1c100s裸奔程序受到的启发

这里就是主程序入口,很简单嘛,怀念8051汇编的日子。有时候挺喜欢汇编的,让我有一种全局掌控的感觉,了解所有寄存的状况,内存,堆栈,中断都在自己的掌控之中

	/* Call _main */
	ldr r1, =_main
	mov pc, r1
_main:
	mov r0, #1;
	mov r1, #0;
	bl boot_main
	b _main

最近编辑记录 kekemuyu (2020-01-05 23:28:06)

离线

楼主 #11 2020-01-06 00:31:07

kekemuyu
会员
注册时间: 2018-12-13
已发帖子: 844
积分: 725

Re: 看f1c100s裸奔程序受到的启发

达克罗德 说:

和楼主有同样的想法,加油!我可能会试试uboot裁剪这条路。我这个裸机有点问题好像200s的高32MB内存用不起来

感谢@达克罗德 大神对f1c100s裸奔的所做的大量工作,我等菜鸟才可以一探f1c100s内部的工作原理。uboot裁剪有点难搞,开始也是想看一下uboot源码,可不知道从哪里下手,本来想看一下makefile,可是makefile文件太多了,不知道从哪一个看起。有时间还邀请大神普及一下uboot和linux内核的编译过程。

离线

楼主 #12 2020-01-06 15:09:22

kekemuyu
会员
注册时间: 2018-12-13
已发帖子: 844
积分: 725

Re: 看f1c100s裸奔程序受到的启发

达克罗德 说:

和楼主有同样的想法,加油!我可能会试试uboot裁剪这条路。我这个裸机有点问题好像200s的高32MB内存用不起来

heap中的len改成48M,应该就支持了吧

MEMORY
{
	ram  : org = 0x80000000, len = 8M
	dma  : org = 0x80800000, len = 8M
	heap : org = 0x81000000, len = 16M
}

最近编辑记录 kekemuyu (2020-01-06 15:09:44)

离线

楼主 #13 2020-01-06 16:21:43

kekemuyu
会员
注册时间: 2018-12-13
已发帖子: 844
积分: 725

Re: 看f1c100s裸奔程序受到的启发

需要明确一件事,把设备树和linux内核加载到ram后,只要把设备树地址赋值给r2寄存器,然后跳转到linux地址就可以了吗?linux就会自动解析设备树了吗?

内核对设备树的处理也是分这三部分的。

1. 对于32bit的arm处理器,bootloader启动内核时,会设置r0,r1,r2三个寄存器,
r0一般设置为0;
r1一般设置为machine id (在使用设备树时该参数没有被使用);
r2一般设置ATAGS(使用设备树之前)或DTB的开始地址(使用设备树之后)

bootloader给内核传递的参数时有2种方法:ATAGS 或 DTB

a. __lookup_processor_type : 使用汇编指令读取CPU ID, 根据该ID找到对应的proc_info_list结构体(里面含有这类CPU的初始化函数、信息)
b. __vet_atags : 判断是否存在可用的ATAGS或DTB
c. __create_page_tables : 创建页表, 即创建虚拟地址和物理地址的映射关系
d. __enable_mmu : 使能MMU, 以后就要使用虚拟地址了
e. __mmap_switched : 上述函数里将会调用__mmap_switched
f. 把bootloader传入的r2参数, 保存到变量__atags_pointer中
g. 调用C函数start_kernel

head.S/head-common.S :
把bootloader传来的r1值, 赋给了C变量: __machine_arch_type
把bootloader传来的r2值, 赋给了C变量: __atags_pointer // dtb首地址

对于32bit的arm处理器,machine_desc 使用 MACHINE_START 初始化,其 dt_compat 存储的是 compatible 属性数组,用于表示支持的单板。

u-boot 中也提供的对dtb文件进行操作的命令,为 fdt, uboot 中所有的命令都是使用U_BOOT_CMD()来定义的,对应文件中有命令的使用注释。

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn