本文跟随着韦东山老师的毕业班移植内核视频进行学习。
首先
tar -xjf linux-3.4.2.tar.bz2
cd linux-3.4.2
修改顶层Makefile:
ARCH ?= arm
CROSS_COMPILE ?= arm-linux-
选择类似的开发板配置文件进行配置:
make s3c2410_defconfig
make uImage
将编译好的uImage烧到开发板中,启动发现乱码,说明串口已经有输出,根据https://blog.csdn.net/weixin_41354745/article/details/82381790文章中linux的启启动流程分析,先考虑机器id是否能够匹配,查看uboot传入的机器id:
在cmd_bootm.c中,
U_BOOT_CMD(
bootm, CONFIG_SYS_MAXARGS, 1, do_bootm,
);
查看do_bootm函数:
boot_fn = boot_os[images.os.os];
boot_os是一个指针数组,由于宏CONFIG_BOOTM_LINUX被定义,我们执行的是do_bootm_linux:
static boot_os_fn *boot_os[] = {
#ifdef CONFIG_BOOTM_LINUX
[IH_OS_LINUX] = do_bootm_linux,
#endif
#ifdef CONFIG_BOOTM_NETBSD
[IH_OS_NETBSD] = do_bootm_netbsd,
#endif
#ifdef CONFIG_LYNXKDI
[IH_OS_LYNXOS] = do_bootm_lynxkdi,
#endif
#ifdef CONFIG_BOOTM_RTEMS
[IH_OS_RTEMS] = do_bootm_rtems,
#endif
#if defined(CONFIG_BOOTM_OSE)
[IH_OS_OSE] = do_bootm_ose,
#endif
#if defined(CONFIG_CMD_ELF)
[IH_OS_VXWORKS] = do_bootm_vxworks,
[IH_OS_QNX] = do_bootm_qnxelf,
#endif
#ifdef CONFIG_INTEGRITY
[IH_OS_INTEGRITY] = do_bootm_integrity,
#endif
};
int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
{
......
boot_jump_linux(images);
return 0;
}
/* 在boot_jump_linux函数中 */
static void boot_jump_linux(bootm_headers_t *images)
{
unsigned long machid = gd->bd->bi_arch_number;
......
s = getenv("machid");
......
r2 = gd->bd->bi_boot_params;
kernel_entry(0, machid, r2);
}
从上面代码看到machid可以从环境变量获得,也可以自己设置,搜索bi_arch_number,发现在board/samsung/smdk2440/smdk2410.c(当初移植uboot的时候,没有改文件名)中有定义机器id:
int board_init(void)
{
/* arch number of SMDK2410-Board */
gd->bd->bi_arch_number = MACH_TYPE_S3C2440; /* id = 362 */
/* adress of boot parameters */
gd->bd->bi_boot_params = 0x30000100;
......
return 0;
}
假定是由于机器id造成的乱码,尝试将机器id修改为MINI2440的7CF:
set machid 7CF
save
nfs 32000000 192.168.1.16:/work/nfs_root/uImage_new
bootm 32000000
启动,还是出现乱码,说明乱码问题跟机器id无关(因为内核已完全支持MINI2440),考虑原因是在启动参数中没有设置串口波特率,因此在uboot阶段设置参数:
set bootargs console=ttySAC0,115200......
save
注意,此时的machid是mini2440的,乱码问题解决。但视频中未重新将machid设置为SMDK2440的,无法确定smdk2440是不是也是由于启动参数造成的(由于开发板不在身边,此问题会留到后期实验,但正常情况下应该也会是乱码)。
Question:
这里对uboot的启动参数有一个疑问,也是学习过程中没有掌握的知识点,启动参数中设置波特率,与后面要改的晶振时钟两者之间的联系。如果启动参数中没有设置115200,只是对晶振的初始值修改为12MHz,能否解决乱码问题?
Answer:
需要拿开发板进行试验。
查看函数mach-smdk2440.c中的代码:
MACHINE_START(S3C2440, "SMDK2440")
/* Maintainer: Ben Dooks */
.atag_offset = 0x100,
.init_irq = s3c24xx_init_irq,
.map_io = smdk2440_map_io,
.init_machine = smdk2440_machine_init,
.timer = &s3c24xx_timer,
.restart = s3c244x_restart,
MACHINE_END
发现在smdk2440_map_io函数中:
static void __init smdk2440_map_io(void)
{
......
s3c24xx_init_clocks(16934400); /* 这是晶振时钟 */
......
}
void __init s3c24xx_init_clocks(int xtal)
{
if (xtal == 0)
xtal = 12*1000*1000; /* 12MHz */
if (cpu == NULL)
panic("s3c24xx_init_clocks: no cpu setup?\n");
if (cpu->init_clocks == NULL)
panic("s3c24xx_init_clocks: cpu has no clock init\n");
else
(cpu->init_clocks)(xtal);
}
由于电路用的是12M的晶振,所以将该函数参数进行修改,把入口参数修改为0即可,重新配置、编译内核,使用新的uImage,乱码问题解决。
make s3c2410_defconfig
make uImage