u-boot

Bootloader(我们用的是uboot)相当于PC中的BIOS,作用是引导操作系统(linux内核),然后识别C盘等(挂载根文件系统),然后运行上面的应用程序。最终目的:启动内核

使用:解压缩、打补丁、配置、编译
配置过程make 100ask24x0_config:分析makefile文件,相当于执行顶层目录下的mkconfig脚本(./mkconfig smdk2410 arm arm920t smdk2410 NULL s3c24x0)。mkconfig的作用:1)确定开发板名称($1) 2)创建到平台/开发板相关的头文件链接($2$6) 3)创建顶层Makefile包含的文件include/config.mk($2-$6 ARCH/CPU/BOARD/VENDOR/SOC) 4)创建开发板相关的头文件include/config.h($6.h配置文件)
编译过程make:分析makefile文件,包含配置过程生成的include/config.mk,确定交叉编译链。包含顶层目录的config.mk,它根据配置生成的4个变量确定编译器、编译选项等,编译选项中指定连接脚本和代码段基地址(33f80000 64M前512k)。 1)首先编译cpu/(CPU)/start.S 2)对于平台/开发板相关的每个目录用各自的makefile生成相应的库 3)将1、2生成的文件按照代码段起始地址和连接脚本进行连接 4)将elf格式的uboot生成二进制格式

目的:启动内核 读写flash、初始化SDRAM、启动内核

第一阶段(汇编):1)硬件设备初始化(CPU设为管理模式、关看门狗、屏蔽中断、关MMU/Cache、设置时钟)2)初始化SDRAM 3)重定位、清bss段 4)设置栈(sp指向一块内存) 5)跳转到第二阶段

第二阶段(c):1)初始化硬件设备(flash、串口、网卡、USB等) 2)检测系统内存映射、环境变量初始化 3)uboot命令 4)为内核设置启动参数

bios界面系统找不到了_bios界面系统找不到了


最后是个main_loop循环,启动内核是getenv(“bootcmd”),bootcmd是设置的环境变量启动命令(nand read.jffs2 0x30007FC0 kernel; bootm 0x30007FC0)。readline读入串口数据,run_command执行命令。

核心:命令
Bootloader有两种操作模式:启动加载模式和下载模式,在下载模式中就是使用uboot的各种命令下载文件。uboot里有U_BOOT_CMD宏,参数有名字、处理函数名、使用说明等。在连接脚本里可以看到u_boot_cmd段,所有的命令都是用特殊的U_BOOT_CMD宏定义,有特殊的段属性,我们也可以根据相应的格式定义自己的命令,如下载uboot、内核、文件系统等菜单。
启动命令:nand read.jffs2 0x30007FC0 kernel; bootm 0x30007FC0
nand read.jffs2 0x30007FC0 kernel 从flash读出内核,Flash没有分区,它是在代码(include/100ask2410.h配置文件)里写死的,名字不重要,重要的是起始地址和大小,mtd查看分区。256k(bootloader)128k(params)2m(kernel)-(root)
bootm 0x30007FC0 1)根据头部移动内核到合适的地方uImage=64byte头部+真正内核,头部里有加载地址和入口地址。bootm+地址,启动时如果真正内核不在加载地址要移动,为了不移动所以地址比较奇怪。2)启动do_bootm_linux 1.uboot设置启动参数告诉内核 2.跳到入口地址启动内核
设置启动参数(在某个地址按某种格式保存数据:taglist标记列表,tag结构体):开始tag、内存tag、命令行tag(bootargs)、结束tag等。其中commondline = getenv(bootargs),bootargs=noinitrd root=/dev/mtdblocks3 init=/linuxrc console=ttySAC0。thekernel(0,bd->bi_arch_number机器ID,bd->bi_boot_params启动参数基地址)启动。

移植2012.04.1

修改交叉编译工具链为arm-linux-gcc-4.3.2,修改环境变量用export PATH
重定位就是把程序复制到链接地址(2012的连接地址是0,程序应该位于的地方,否则访问全局变量或静态变量会出错),前面的能运行是用位置无关码写的,复制过去后能执行要修改各个变量、函数使用新地址。编译时加上了-pie,生成位置无关可执行程序,生成旧地址信息保存在rel和dynsym段里面,可以根据信息改变地址。

1 新建一个开发板的相应目录和文件。基于最接近的单板s3c2410 复制board目录,还要在include/configs目录下建立配置文件smdk2440.h

2 UBOOT里先以60MHz的时钟计算参数来设置内存控制器(系统时钟12Mhz,设置SDRAM内存控制器用到刷新频率等时间参数,它基于的HCLK=60MHz,但是后面才去设置系统时钟,然后还用了SDRAM中的栈,在board_init_f里才设置时钟,不合理),但是MPLL还未设置。
处理措施: 把MPLL的设置放到Start.S里,取消board_early_init_f里对MPLL的设置。(board_init_f在board.c里init_sequence 到board_early_init_f,注释掉对MPLL的设置)。将自己写uboot的时钟设置和SDRAM设置部分替换过来,自己设置时钟400MHz、异步模式

3 乱码,查看串口波特率的设置(Serial_s3c24x0.c),发现get_HCLK里没有配有配置宏CONFIG_S3C2440,使用的是宏CONFIG_S3C2410,。
处理措施:include/configs/smdk2440.h配置文件里去掉CONFIG_S3C2410,#define CONFIG_S3C2440。

4 2012使用了pie选项,使得代码变大(多了地址信息)不利于从Nand启动(<4k),重定位复杂。
处理措施:用老方法重定位,去掉-pie编译选项,把连接地址定死33f00000(前面分析了内存分配,确定代码段基地址,1M超过了512k),而且重定位代码中的ldmia、stmia等指令不适用于nand启动(nand读写用命令)。自己写重定位代码清bss段和有关于nand的操作。

5 支持Norflash
定义宏DEBUG,打印调试信息。Nor操作简单,类似内存,只需要确定基地址和位宽,然后内核会发出各种命令,在协议层已经做好了。发现在Nor的匹配型号jedec_table[]数组里没有这款芯片的参数,自己添加这个结构体(厂家id,设备id,解锁地址,容量,命令集,扇区结构(8k,16k,32k,64k的个数)等)。

6 支持Nandflash
定义CONFIG_S3C2440的宏开关来使用s3c2440_nand寄存器结构体,复制一份s3c2410_nand.c的文件来修改。2410和2440的Nand寄存器有点区别,要修改。Nand会设置默认的操作函数,查看默认函数中有的不符合(select_chip, cmdfunc, read_byte等)需要自己提供这些函数。

7 支持Dm9000
Uboot支持dm9000网卡,但是用的是cs8900网卡,所以在smdk2440.h配置文件中注释掉cs8900相关的宏,定义宏CONFIG_DRIVER_DM9000,然后还要参考其它单板的配置文件添加宏参数CONFIG_DM9000_BASE、DM9000_IO、DM9000_DATA,要修改这些值。 网卡是内存类接口,要设置内存控制器访问地址和时序位宽。

bios界面系统找不到了_重定位_02


网卡接的是nGCS4,CONFIG_DM9000_BASE就是0x20000000。地址线只有LADDR2接到CMD,DM9000_IO和DM9000_DATA,只关心LADDR2,bit2就是4,DM9000_IO=CONFIG_DM9000_BASE,DM9000_DATA=(CONFIG_DM9000_BASE+4)。设置内存控制器中的BANK4,位宽16,没有wait信号,设置访问时序。网卡初始化的是cs8900,仿造其它单板使用dm9000网卡的初始化函数dm9000_initialize(bis),注意修改参数和返回值。

8 没有设置默认的环境变量(params分区)
在env_common.c文件里有default_environment数组,可以在smdk2440.h文件里定义这些宏设置环境变量bootargs、bootcmd、bootdelay等,修改默认的ipaddr、ethaddr、serverip。
在smdk2440.h文件仿造原来的定义宏CONFIG_ENV_IS_IN_NAND,CONFIG_ENV_OFFSET 0x40000,CONFIG_ENV_SIZE 0x20000.

9 易用性修改,把uboot改小点
在smdk2440.h配置文件中注释掉宏开关USB、RTC、文件系统等,最后uboot为两百多k。

10 分区
在smdk2440.h中定义宏MTDPARTS_DEFAULT “mtdparts=jz2440-0:256k(uboot),128k(params),2m(kernel),-(rootfs)”确定分区信息。

11 支持烧写文件系统
Jffs2文件系统可以支持,Yaffs文件系统不支持
处理措施:在smdk2440.h里定义宏CONFIG_CMD_NAND_YAFFS,但还是找不到Init程序,程序中写oob的函数返回值要非零才返回,搞反了,导致只写了一页数据。