uboot移植(uboot2024.4移植)
imx6ull板子为例:
下载源码:https://github.com/nxp-imx/uboot-imx/tree/lf_v2024.04
注意设备树的语法最后要空行
1、编译
拿到源码后,先编译一遍和自己要移植的板子所用的芯片匹配的配置文件。如我这里用的是imx6ull的板子,就需要编译imx6ull的配置文件。编译过后,需要改的目录下生成了一些文件,可以按照文件去判定编译的配置文件是否和自己板子匹配。
1 | !/bin/bash |
2、查看u-boot.map文件
编译完成后,会在u-boot-2024.04/build/目录下生成u-boot.bin文件,这个文件就是我们最终要烧写的文件。
查看uboot.map文件,可以知道参与编译的文件。
3、烧写到板子上
烧写到板子上,观察有无打印,没打印的,需要检查是否编译的配置文件和自己板子匹配。
一般串口优先使用原厂的串口,如果不行,再尝试其他的串口。
4、修改配置文件
将配置文件改为自己的配置文件。mx6ull_14x14_emmc_naro_defconfig、改为自己的配置文件,如mx6ull_14x14_naro_emmc_defconfig。文件存在于uboot/configs/目录下。
这个文件中主要改这几条:
第一条:设备树的名字
1
CONFIG_DEFAULT_DEVICE_TREE="imx6ull-14x14-evk-emmc"
改为:
1
CONFIG_DEFAULT_DEVICE_TREE="imx6ull-14x14-naro-emmc"
第二条:这个开发版编译的一个条件,存在于uboot/board/freescale/imx6ullevk中
1
CONFIG_TARGET_MX6ULL_14X14_EVK=y
改为:
1
CONFIG_TARGET_MX6ULL_14X14_NARO=y
还有一条网络后面说。
5、修改板级文件
复制一份mx6ullevk,改为自己的板子名,如mx6ullnaro
将mx6ullevk.c文件改为自己的板子名,如mx6ullnaro.c
更改Kconfig文件,添加自己的板子名。
原文:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19if TARGET_MX6ULL_14X14_EVK || TARGET_MX6ULL_9X9_EVK
config SYS_BOARD
default "mx6ullevk"
config SYS_VENDOR
default "freescale"
config SYS_CONFIG_NAME
default "mx6ullevk"
config IMX_CONFIG
default "board/freescale/mx6ullevk/imximage.cfg"
config TEXT_BASE
default 0x87800000
endif改为自己的,前面的配置就是在这里用了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18if TARGET_MX6ULL_14X14_NARO
config SYS_BOARD
default "mx6ullnaro"
config SYS_VENDOR
default "freescale"
config SYS_CONFIG_NAME
default "mx6ullnaro"
config IMX_CONFIG
default "board/freescale/mx6ullnaro/imximage.cfg"
config TEXT_BASE
default 0x87800000
endif就是一些条件编译宏
更改MAINTAINERS文件:
原文:1
2
3
4
5
6
7
8MX6ULLEVK BOARD
M: Peng Fan <peng.fan@nxp.com>
S: Maintained
F: board/freescale/mx6ullevk/
F: include/configs/mx6ullevk.h
F: configs/mx6ull_14x14_evk_defconfig
F: configs/mx6ull_14x14_evk_plugin_defconfig
F: configs/mx6ulz_14x14_evk_defconfig这段代码描述了MX6ULL NARO开发板的相关维护信息和配置文件路径。具体说明如下:
M: 维护者信息,Peng Fan peng.fan@nxp.com。
S: 当前状态为“Maintained”,表示该板子正在维护中。
F: 列出了与MX6ULL NARO开发板相关的配置文件路径,包括:
board/freescale/mx6ullevk/
include/configs/mx6ullevk.h
configs/mx6ull_14x14_evk_defconfig
configs/mx6ull_14x14_evk_plugin_defconfig
configs/mx6ulz_14x14_evk_defconfig
这些文件定义了开发板的硬件配置和启动参数。
改为自己的:
1 | MX6ULLNARO BOARD |
更改Makefile文件:
原文:1
2
3
4# SPDX-License-Identifier: GPL-2.0+
# (C) Copyright 2016 Freescale Semiconductor, Inc.
obj-y := mx6ullevk.o改为自己的:
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415# SPDX-License-Identifier: GPL-2.0+
# (C) Copyright 2016 Freescale Semiconductor, Inc.
obj-y := mx6ullnaro.o
```
更改mx6ullalpha.c文件:
原文:
```C
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2016 Freescale Semiconductor, Inc.
* Copyright 2017 NXP
*/
#include <init.h>
#include <asm/arch/clock.h>
#include <asm/arch/iomux.h>
#include <asm/arch/imx-regs.h>
#include <asm/arch/crm_regs.h>
#include <asm/arch/mx6-pins.h>
#include <asm/arch/sys_proto.h>
#include <asm/global_data.h>
#include <asm/gpio.h>
#include <asm/mach-imx/iomux-v3.h>
#include <asm/mach-imx/boot_mode.h>
#include <asm/mach-imx/mxc_i2c.h>
#include <asm/io.h>
#include <common.h>
#include <env.h>
#include <fsl_esdhc_imx.h>
#include <i2c.h>
#include <miiphy.h>
#include <linux/sizes.h>
#include <linux/delay.h>
#include <mmc.h>
#include <miiphy.h>
#include <power/pmic.h>
#include <power/pfuze3000_pmic.h>
#include "../common/pfuze.h"
DECLARE_GLOBAL_DATA_PTR;
// 定义I2C引脚控制寄存器的配置
#define I2C_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \
PAD_CTL_ODE)
// 定义LCD引脚控制寄存器的配置
#define LCD_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | PAD_CTL_PUE | \
PAD_CTL_PKE | PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm)
// 定义GPMI NAND引脚控制寄存器的配置
#define GPMI_PAD_CTRL0 (PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP)
#define GPMI_PAD_CTRL1 (PAD_CTL_DSE_40ohm | PAD_CTL_SPEED_MED | \
PAD_CTL_SRE_FAST)
#define GPMI_PAD_CTRL2 (GPMI_PAD_CTRL0 | GPMI_PAD_CTRL1)
#ifdef CONFIG_DM_PMIC
// 初始化电源管理IC(PMIC)
int power_init_board(void)
{
struct udevice *dev;
int ret, dev_id, rev_id;
unsigned int reg;
// 获取PFUZE3000 PMIC设备
ret = pmic_get("pfuze3000@8", &dev);
if (ret == -ENODEV)
return 0; // 如果设备不存在,返回0
if (ret != 0)
return ret; // 如果获取设备失败,返回错误码
// 读取PMIC的设备ID和修订ID
dev_id = pmic_reg_read(dev, PFUZE3000_DEVICEID);
rev_id = pmic_reg_read(dev, PFUZE3000_REVID);
printf("PMIC: PFUZE3000 DEV_ID=0x%x REV_ID=0x%x\n", dev_id, rev_id);
// 禁用待机模式期间的低功耗模式
reg = pmic_reg_read(dev, PFUZE3000_LDOGCTL);
reg |= 0x1;
pmic_reg_write(dev, PFUZE3000_LDOGCTL, reg);
// 设置SW1B的上升时间从2us到4us/25mV
pmic_reg_write(dev, PFUZE3000_SW1BCONF, 0x40);
// 设置SW1B模式为APS/PFM
pmic_reg_write(dev, PFUZE3000_SW1BMODE, 0xc);
// 设置SW1B待机电压为0.975V
pmic_reg_write(dev, PFUZE3000_SW1BSTBY, 0xb);
return 0;
}
#ifdef CONFIG_LDO_BYPASS_CHECK
// 设置LDO旁路模式
void ldo_mode_set(int ldo_bypass)
{
unsigned int value;
u32 vddarm;
struct udevice *dev;
int ret;
// 获取PFUZE3000 PMIC设备
ret = pmic_get("pfuze3000@8", &dev);
if (ret == -ENODEV) {
printf("No PMIC found!\n");
return;
}
// 切换到LDO旁路模式
if (ldo_bypass) {
prep_anatop_bypass();
// 将VDDARM电压降低到1.275V
value = pmic_reg_read(dev, PFUZE3000_SW1BVOLT);
value &= ~0x1f;
value |= PFUZE3000_SW1AB_SETP(12750);
pmic_reg_write(dev, PFUZE3000_SW1BVOLT, value);
set_anatop_bypass(1);
vddarm = PFUZE3000_SW1AB_SETP(11750);
value = pmic_reg_read(dev, PFUZE3000_SW1BVOLT);
value &= ~0x1f;
value |= vddarm;
pmic_reg_write(dev, PFUZE3000_SW1BVOLT, value);
finish_anatop_bypass();
printf("switch to ldo_bypass mode!\n");
}
}
#endif
#endif
// 初始化DRAM
int dram_init(void)
{
gd->ram_size = imx_ddr_size(); // 获取DDR内存大小
return 0;
}
// 获取MMC设备编号
int board_mmc_get_env_dev(int devno)
{
return devno;
}
#ifdef CONFIG_FSL_QSPI
#ifndef CONFIG_DM_SPI
// 定义QuadSPI引脚控制寄存器的配置
#define QSPI_PAD_CTRL1 \
(PAD_CTL_SRE_FAST | PAD_CTL_SPEED_MED | \
PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_47K_UP | PAD_CTL_DSE_120ohm)
// QuadSPI引脚配置数组
static iomux_v3_cfg_t const quadspi_pads[] = {
MX6_PAD_NAND_WP_B__QSPI_A_SCLK | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
MX6_PAD_NAND_READY_B__QSPI_A_DATA00 | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
MX6_PAD_NAND_CE0_B__QSPI_A_DATA01 | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
MX6_PAD_NAND_CE1_B__QSPI_A_DATA02 | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
MX6_PAD_NAND_CLE__QSPI_A_DATA03 | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
MX6_PAD_NAND_DQS__QSPI_A_SS0_B | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
};
#endif
// 初始化QuadSPI
static int board_qspi_init(void)
{
#ifndef CONFIG_DM_SPI
// 设置QuadSPI引脚
imx_iomux_v3_setup_multiple_pads(quadspi_pads,
ARRAY_SIZE(quadspi_pads));
#endif
// 启用QuadSPI时钟
enable_qspi_clk(0);
return 0;
}
#endif
#ifdef CONFIG_NAND_MXS
// NAND引脚配置数组
static iomux_v3_cfg_t const nand_pads[] = {
MX6_PAD_NAND_DATA00__RAWNAND_DATA00 | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
MX6_PAD_NAND_DATA01__RAWNAND_DATA01 | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
MX6_PAD_NAND_DATA02__RAWNAND_DATA02 | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
MX6_PAD_NAND_DATA03__RAWNAND_DATA03 | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
MX6_PAD_NAND_DATA04__RAWNAND_DATA04 | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
MX6_PAD_NAND_DATA05__RAWNAND_DATA05 | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
MX6_PAD_NAND_DATA06__RAWNAND_DATA06 | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
MX6_PAD_NAND_DATA07__RAWNAND_DATA07 | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
MX6_PAD_NAND_CLE__RAWNAND_CLE | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
MX6_PAD_NAND_ALE__RAWNAND_ALE | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
MX6_PAD_NAND_CE0_B__RAWNAND_CE0_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
MX6_PAD_NAND_CE1_B__RAWNAND_CE1_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
MX6_PAD_NAND_RE_B__RAWNAND_RE_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
MX6_PAD_NAND_WE_B__RAWNAND_WE_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
MX6_PAD_NAND_WP_B__RAWNAND_WP_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
MX6_PAD_NAND_READY_B__RAWNAND_READY_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
MX6_PAD_NAND_DQS__RAWNAND_DQS | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
};
// 初始化GPMI NAND
static void setup_gpmi_nand(void)
{
struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
// 设置GPMI NAND引脚
imx_iomux_v3_setup_multiple_pads(nand_pads, ARRAY_SIZE(nand_pads));
// 设置GPMI IO时钟
setup_gpmi_io_clk((MXC_CCM_CS2CDR_ENFC_CLK_PODF(0) |
MXC_CCM_CS2CDR_ENFC_CLK_PRED(3) |
MXC_CCM_CS2CDR_ENFC_CLK_SEL(3)));
// 启用APBH时钟门控
setbits_le32(&mxc_ccm->CCGR0, MXC_CCM_CCGR0_APBHDMA_MASK);
}
#endif
#ifdef CONFIG_FEC_MXC
// 初始化FEC(以太网)
static int setup_fec(void)
{
struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
int ret;
/*
* 使用50M anatop环回REF_CLK1作为ENET1的时钟源,
* 清除gpr1[13],设置gpr1[17]。
*/
clrsetbits_le32(&iomuxc_regs->gpr[1], IOMUX_GPR1_FEC1_MASK,
IOMUX_GPR1_FEC1_CLOCK_MUX1_SEL_MASK);
/*
* 使用50M anatop环回REF_CLK2作为ENET2的时钟源,
* 清除gpr1[14],设置gpr1[18]。
*/
if (!check_module_fused(MODULE_ENET2)) {
clrsetbits_le32(&iomuxc_regs->gpr[1], IOMUX_GPR1_FEC2_MASK,
IOMUX_GPR1_FEC2_CLOCK_MUX1_SEL_MASK);
}
// 启用ENET1的anatop时钟
ret = enable_fec_anatop_clock(0, ENET_50MHZ);
if (ret)
return ret;
// 启用ENET2的anatop时钟
if (!check_module_fused(MODULE_ENET2)) {
ret = enable_fec_anatop_clock(1, ENET_50MHZ);
if (ret)
return ret;
}
// 启用ENET时钟
enable_enet_clk(1);
return 0;
}
// 配置PHY设备
int board_phy_config(struct phy_device *phydev)
{
phy_write(phydev, MDIO_DEVAD_NONE, 0x1f, 0x8190);
if (phydev->drv->config)
phydev->drv->config(phydev);
return 0;
}
#endif
#ifdef CONFIG_VIDEO
// LCD引脚配置数组
static iomux_v3_cfg_t const lcd_pads[] = {
/* 使用GPIO进行亮度调整,占空比=周期。 */
MX6_PAD_GPIO1_IO08__GPIO1_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL),
};
// 初始化LCD
static int setup_lcd(void)
{
// 启用LCDIF时钟
enable_lcdif_clock(LCDIF1_BASE_ADDR, 1);
// 设置LCD引脚
imx_iomux_v3_setup_multiple_pads(lcd_pads, ARRAY_SIZE(lcd_pads));
// 重置LCD
gpio_request(IMX_GPIO_NR(5, 9), "lcd reset");
gpio_direction_output(IMX_GPIO_NR(5, 9) , 0);
udelay(500);
gpio_direction_output(IMX_GPIO_NR(5, 9) , 1);
// 设置亮度为高
gpio_request(IMX_GPIO_NR(1, 8), "backlight");
gpio_direction_output(IMX_GPIO_NR(1, 8) , 1);
return 0;
}
#else
static inline int setup_lcd(void) { return 0; }
#endif
// 早期初始化
int board_early_init_f(void)
{
return 0;
}
// 板级初始化
int board_init(void)
{
/* 设置启动参数地址 */
gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
#ifdef CONFIG_FEC_MXC
// 初始化FEC
setup_fec();
#endif
#ifdef CONFIG_FSL_QSPI
// 初始化QuadSPI
board_qspi_init();
#endif
#ifdef CONFIG_NAND_MXS
// 初始化GPMI NAND
setup_gpmi_nand();
#endif
return 0;
}
#ifdef CONFIG_CMD_BMODE
// 定义启动模式
static const struct boot_mode board_boot_modes[] = {
/* 4位总线宽度 */
{"sd1", MAKE_CFGVAL(0x42, 0x20, 0x00, 0x00)},
{"sd2", MAKE_CFGVAL(0x40, 0x28, 0x00, 0x00)},
{"qspi1", MAKE_CFGVAL(0x10, 0x00, 0x00, 0x00)},
{NULL, 0},
};
#endif
// 板子初始化
int board_late_init(void)
{
#ifdef CONFIG_CMD_BMODE
// 添加启动模式
add_board_boot_modes(board_boot_modes);
#endif
// 设置tee环境变量
env_set("tee", "no");
#ifdef CONFIG_IMX_OPTEE
env_set("tee", "yes");
#endif
#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
// 设置板级名称
env_set("board_name", "EVK");
// 设置板级版本
if (is_mx6ull_9x9_evk())
env_set("board_rev", "9X9");
else
env_set("board_rev", "14X14");
// 如果是MX6ULZ CPU,设置特定的环境变量
if (is_cpu_type(MXC_CPU_MX6ULZ)) {
env_set("board_name", "ULZ-EVK");
env_set("usb_net_cmd", "usb start");
}
#endif
// 初始化LCD
setup_lcd();
#ifdef CONFIG_ENV_IS_IN_MMC
// 初始化MMC环境
board_late_mmc_env_init();
#endif
// 设置看门狗复位
set_wdog_reset((struct wdog_regs *)WDOG1_BASE_ADDR);
return 0;
}
// 检查板级信息
int checkboard(void)
{
if (is_mx6ull_9x9_evk())
puts("Board: MX6ULL 9x9 EVK\n");
else if (is_cpu_type(MXC_CPU_MX6ULZ))
puts("Board: MX6ULZ 14x14 EVK\n");
else
puts("Board: MX6ULL 14x14 EVK\n");
return 0;
}
// 静音设备
void board_quiesce_devices(void)
{
#if defined(CONFIG_VIDEO_MXS)
// 禁用LCDIF时钟
enable_lcdif_clock(LCDIF1_BASE_ADDR, 0);
#endif
}搜索CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG配置项
1
2
3
4
5
6
7
8
9
10
11
12
13
14
env_set("board_name", "EVK");
if (is_mx6ull_9x9_evk())
env_set("board_rev", "9X9");
else
env_set("board_rev", "14X14");
if (is_cpu_type(MXC_CPU_MX6ULZ)) {
env_set("board_name", "ULZ-EVK");
env_set("usb_net_cmd", "usb start");
}改为
1
2
3
4
env_set("board_name", "naro");
env_set("board_rev", "14X14");找到checkboard函数
1
2
3
4
5
6
7
8
9
10
11int checkboard(void)
{
if (is_mx6ull_9x9_evk())
puts("Board: MX6ULL 9x9 EVK\n");
else if (is_cpu_type(MXC_CPU_MX6ULZ))
puts("Board: MX6ULZ 14x14 EVK\n");
else
puts("Board: MX6ULL 14x14 EVK\n");
return 0;
}改为:
1
2
3
4
5int checkboard(void)
{
puts("Board: MX6ULL ALPHA\n");
return 0;
}
6、添加板级头文件
原文
1 | /* SPDX-License-Identifier: GPL-2.0+ */ |
evk关键字进行修改,防止遗漏。
宏定义改了
1 |
找到CONFIG_TARGET_MX6ULL_9X9_EVK。
1 |
改为:
1 |
找findfdt:
1 | "findfdt="\ |
改为
1 | "findfdt="\ |
这里配置的设备树是linux启动时所需要的设备树。
找到findtee:
1 | "if test $tee_file = undefined; then " \ |
改为
1 | "findtee="\ |
7 、配置Kconfig
找到arch/arm/mach-imx/mx6/Kconfig文件。
搜索TARGET_MX6ULL_14X14_EVK,默认内容为:
1 | config TARGET_MX6ULL_14X14_EVK |
下方添加:
1 | config TARGET_MX6ULL_14X14_NARO |
搜索source “board/freescale/mx6ullevk/Kconfig” ,在其下方添加:
1 | source "board/freescale/mx6ullnaro/Kconfig" |
8、添加相应设备树文件
8-1、dtsi和dts区别
.dtsi文件:类似于C语言中的头文件(.h文件),通常包含多个设备或子系统的公共定义和配置。这些文件可以被多个.dts文件引用,以避免重复定义。例如,处理器的通用外设定义、引脚复用配置等。
.dts文件:是具体的设备树源文件,针对特定的板级配置。它会包含对具体硬件平台的所有详细描述,并且可以引用一个或多个.dtsi文件来组合成完整的设备树。
找到imx6ull-14x14-evk.dts,打开看的包含的文件,也要改,include了下面几个文件,所以也要复制。
找到arch/arm/dts/imx6ull-14x14-evk.dts文件,复制为arch/arm/dts/imx6ull-14X14-naro.dts。
找到arch/arm/dts/imx6ul-14x14-evk.dtsi文件,复制为arch/arm/dts/imx6ull-14X14-naro.dtsi。
找到arch/arm/dts/imx6ull-14x14-evk-u-boot.dtsi文件,复制为arch/arm/dts/imx6ull-14X14-naro-u-boot.dtsi。
修改imx6ull-14X14-naro.dts文件。
原文:
1 | // SPDX-License-Identifier: (GPL-2.0 OR MIT) |
改为:移植的是EMMC版本的,所以需要将imx6ull-14x14-evk-emmc.dts文件的usdhc2结点复制到imx6ull-alpha.dts文件中,修改后文件内容为:
1 | // SPDX-License-Identifier: (GPL-2.0 OR MIT) |
9、移植网络
找到configs/mx6ull_alpha_defconfig文件,搜索CONFIG_PHY_MICREL和CONFIG_PHY_MICREL_KSZ8XXX,注释掉这两行,添加CONFIG_PHY_SMSC=y。
找到arch/arm/dts/imx6ull-alpha.dtsi文件,搜索fec1,看到网络默认配置为:
1 |
|
改为:
1 | &fec1 { |
uboot只能使能一个网口,所以我们需要disable一个网口,fec1使能比较麻烦,所以我这里使能fec2,同时添加了复位引脚。
搜索找到pinctrl_enet1结点位置,在此节点后面添加:
1 | pinctrl_enet1_reset:enet1resetgrp { |
同理,在pinctrl_enet2后面添加:
1 | pinctrl_enet2_reset:enet2resetgrp { |
最后需要修改drivers/net/phy/phy.c文件,找到genphy_config_aneg函数,在int result;后面加上phy_reset(phydev);让网口复位
10、编译 测试
最后会发现无法启动内核,是需要将arch/arm/mach-imx/mx6/Kconfig文件中把select OF_SYSTEM_SETUP去掉----重点
这里不改,就起不来。
11、修改屏幕
arch/arm/dts/imx6ull-naro.dtsi文件,搜索lcdicc结点,找到:
1 | &lcdif { |
改为自己的屏幕参数
1 |
|
正点原子的uboot移植视频里还讲了校验码的修改,这个文件写的就是生成的bin文件的头部信息,只有校验码正确了,我们才能够直接烧写uboot编译生成的uboot-dtb.imx文件。
找到board/freescale/mx6ullalpha/imximage.cfg文件,搜索0x021B083C,连续三行默认值为:
1 | DATA 4 0x021B083C 0x41640158 |
改为:
1 | DATA 4 0x021B083C 0x01380138 |
12、编译测试
重置环境变量
1 | env default -a |
配置uboot网络环境,有两个网口,设置mac要注意顺序
1 | setenv ipaddr 192.168.8.11 |
启动后。测试ping通,显示正常。
1 | => ping 192.168.8.9 |
1 | setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw' |
可以通过下面命令核对。
1 | mmc part |
网络挂载系统
1 | setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw' |
13、修改emmc
测试发现emmc的设备节点相比旧版本,缺少了重置的gpio,所以需要修改dts文件。
报错信息:
1 | Normal Boot |
1 | reg_sd1_vmmc: regulator-sd1-vmmc { |
1 |
|
移植linux时注意用emmc版本