想做一个简易的引导f1c100s的bootloader,查阅了很多资料,最后看了韦东山视频发现做一个简易的引导linux的boot并不难。
简易boot源码https://www.cnblogs.com/blogs-of-lxl/p/5906103.html 。手里正好有tiny200s的板子,所以想在这个板子上移植这个boot。
达克罗德大神的裸奔代码正好可以用上,在这个基础上加上引导代码即可。现在的问题是copy内核到sdram出现问题,卡在了拷贝内核到sdram的过程。如下:
引导代码:
#include <stdint.h>
#include <stdio.h>
#include <string.h>
extern void sys_uart_putc(char c);
extern void sys_uart_print(char *str);
extern void sys_spi_flash_init(void);
extern void sys_spi_flash_exit(void);
extern void sys_spi_flash_read(int addr, void * buf, int count);
static inline void sdelay(int loops)
{
__asm__ __volatile__ ("1:\n" "subs %0, %1, #1\n"
"bne 1b":"=r" (loops):"0"(loops));
}
int boot_main(int argc, char **argv) {
void (*theKernel)(int zero, int arch, unsigned int params);
void *sdram_dtb_start = (void *)0x80030000;
void *sdram_kernel_start = (void *)0x80040000;
/* 0. 从NOR FLASH里把dtb读入内存 */
sys_uart_print("Copy dtb from nor\n\r");
sys_spi_flash_init();
volatile unsigned int spi_dtb_start=0x30000;
sys_spi_flash_read( spi_dtb_start,sdram_kernel_start, 0x10000);
sys_uart_print("Copy dtb from nor ok!\n\r");
/* 1. 从NOR FLASH里把内核读入内存 */
sys_uart_print("Copy kernel from nor\n\r");
volatile unsigned int spi_kernel_start=0x40000;
sys_spi_flash_read(spi_kernel_start, sdram_kernel_start, 0x260000);
sys_uart_print("Copy kernel from nor ok!\n\r");
sys_spi_flash_exit();
/* 2. 设置参数 ,与内核约定参数存放地址,Uboot写个内核的遗嘱^^*/
// puts("Set boot params\n\r");
// setup_start_tag();
// setup_memory_tags();
// setup_commandline_tag("noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0");
// setup_end_tag();
/* 3. 跳转执行 */
sys_uart_print("Boot kernel\n\r");
theKernel = (void (*)(int, int, unsigned int))0x80040000;
theKernel(0, 0, 0x80030000); //362:arm
/*
* mov r0, #0
* ldr r1, =362
* ldr r2, =0x30000100
* mov pc, #0x30008000
*/
sys_uart_print("Error!\n\r");
/* 如果一切正常, 不会执行到这里 */
return 0;
}
问题现象:
离线
取sdram地址搞错了,改成如下:
volatile unsigned int *sdram_dtb_start = (volatile unsigned int *)0x80030000;
volatile unsigned int *sdram_kernel_start = (volatile unsigned int *)0x80040000;
// void *sdram_dtb_start = (void *)0x80030000;
// void *sdram_kernel_start = (void *)0x80040000;
启动kernel还有问题,继续。。。
离线
Copy kernel from nor ok!
这句打印出来了没
离线
Copy kernel from nor ok!
这句打印出来了没
打印了
离线
现在有个疑问:使用设备树作参数引导linux的话,还需要传其他参数给linux吗?我记得uboot中还配置了如下参数:
bootargs修改
勾选 [*] Enable boot arguments;
在下方一项中填入 bootargs 参数:
console=ttyS0,115200 panic=5 rootwait root=/dev/mtdblock3 rw rootfstype=jffs2
离线
从uboot的启动日志看到,uboot对dtb文件做了处理后再放到内存的,还是要分析一下uboot的启动源码:
device 0 offset 0x110000, size 0x400000
SF: 4194304 bytes @ 0x110000 Read: OK
## Flattened Device Tree blob at 80c00000
Booting using the fdt blob at 0x80c00000
Loading Device Tree to 80e4c000, end 80e511c8 ... OK
离线
刚好之前分析过uboot,自己的bootloader成功启动过kernel,楼主参考下
1.
kernel_entry = (void (*)(int, int, u32))0x80000000;
kernel_entry(0, 0, 0x80c00000);
0x80c00000为DTB地址
2.kernel配置时 bootargs要配置为内置,这样bootloader省事多了
3.kernel dts文件加入内存信息,因为目前kernel内存参数靠uboot写dts传,这里我也是卡住了很久,直到将uboot bootz删减到最小才发现
memory_DDR0@80000000 {
device_type = "memory";
reg = <0x80000000 0x2000000>;
};
现在自己的bootloader使用spi dma读取kernel,启动速度缩短到2.xs液晶进界面
离线
刚好之前分析过uboot,自己的bootloader成功启动过kernel,楼主参考下
1.
kernel_entry = (void (*)(int, int, u32))0x80000000;
kernel_entry(0, 0, 0x80c00000);
0x80c00000为DTB地址
2.kernel配置时 bootargs要配置为内置,这样bootloader省事多了
3.kernel dts文件加入内存信息,因为目前kernel内存参数靠uboot写dts传,这里我也是卡住了很久,直到将uboot bootz删减到最小才发现
memory_DDR0@80000000 {
device_type = "memory";
reg = <0x80000000 0x2000000>;
};
现在自己的bootloader使用spi dma读取kernel,启动速度缩短到2.xs液晶进界面
谢谢提醒,可能是内存没初始化,加上试一下。
离线