(三)修改代码
(I)修改代码— 建新板 _ 时钟 _ SDRAM _ UART
两个PLL(phase locked loop):
1.UPLL:用于USB;
2.MPLL:用于CPU及其他外围器件;
2.1 FCLK:CPU提供的时钟信号。在CPU上电后,晶振开始正常工作,此时FCLK=晶振频率,注意此时不存在MPLL,经过PLL电路后,得到MPLL,UPLL。此时FCLK=MPLL。
2.2 HCLK:为AHB总线提供的时钟信号。主要用于高速外设,比如内存控制器,中断控制器,LCD控制器,DMA等。
2.3 PCLK:为APB总线提供的时钟信号。主要用于低速外设,比如看门狗,UART控制器,IIS,I2C,SDI/MMC,GPIO,RTC,SPI等。
新建支持s3c2440开发板的目录和文件
在board目录下,复制smdk2410文件夹为,并修改smdk2440文件夹
中的Makefile在include/configs目录下,复制smdk2410.h为smdk2440.h
修改boards.cfg
配置、编译
将新的uboot.bin烧到开发板Nor Flash中,启动,串口上没反应(肯定不能成功)。
修改SDRAM的配置
将原本在board\samsung\smdk2440\Smdk2440.c文件中board_early_init_f函数下设置的代码屏蔽掉;
修改start.S
将原本的代码改为如图所示(之前自己写的Bootloader中的start.S中的代码)
—(原本代码):
—(修改后):
修改在cpu_init_crit后跳转的lowlevel_init函数(lowlevel_init.S文件)
—(原本代码)
—修改后(之前自己写的Bootloader中的start.S中的代码)
将修改后的3个文件上传到服务器看,重新编译u-boot,并用旧版u-boot烧写新的u-boot
make
先烧写旧版u-boot,再用命令结合dnw烧写新u-boot,重启开发板,乱码(这说明内存可以使用了)。
这里可以用之前的方法:用openjatg检验sdram是否真的可用。
注:参照下面链接
解决乱码问题(主要关心波特率)–修改关于串口配置代码,发现在get _ HCLK里没有定义CONFIG_S3C2440
5.1 找到关于串口配置的函数,并找到设置波特率的代码
start.S文件中:
board _ ini t_ f函数中:
init_sequence数组:
由serial_init函数找到设置波特率函数:
5.2 找到需要的宏,并相应的文件中配置该宏
在smdk2440.h文件中:
5.3 重新配置编译u-boot,出错,解决出错
找到该文件所在文件夹,查看Makefile,找到该文件所依赖的宏:
屏蔽该宏:
编译后若出现如下图错误,还需将smdk2440.h中的部分配置去掉(如下下图)
5.5 再次编译u-boot,烧写新的u-boot(方法与第4步一致)
(II)修改代码—支持NAND启动
在uboot目录board\samsung\smdk2440中添加init.c文件
1.1 将之前自己写的bootloader的代码中的init.c文件添加到uboot目录board\samsung\smdk2440中,然后再si工程中添加该文件;
1.2 修改init.c文件:给该文件中与其他文件重名的函数改名(例:nand _ read -> nand _ read _ ll),只在该文件中使用的函数,前面均加上static。
注:改名后,在调用nand_read函数的函数中,也需将名字改为nand_read_ll
1.3 并在服务器上修改该文件夹下Makefile
注:该文件中copy_code_to_sdram、clear_bss、nand_init_ll是在start.S中需要跳转执行的。
参照之前写的bootloader的代码中start.S文件修改现有的start.S
2.1 修改第一阶段
—(修改前)
—(修改后)
其中清bss段的clear_bss函数也有一处需稍作修改(init.c)
既然我们自己已经重定位了,就不需要board_init_f函数再调用relocate_code(addr_sp, id, addr)
由于我们使用了自己的重定位和清除bss的函数,故将start.S有的代码删去
—修改的链接地址
由于我们已经将链接地址“定死”为0x33f00000,所以也需将board_init_f函数中算得的addr”定死”
—(修改前)
—(修改后)
2.2 修改第二阶段
—(查看第二阶段board_init_r函数,确定其两个参数。第一个参数需要将board_init_f函数改为有返回值的函数,其返回值就是board_init_r的第一个参数)
注:还需将头文件include/Common.hboard_init_f函数的声明修改成一致的
—(经2.1修改)
—(再次修改)
将修改后的文件均上传到服务器上,并在Init.c文件所对应的文件夹下,修改其Makefile,使其编译时生成对应的.o文件
修改的文件:
Init.c (board\samsung\smdk2440)
start.S (arch\arm\cpu\arm920t)
Board.c (arch\arm\lib)
Smdk2440.h (include\configs)
去掉-pie选项:
找到配置pie选项的文件
修改arch/arm/config.mk第75行,注释掉pie
修改链接文件,将start.S、Init.c、lowlevel.S等文件放在最前面:
在服务器上修改arch\arm\cpu目录下的u-boot.lds文件
重新编译,烧写新的uboot.bin
(III)修改代码—支持Nor Flash(读写)
在(I)修改代码–配置SDRAM后,从Nor Flash重启uboot,串口会打印如下图错误;在uboot源码中搜索“Flash:”,找到如图文件,进行分析
初步分析之后,修改Board.c (arch\arm\lib)和Cfi_flash.c (drivers\mtd),作用分别是:屏蔽系统僵死、加打印语句
—屏蔽系统僵死
—Flash初始化函数入口
—进入flash_init函数,并进入检测Flash的新方法函数flash_get_size
—加打印语句
重新编译uboot后,在NOR Flash上烧写uboot-1.16.6,设置NOR启动,用dnw将新的uboot烧到Nor Flash中,重新启动开发板,出现如下图界面
核实上图打印信息的真实性(开发板上使用的Nor Flash型号:MX29LV160DB)
—打印信息:
(插入)在源码中搜索JEDEC PROBE:
—芯片手册:
既然已经读出了设备ID,为什么还会出错呢?
答:这是因为只读出ID还不行,还需与数组中内容匹配。显然这是出错之处。
—进入Flash匹配函数,找到数组
—进入数组
—查看数组内容,只发现与开发板中的Nor Flash相近的一个芯片信息
—故,我们仿照相似的Flash,在数组中添加我们使用的Nor Flash信息
此时,可以将第2步在Cfi_flash.c文件中加的打印去掉
将修改的文件上传服务器,重新编译u-boot,再用旧的u-boot和dnw将新的u-boot烧写到Nor Flash,重新上电从Nor启动,串口打印如下图
在uboot源码中搜索” ERROR: too many flash sectors “,找到出现该错误的出处,并修改相关宏
—原宏
—修改后
将修改后的头文件上传到服务器,重新编译uboot,并重新烧写到Nor Falsh并重上电启动,成功识别所用NOR Flash
通过从sdram的0x30000000地址烧写数据给Nor Flash地址,发现问题–比较的0x30000000数据和已烧写给Nor flash地址的数据不相同–应该是start.S中设置栈的问题!
—经过前面过的start.S
解决措施:重定位之后还要重新设置栈(需在调用第二阶段代码前重新设置栈)
a. 在start.S中定义一个新的栈变量
b. 在board_init_f中,声明汇编中的栈变量,并使用
c. 在调用第二阶段代码前读出新栈
将修改的start.S和board.c文件重新上传服务器,重新编译u-boot,并将新的.bin文件拷贝到本地
a. 在串口上使用loady命令,将新的uboot先烧写到sdram的32000000地址,然后再从该地址拷贝到Nor flash,重新上电
b. 重新上电后,重新从sdram的0x30000000地址烧写数据给Nor Flash地址,检查其正确性
(IV)修改代码—支持Nand Flash(读写)
在修改代码(I)配置SDRAM时,我们当时为了解决编译出错,将配置文件里的宏屏蔽掉了(下图),现在我们要将其恢复(下下图)
上传上面修改的文件,重新编译,出错(如下图)
查看错误提示的文件所在行(s3c2410_nand.c:72),一步步找到定义的结构体 s3c2410_nand。由于之前当时解决编译错误,将配置文件里的支持2410的宏屏蔽掉了
鉴于上述文件(s3c2410_nand.c)是给2410用的,我们决定将其复制为 s3c2440_nand.c文件(之后加入si工程),再修改该文件来支持2440的NAND Flash
复制s3c2440_nand.c文件后,修改该文件下的Makefile
由于依赖于宏CONFIG_NAND_S3C2440,要在配置文件中定义该宏(这里利用已经屏蔽支持2410nand的宏CONFIG_S3C2410作为开关)
从NAND Flash的入口函数开始进行分析,进入board_nand_init函数
5.1 首先,将该文件(S3c2440_nand.c)中关于2410的函数全部修改为2440的;
5.2 初始化时序,使能NAND Flash控制器
从NAND Flash的入口函数开始进行分析,进入nand_scan函数,继而进入nand_scan_ident函数
6.1 进入nand_get_flash_type函数,依次查看下列函数,我们需要根据默认函数进行修改一些文件的代码
— nand_get_flash_type
—默认函数
6.2 选择芯片
6.3 发送命令
—默认发送命令
chip->cmd_ctrl指向的就是s3c2440_nand.c文件中s3c2440_hwcontrol函数
—修改s3c2440_hwcontrol函数
将修改过的文件(s3c2440_nand.c、Makefile、smdk2440.h)都上传服务器,重新编译uboot,并在串口上用loady命令下载到NOR Flash,重上电启动(NOR启动)
在串口上,用nand操作命令将刚才NOR Flash中的uboot写进NAND Flash后,断电,设为NAND启动,重新上电启动开发板(NAND启动)
(V)修改代码—支持DM9000网卡
在uboot源码中搜索”DM9000”,可以找到支持DM9000网卡的代码文件Dm9000x.c (drivers\net),故我们查看该文件夹下的Makefile并修改配置文件(smdk2440.h)将Dm9000x.c编译进uboot,上传文件,重新编译uboot,编译出错
进入出错指示的文件所在行,搜索”DM9000_DATA”,看看别的文件是怎样使用的,在配置文件中仿照其加入宏(该步其实就是确定访问地址)
—其他文件
—再次修改配置文件
/* 下面解释配置文件中的宏的修改过程 */
CONFIG_DM9000_BASE:访问地址,由网卡芯片的片选引脚和内存控制器共同决定(如下图)
DM9000_DATA:由与内存相接的引脚决定,由于DM9000只有一条地址线LADDR2(bit2取1),故在基地址上加4
设置内存控制器(Start.S -> cpu_init_crit -> lowlevel_init)
—原来我们设置的内存控制器
注:其实这里我们使用默认的也是可以编译通过的。
—位宽
—时序
—修改后的内存控制器
上传修改文件(smdk2440.h和lowlevel_init.S),重新编译uboot,编译成功,用loady命令下载新的uboot,并以NOR重上电启动,显示查找网卡失败(如图)
根据错误提示,在源码中搜索”Net:”,找到Board.c文件的所在行(如图),并从网卡初始化函数进去,一路找到smdk2440.c中的board_eth_init函数
仿照支持cs8900初始化,支持dm9000初始化(调用dm9000x.c的初始化函数)
上传修改文件(smdk2440.h和lowlevel_init.S),重新编译uboot,编译成功,用loady命令下载新的uboot,并以NOR重上电启动,成功找到网卡(如图)
插上网线,设置参数,实现ping通
set ipaddr 192.168.0.4
set ethaddr 00:0c:29:07:33:a6
使用tftp工具下载文件
—设置serverip,须跟tftp上的IP一致
set serverip 192.168.0.2
—设置tftp工作目录及工作IP
—下载文件(这里下载所在目录的uImage_4.3文件)
—启动内核(这里不成功的问题,以后解决)