这一篇主要介绍启动过程,结合上一篇会更契合.
分为如下几步,可能会有些许细节漏掉,尽量完善
1. 首先编译Linux内核,得到Image文件,至于如何编译,这类工作资料很多,不赘述。
从这里可看出,此移植过程并未对Linux作任何修改,项目的结果是让linux操作系统运行在特定的嵌入式平台中。
得到的Image文件,就是操作系统了,需要载入内存中,但是目前,Image中的平台中是不支持本硬件环境的,这个就需要写对应平台的支持文件了,这部分暂不表
我们知道,在操作系统之前,有个BIOS,这一篇就是写一个类似BIOS的功能。
2. 新建一个文件夹bootloader/,添加的文件有若干个,主要文件有几个:
~串口相关的文件,就叫serial.c
这个就是调试用的,要不怎么和操作系统交互
~启动文件,就叫start.S
这个需要用汇编写就。硬件平台的功能,就是从某一特定物理地址开始执行程序,那么,这个启动文件就是要执行的代码。
start.S的功能肯定是配置工作了,配置工作做好了,硬件才可以使用。
截取其中一段代码说下:
# start config ddrc .align 5,0x0 ldr r0, =0x01ee8000 mov r1, #0x0 str r1, [r0,#0x1b0]
这个配置ddr-ctl,设置的起始地址是0x01ee8000, 查手册,配置工作就是设置其值
3. serial.c
当配置工作做好了之后,就需要编写串口程序了
unsigned int readl(unsigned int addr) { return *(volatile unsigned int *)(addr); } void writel(unsigned int lval, unsigned int addr) { *(volatile unsigned int *)(addr) = lval; }这个就实现了最简单基本的功能,到特定物理地址去读或写,很简单
那么读取串口数据就是:
void uart_putc(unsigned char c) { while(!(readl(UART_STATE)&0x60)); *(unsigned char *)(UART_BASE) = c; } void uart_puts(char *str) { char c; char *s = str; while(1) { c =*(s); if(c == ' ') break; uart_putc(c); if(c == ' ') { uart_putc(' '); } s++; } }输出字符和字符串
对应的还有其它类似功能的函数。
当我们调试的时候,想打印一个字符或信息,我们就可以调用写函数,然后让其打印出来
当然,目前最高级的调试就只能是这样了
先到这里...待续