day44-系统移植bootloader

day44-系统移植bootloader

一、bootloader简介

  就是在操作系统内核运行之前运行的一段小程序。通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境,他就是所谓的引导加载程序(Boot Loader)。

  BootLoader的任务是引导操作系统,所谓引导操作系统,就是启动内核,让内核运行就是把内核加载到内存RAM中去运行,那先问两个问题:第一个问题,是谁把内核搬到内存中去运行?第二个问题:我们说的内存是SDRAM,大家都知道,这种内存和SRAM不同,最大的不同就是SRAM只要系统上电就可以运行,而SDRAM需要软件进行初始化才能运行,那么在把内核搬运到内存运行之前必须要先初始化内存吧,那么内存是由谁来初始化的呢?其实这两件事情都是由bootloader来干的,目的是为内核的运行准备好软硬件环境,没有bootloadr我们的系统当然不能跑起来。

  BootLoader种类众多,其中u-boot使用较为广泛

① 开放源码;
② 支持多种嵌入式操作系统内核,如Linux、NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS;
③ 支持多个处理器系列,如PowerPC、ARM、x86、MIPS、XScale;
④ 较高的可靠性和稳定性;
⑤ 高度灵活的功能设置,适合U-Boot调试、操作系统不同引导要求、产品发布等;
⑥ 丰富的设备驱动源码,如串口、以太网、SDRAM、FLASH、LCD、NVRAM、EEPROM、RTC、键盘等;
⑦ 较为丰富的开发调试文档与强大的网络技术支持;




二、 u-boot

2.1 u-boot结构

Directory Description
API 存储U-Boot提供的接口函数
arch 与体系结构相关的代码,是核心文件夹
board 基于不同具体开发板的自定义代码
common 通用代码,涵盖所有方面,以处理命令行为主
disk 与分区相关的代码
doc 常见特性和问题描述的文档
drivers 常用设备驱动程序,每种类型的设备驱动程序都占用一个子目录
fs 文件系统,支持嵌入式开发常用的文件系统(CRAMFS,EXT2,EXT3,JFFS2等)
include 定义了全局需要的头文件
lib 通用库文件
net 网络相关代码,小型协议栈
post 上电自检
tools 辅助工具,用于编译和检查uboot目标文件

2.2 u-boot命令

pri:显示
set:设置
save:保存
tftp:下载
loadb:kermit协议下载二进制
movi:emmc写入/读取
boot:启动

bootcmd:启动命令
bootargs:启动参数

2.3 u-boot工作模式

  U-Boot的工作模式有启动加载模式和下载模式。启动加载模式是Bootloader的正常工作模式,嵌入式产品发布时,Bootloader必须工作在这种模式下,Bootloader将嵌入式操作系统从FLASH中加载到SDRAM中运行,整个过程是自动的。下载模式就是Bootloader通过某些通信手段将内核映像或根文件系统映像等从PC机中下载到目标板的SDRAM中运行,用户可以利用Bootloader提供的一些令接口来完成自己想要的操作,这种模式主要用于测试和开发。




三、 启动流程

启动模式包含:自启动和交互模式,正常使用是自启动模式。

  大多数BootLoader都分为stage1和stage2两大部分,U-boot也不例外。依赖于cpu体系结构的代码(如设备初始化代码等)通常都放在stage1且可以用汇编语言来实现,而stage2则通常用C语言来实现,这样可以实现复杂的功能,而且有更好的可读性和移植性。

  1. stage1(start.s代码结构)

U-boot的stage1代码通常放在start.s文件中,它用汇编语言写成,其主要代码部分如下:

  • 定义入口。由于一个可执行的image必须有一个入口点,并且只能有一个全局入口,通常这个入口放在rom(Flash)的0x0地址,因此,必须通知编译器以使其知道这个入口,该工作可通过修改连接器脚本来完成。
  • 设置异常向量,设置SVC模式,关闭MMU Cache
  • 设置CPU的速度、时钟频率及中断控制寄存器。
  • 初始化内存控制器 。
  • 将rom中的程序复制到ram中。
  • 初始化堆栈 。
  • 转到ram中执行,该工作可使用指令ldrpc来完成。
  1. stage2(C语言代码部分)

lib_arm/board.c中的start armboot是C语言开始的函数,也是整个启动代码中C语言的主函数,同时还是整个u-boot(armboot)的主函数,该函数主要完成如下操作:

  • 调用一系列的初始化函数。
  • 初始化flash设备。
  • 初始化系统内存分配函数。
  • 如果目标系统拥有nand设备,则初始化nand设备。
  • 如果目标系统有显示设备,则初始化该类设备。
  • 初始化相关网络设备,填写ip,c地址等。
  • 进入命令循环(即整个boot的工作循环),接受用户从串口输入的命令,然后进行相应的工作。



四、u-boot移植

已配置好的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
0、注释配置文件中的中文设置, 在下面三行加#
# sudo vim ~/.bashrc
#export LANG=LANG="zh_CN.utf-8"
#export LANGUAGE="zh_CN:zh:en_US:en"
#export LC_ALL="zh_CN.utf-8"

1、解压day2中的u-boot-2013.01-fs4412.tar.bz2
tar -xvf u-boot-2013.01-fs4412.tar.xz

2、拷贝day2下的build.sh到解压的目录下,替换原有的目录

3、进入u-boot-2013.01-fs4412,执行build.sh
./build.sh
注: 如果Flash不是三星的,则需要根据FS4412兼容高版本eMMC.pdf更改emmc配置

4、验证u-boot.bin
1) 将生成的u-boot-fs4412.bin文件拷贝到tftp共享目录中;
cp u-boot-fs4412.bin /tftpboot
2) 通过sd方式将生产uboot烧写到mmc中;
将拨码开关拨到sd启动方式,启动开发板进入到交互模式:
tftp 41000000 u-boot-fs4412.bin
movi write u-boot 41000000
将拨码开关拨到emmc启动方式,观察现象,启动成功

未配置好的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
0、 将官方的uboot下载下来,在boot中的`makefile`中搜索`CROSS_COMPILE`指定架构(如arm)和交叉编译工具链(如arm-none-linux-gnueabi)
1、借鉴origen板子的信息; find . -name origen*
拷贝板子头文件信息:
cp include/configs/origen.h include/configs/fs4412.h
拷贝并且修改板级文件:
cp board/samsung/origen/ board/samsung/fs4412 -afr
mv board/samsung/fs4412/origen.c board/samsung/fs4412/fs4412.c

修改board/samsung/fs4412/Makefile的目标文件:
vim board/samsung/fs4412/Makefile
将 31行 的 origen.o 修改为 fs4412.o

修改u-boot目录下板级配置文件 boards.cfg
在origen后面添加新行fs4412
284 origen arm armv7 origen samsung exynos
285 fs4412 arm armv7 fs4412 samsung exynos

重新编译:烧写到emmc启动开发板,
@make distclean //清除原有的配置文件和生产的文件
@make fs4412_config //添加现有板子的配置文件
@make //编译uboot
-->生产u-boot.bin
@cp u-boot.bin /tftpboot //将生成的u-boot.bin拷贝到tftp共享文件中;

将拨码开关拨到100x SD启动
#tftp 41000000 u-boot.bin //在目标机上下载u-boot到41000000
#movi write u-boot 41000000 //将41000000地址空间的数据写入到uboot对应的位置

将拨码开关拨到011x emmc启动
观察现象:串口没有数据输出,板子没有任何反应;(板砖)

分析原因:uboot是否执行:
解决办法: 通过点灯的方式验证uboot是否执行

2、 在 arch/arm/cpu/armv7/start.S 文件中添加点灯代码:
136 /* led on */
137 ldr r0, =0x11000c40 @GPK2_7 led2
138 ldr r1, [r0]
139 bic r1, r1, #0xf0000000
140 orr r1, r1, #0x10000000
141 str r1, [r0]
142
143 ldr r0, =0x11000c44
144 mov r1,#0xff
145 str r1, [r0]

重新编译:将uboot烧写到emmc,通过emmc启动开发板
@make //编译uboot
-->生产u-boot.bin
@cp u-boot.bin /tftpboot //将生成的u-boot.bin拷贝到tftp共享文件中;

将拨码开关拨到100x SD启动
#tftp 41000000 u-boot.bin //在目标机上下载u-boot到41000000
#movi write u-boot 41000000 //将41000000地址空间的数据写入到uboot对应的位置


串口没有数据输出,led并未被点亮;(板砖) --> uboot并未被执行;
分析原因:与板子的启动有关系;
解决办法:查看芯片手册,看启动流程,需要添加启动代码:BL1、BL2
1) 将CodeSign4SecureBoot 三星提供的安全启动方式拷贝uboot的目录中;
2) 进入到CodeSign4SecureBoot目录中修改build.sh文件中cp对应行
cp u.bin /tftpboot
3) 重新编译 执行build.sh
编译的同时将生产的u.bin拷贝到tftp共享文件中;
4) 通过sd启动方式将uboot烧写到emmc
将拨码开关拨到100x SD启动
#tftp 41000000 u.bin //在目标机上下载u-boot到41000000
#movi write u-boot 41000000 //将41000000地址空间的数据写入到uboot对应的位置
5) 通过emmc启动开发板
将拨码开关拨到011x emmc启动
观察现象:串口没有数据输出,led亮了,等一会灭了,又亮了,在等会led亮了,等一会灭了,又亮了 ……
分析原因:看门狗是否关闭、中断是否关闭、其它;
通过排除的方式,看门狗和中断没有问题,而是电源控制单元的问题
驱动电路过流或过热保护了。你这情况一般都是过热保护,驱动电路板散热不好,元件过热,电路就会自动断来,等温度降下来后,又再次启动。

解决办法:添加电源管理相关代码,关闭看门狗
1) 代码修改
vim arch/arm/cpu/armv7/start.S中添加
147 /*for close watchdog */
148 /* PS-Hold high */
149 ldr r0, =0x1002330c /*PS_HOLD_CONTROL*/
150 ldr r1, [r0]
151 orr r1, r1, #0x300
152 str r1, [r0]
153 ldr r0, =0x11000c08
154 ldr r1, =0x0 /*Disables Pull-up/Pull-down*/
155 str r1, [r0]
156 /* Clear MASK_WDT_RESET_REQUEST */
157 ldr r0, =0x1002040c
158 ldr r1, =0x00
159 str r1, [r0]
2) 重新编译:
cd CodeSign4SecureBoot
./build.sh
--> 生成的u.bin文件存储在tftp共享文件中

3) 通过sd启动方式将uboot烧写到emmc
将拨码开关拨到100x SD启动
#tftp 41000000 u.bin //在目标机上下载u-boot到41000000
#movi write u-boot 41000000 //将41000000地址空间的数据写入到uboot对应的位置
4) 通过emmc启动开发板
将拨码开关拨到011x emmc启动
重新观察结果: led常亮(说明uboot正常执行),但是串口依然没有数据输出;
分析原因:串口初始化有问题,通过代码跟踪(串口时钟初始化的问题);
解决办法:
1) 添加串口时钟初始化代码:board/samsung/fs4412/lowlevel_init.S
vim board/samsung/fs4412/lowlevel_init.S

在串口初始化代码中的
str r1, [r0, #EXYNOS4_GPIO_A1_CON_OFFSET]
后面添加
338 /* 添加串口相关的时钟初始化 */
339 ldr r0, =EXYNOS4_CLOCK_BASE /*system_clock_init*/
340
341 ldr r1, =CLK_SRC_PERIL0_VAL /*uart[0:4]*/
342 ldr r2, =CLK_SRC_PERIL0_OFFSET
343 str r1, [r0, r2]
344
345 ldr r1, =CLK_DIV_PERIL0_VAL /*uart clock divisors*/
346 ldr r2, =CLK_DIV_PERIL0_OFFSET
347 str r1, [r0, r2]
并且把串口初始化后面的
#if 0
90 bl tzpc_init
#endif
屏蔽掉

2) 重新编译:
cd CodeSign4SecureBoot
./build.sh
--> 生成的u.bin文件存储在tftp共享文件中

3) 通过sd启动方式将uboot烧写到emmc
将拨码开关拨到100x SD启动
#tftp 41000000 u.bin //在目标机上下载u-boot到41000000
#movi write u-boot 41000000 //将41000000地址空间的数据写入到uboot对应的位置
4) 通过emmc启动开发板
将拨码开关拨到011x SD启动

【网卡移植】
网卡移植请参考 网络.doc文件

网卡移植:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
1、	添加网络初始化代码
$vim board/samsung/fs4412/fs4412.c


在struct exynos4_gpio_part2 *gpio2; 后添加:

#ifdef CONFIG_DRIVER_DM9000
#define EXYNOS4412_SROMC_BASE 0X12570000

#define DM9000_Tacs (0x1)
#define DM9000_Tcos (0x1)
#define DM9000_Tacc (0x5)
#define DM9000_Tcoh (0x1)
#define DM9000_Tah (0xC)
#define DM9000_Tacp (0x9)
#define DM9000_PMC (0x1)

struct exynos_sromc {
unsigned int bw;
unsigned int bc[6];
};

/*
* s5p_config_sromc() - select the proper SROMC Bank and configure the
* band width control and bank control registers
* srom_bank - SROM
* srom_bw_conf - SMC Band witdh reg configuration value
* srom_bc_conf - SMC Bank Control reg configuration value
*/
void exynos_config_sromc(u32 srom_bank, u32 srom_bw_conf, u32 srom_bc_conf)
{
unsigned int tmp;
struct exynos_sromc *srom = (struct exynos_sromc *)(EXYNOS4412_SROMC_BASE);

/* Configure SMC_BW register to handle proper SROMC bank */
tmp = srom->bw;
tmp&= ~(0xF << (srom_bank * 4));
tmp |= srom_bw_conf;
srom->bw = tmp;

/* Configure SMC_BC register */
srom->bc[srom_bank] = srom_bc_conf;
}
static void dm9000aep_pre_init(void)
{
unsigned int tmp;
unsigned char smc_bank_num = 1;
unsigned int smc_bw_conf=0;
unsigned int smc_bc_conf=0;

/* gpio configuration */
writel(0x00220020, 0x11000000 + 0x120);
writel(0x00002222, 0x11000000 + 0x140);
/* 16 Bit bus width */
writel(0x22222222, 0x11000000 + 0x180);
writel(0x0000FFFF, 0x11000000 + 0x188);
writel(0x22222222, 0x11000000 + 0x1C0);
writel(0x0000FFFF, 0x11000000 + 0x1C8);
writel(0x22222222, 0x11000000 + 0x1E0);
writel(0x0000FFFF, 0x11000000 + 0x1E8);
smc_bw_conf &= ~(0xf<<4);
smc_bw_conf |= (1<<7) | (1<<6) | (1<<5) | (1<<4);
smc_bc_conf = ((DM9000_Tacs << 28)
| (DM9000_Tcos << 24)
| (DM9000_Tacc << 16)
| (DM9000_Tcoh << 12)
| (DM9000_Tah << 8)
| (DM9000_Tacp << 4)
| (DM9000_PMC));
exynos_config_sromc(smc_bank_num,smc_bw_conf,smc_bc_conf);
}
#endif


在gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100UL); 后添加

#ifdef CONFIG_DRIVER_DM9000
dm9000aep_pre_init();
#endif

在文件末尾添加:

#ifdef CONFIG_DRIVER_DM9000
int board_eth_init(bd_t *bis)
{
return dm9000_initialize(bis);

}
#endif

2、 修改配置文件添加网络相关配置
$ vim include/configs/fs4412.h
修改
#undef CONFIG_CMD_PING

#def ine CONFIG_CMD_PING

修改
#undef CONFIG_CMD_NET

#def ine CONFIG_CMD_NET

在文件末尾
#ifdef CONFIG_CMD_NET
#define CONFIG_NET_MULTI
#define CONFIG_DRIVER_DM9000 1
#define CONFIG_DM9000_BASE 0x05000000
#define DM9000_IO CONFIG_DM9000_BASE
#define DM9000_DATA (CONFIG_DM9000_BASE + 4)
#define CONFIG_DM9000_USE_16BIT
#define CONFIG_DM9000_NO_SROM 1
#define CONFIG_ETHADDR 11:22:33:44:55:66
#define CONFIG_IPADDR 192.168.9.233
#define CONFIG_SERVERIP 192.168.9.120
#define CONFIG_GATEWAYIP 192.168.9.1
#define CONFIG_NETMASK 255.255.255.0
#endif

3、 重新进入CodeSign4SecureBoot编译u-boot
$ ./build.sh
烧写新的u.bin

最后复位


注意要修改对应的IP地址

Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2020-2024 nakano-mahiro
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信