Chinaunix首页 | 论坛 | 博客
  • 博客访问: 831165
  • 博文数量: 281
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2770
  • 用 户 组: 普通用户
  • 注册时间: 2009-08-02 19:45
个人简介

邮箱:zhuimengcanyang@163.com 痴爱嵌入式技术的蜗牛

文章分类
文章存档

2020年(1)

2018年(1)

2017年(56)

2016年(72)

2015年(151)

分类: LINUX

2016-06-18 11:15:08

分析由uboot启动内核的流程,根据机器ID配置内核
这里是移植linux-3.4.2
------------------------------------------------------------

流程分析:

1. 修改主目录下的Makefile

ARCH  ?=
CROSS_COMPILE  ?=
修改为:
ARCH  ?= arm
CROSS_COMPILE  ?= arm-linux-

tips:
vi中显示行号,在底行模式下输入:
:set nu  // 即可以显示行号了

2. 找到配置文件

$ find -name "*defconfig"
可以看到一堆配置文件
......
......
./arch/arm/configs/ns9xxx_defconfig
./arch/arm/configs/iop32x_defconfig
./arch/arm/configs/realview-smp_defconfig
./arch/arm/configs/neponset_defconfig
./arch/arm/configs/at91sam9261ek_defconfig
./arch/arm/configs/lpd7a400_defconfig
./arch/arm/configs/h7201_defconfig
./arch/arm/configs/versatile_defconfig
./arch/arm/configs/kb9202_defconfig
./arch/arm/configs/at91sam9260ek_defconfig
./arch/arm/configs/fortunet_defconfig
./arch/arm/configs/ixp4xx_defconfig
./arch/arm/configs/picotux200_defconfig
./arch/arm/configs/at91sam9263ek_defconfig
./arch/arm/configs/mainstone_defconfig
./arch/arm/configs/clps7500_defconfig
./arch/arm/configs/at91rm9200dk_defconfig
./arch/arm/configs/pxa255-idp_defconfig
./arch/arm/configs/footbridge_defconfig
./arch/arm/configs/integrator_defconfig
./arch/arm/configs/csb637_defconfig
......

3. 找到单板对应的配置文件

book@book-desktop:/work/system/llinux-3.4.2$ cd arch/arm/configs/
book@book-desktop:/work/system/linux-3.4.2/arch/arm/configs$ ls *2410*
s3c2410_defconfig

4. 编译配置文件

book@book-desktop:/work/system/linux-3.4.2$make s3c2410_defconfig
打印:表示配置为.config成功
......
#
# configuration written to .config
#

5. 编译内核

book@book-desktop:/work/system/linux-3.4.2$ make uImage

6. 利用TFTP下载新的uImage到板子,看打印信息:

SMDK2410 # tftp 30000000 uImage_newkernel
SMDK2410 # bootm 30000000
    ## Booting kernel from Legacy Image at 30000000 ...
       Image Name:   Linux-3.4.2
       Image Type:   ARM Linux Kernel Image (uncompressed)
       Data Size:    2399640 Bytes = 2.3 MiB (注意:这里新内核的大小,比我们在NAND中给内核预留的空间要大)
       Load Address: 30108000
       Entry Point:  30108000
       Verifying Checksum ... OK
       Loading Kernel Image ... OK
    OK

    Starting kernel ...

    Uncompressing Linux... done, booting the kernel.
    ?x?x?x?x??x?x?x??x??x?xxxx???x?x?x?x?x?x??xxx?x??
    打印一堆乱码.......
    
    出现乱码的原因:波特率设置不对。那可能是时钟频率设置的不正确。
分析u-boot启动内核流程:
u-boot-1.1.6中:
==========================
\common\md_bootm.c

do_bootm
    boot_os[images.os.os]
    do_bootm_linux
        boot_jump_linux
            unsigned long machid = gd->bd->bi_arch_number;  // 获取默认的机器ID
            s = getenv("machid");                           // 从环境变量获取机器ID
            r2 = gd->bd->bi_boot_params;                    // 获取bootload传递给kernel的参数
            kernel_entry(0, machid, r2);                    // 启动内核,跳转到linux kernel的程序当中


==================================================================
u-boot-2012.04.01:做法都是一样的。
\common\cmd_bootm.c: do_bootz

U_BOOT_CMD(
    bootz,    CONFIG_SYS_MAXARGS,    1,    do_bootz,
    "boot Linux zImage image from memory",
    "[addr [initrd[:size]] [fdt]]\n"
    "    - boot Linux zImage stored in memory\n"
    "\tThe argument 'initrd' is optional and specifies the address\n"
    "\tof the initrd in memory. The optional argument ':size' allows\n"
    "\tspecifying the size of RAW initrd.\n"
);

static int do_bootz(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
    do_bootm_linux(0, argc, argv, &images);
        boot_jump_linux(images);
            unsigned long machid = gd->bd->bi_arch_number;          // 获取默认的机器ID
            void (*kernel_entry)(int zero, int arch, uint params);  // 构造函数
            kernel_entry = (void (*)(int, int, uint))images->ep;   
            s = getenv("machid");          // 从环境参数获取机器ID
            r2 = gd->bd->bi_boot_params;   // 获取BootLoader传递参数给kernel的地址
            kernel_entry(0, machid, r2);   // 启动内核

在文件:\board\samsung\smdk2410\smdk2410.c 中可以找到默认的机器ID

board_init
    gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;           // 默认的机器ID为:MACH_TYPE_SMDK2410 = 193  

7. 测试利用环境变量,输入机器ID,来查看打印信息(环境变量,可以利用uboot输入参数)

SMDK2410 # set machid 33245   //随便设置一个机器ID,启动内核
SMDK2410 # save
SMDK2410 # tftp 30000000 uImage_newkernel; bootm 30000000
启动会打印:
## Booting kernel from Legacy Image at 30000000 ...
   Image Name:   Linux-3.4.2
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    2399640 Bytes = 2.3 MiB
   Load Address: 30108000
   Entry Point:  30108000
   Verifying Checksum ... OK
   Loading Kernel Image ... OK
OK
Using machid 0x33245 from environment

Starting kernel ...

Uncompressing Linux... done, booting the kernel.

Error: unrecognized/unsupported machine ID (r1 = 0x00033245).

Available machine support:

ID (hex)        NAME
00000400        AML_M5900
0000014b        Simtec-BAST
0000015b        IPAQ-H1940
0000039f        Acer-N35
00000290        Acer-N30
000002a8        Nex Vision - Otom 1.1
00000454        QT2410

000000c1        SMDK2410

000005b4        TCT_HAMMER
000001db        Thorcom-VR1000
000005d2        JIVE
000003fe        SMDK2413
000003f1        SMDK2412
00000377        S3C2413
00000474        VSTMS
00000695        SMDK2416
000002de        Simtec-Anubis
00000707        AT2440EVB

000007cf        MINI2440

000002a9        NexVision - Nexcoder 2440
0000034a        Simtec-OSIRIS
00000250        IPAQ-RX3715

0000016a        SMDK2440

00000518        GTA02
000003b8        HP iPAQ RX1950
0000043c        SMDK2443
Please check your kernel config and/or bootloader.
会打印这句话:Error: unrecognized/unsupported machine ID (r1 = 0x00033245).
说明环境变量输入的机器ID不认识/不支持。

如果想使用机器:SMDK2440,则机器ID设置成相应的值:0000016a

uboot中默认的机器ID设置为,传递给内核的也是这个机器ID。
000000c1        SMDK2410

8. 重启,重新设置

SMDK2410 # set machid 16a    
SMDK2410 # save
SMDK2410 # tftp 30000000 uImage_newkernel; bootm 30000000
打印:
## Booting kernel from Legacy Image at 30000000 ...
   Image Name:   Linux-3.4.2
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    2399640 Bytes = 2.3 MiB
   Load Address: 30108000
   Entry Point:  30108000
   Verifying Checksum ... OK
   Loading Kernel Image ... OK
OK
Using machid 0x16a from environment

Starting kernel ...

Uncompressing Linux... done, booting the kernel.
?x?x?x?x??x?x?x??x??x?xxxx???x?x?x?x?x?x??xxx?x??
乱码一堆.......

但是没有出现机器ID的错误。。。。。

9. 设置成mini2440的机器ID

SMDK2410 # set machid 7cf    
SMDK2410 # save
SMDK2410 # tftp 30000000 uImage_newkernel; bootm 30000000
还是打印乱码,这说明不是机器ID的问题,可能是串口波特率或者时钟没配置正确。

10. 查看启动参数,修改串口波特率

SMDK2410 # print
baudrate=115200
bootargs=console=ttySAC0 root=/dev/nfs nfsroot=192.168.1.10:/work/nfs_root/first_fs ip=192.168.1.17:192.168.1.10:192.168.1.1:255.255.255.0::eth0:off
bootcmd=nand read 0x30000000 kernel; bootm 0x30000000
bootdelay=2
ethact=dm9000
ethaddr=08:00:3e:26:0a:5b
fileaddr=30000000
filesize=5b89a8
ipaddr=192.168.1.17
machid=7cf
mtddevname=u-boot
mtddevnum=0
mtdids=nand0=jz2440-0
mtdparts=mtdparts=jz2440-0:256k(u-boot),128k(params),2m(kernel),-(rootfs)
netmask=255.255.255.0
partition=nand0,0
serverip=192.168.1.100
stderr=serial
stdin=serial
stdout=serial
Environment size: 607/131068 bytes

修改启动参数,设置波特率为115200,并且记得保存:
SMDK2410 # set bootargs console=ttySAC0,115200 root=/dev/mtdblock3
SMDK2410 # save
重新下载内核并启动:
tftp 30000000 uImage_newkernel; bootm 30000000
打印信息:
## Booting kernel from Legacy Image at 30000000 ...
   Image Name:   Linux-3.4.2
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    2399640 Bytes = 2.3 MiB
   Load Address: 30108000
   Entry Point:  30108000
   Verifying Checksum ... OK
   Loading Kernel Image ... OK
OK
Using machid 0x7cf from environment

Starting kernel ...

Uncompressing Linux... done, booting the kernel.
Booting Linux on physical CPU 0
Linux version 3.4.2 (book@book-desktop) (gcc version 4.3.2 (Sourcery G++ Lite 2008q3-72) ) #1 Fri May 20 12:08:33 CST 2016
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
CPU: VIVT data cache, VIVT instruction cache
Machine: MINI2440
Memory policy: ECC disabled, Data cache writeback
CPU S3C2440A (id 0x32440001)
S3C24XX Clocks, Copyright 2004 Simtec Electronics
S3C244X: core 400.000 MHz, memory 100.000 MHz, peripheral 50.000 MHz
CLOCK: Slow mode (1.500 MHz), fast, MPLL on, UPLL on
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 16256
Kernel command line: console=ttySAC0,115200 root=/dev/mtdblock3
PID hash table entries: 256 (order: -2, 1024 bytes)
Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
Memory: 64MB = 64MB total
.....
最后打印:
List of all partitions:
1f00             256 mtdblock0  (driver?)
1f01             128 mtdblock1  (driver?)
1f02            5120 mtdblock2  (driver?)
1f03          256640 mtdblock3  (driver?)
No filesystem could mount root, tried:  ext3 ext2 cramfs vfat msdos iso9660 romfs
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(31,3)
Backtrace:
[] (dump_backtrace+0x0/0x10c) from [] (dump_stack+0x18/0x1c)
 r6:c38b2000 r5:ffffffea r4:c381df2c
[] (dump_stack+0x0/0x1c) from [] (panic+0x7c/0x1d0)
[] (panic+0x0/0x1d0) from [] (mount_block_root+0x1e0/0x23c)
 r3:00000003 r2:c381df2c r1:c381df2c r0:c04e4c20
[] (mount_block_root+0x0/0x23c) from [] (mount_root+0x88/0x108)
[] (mount_root+0x0/0x108) from [] (prepare_namespace+0x110/0x1d0)
 r7:c05ac540 r6:c056e764 r5:c056e764 r4:c05ac5a0
[] (prepare_namespace+0x0/0x1d0) from [] (kernel_init+0x164/0x1b8)
 r6:00000008 r5:c056df38 r4:c0574b34
[] (kernel_init+0x0/0x1b8) from [] (do_exit+0x0/0x76c)
发现问题:驱动分区信息不对,找不到根文件系统,启动不起来。
查找机器ID:
\board\samsung\smdk2410\smdk2410.c
    board_init
        gd->bd->bi_arch_number = MACH_TYPE_SMDK2410; // mach_types.h: MACH_TYPE_SMDK2410 = 193 
设置机器ID:
set machid 16a     // SMDK2440  mach-smdk2440.c    
set machid 7CF     // mini2440  mach-mini2440.c
板子不同对应的初始化函数不同,而为什么mini2440可以打印,而SMDK2440不能打印数据呢?
可以对照mach-smdk2440.c和mach-mini2440.c中的初始化函数有什么不同。
可以看到mach-smdk2440.c里面时钟设置的不对,外部晶振应该该为12Mhz。

11. 修改mach-smdk2440.c里面初始化时钟晶振为12000000

\arch\arm\mach-s3c24xx\mach-smdk2440.c
函数:smdk2440_map_io
    s3c24xx_init_clocks(16934400);
    修改为:
    s3c24xx_init_clocks(12000000);

-重新编译烧写内核,
-启动开发板
-设置成SMDK2440
-看打印信息
打印信息:
Creating 8 MTD partitions on "NAND":
0x000000000000-0x000000004000 : "Boot Agent"
mtd: partition "Boot Agent" doesn't end on an erase block -- force read-only
0x000000000000-0x000000200000 : "S3C2410 flash partition 1"
0x000000400000-0x000000800000 : "S3C2410 flash partition 2"
0x000000800000-0x000000a00000 : "S3C2410 flash partition 3"
0x000000a00000-0x000000e00000 : "S3C2410 flash partition 4"
0x000000e00000-0x000001800000 : "S3C2410 flash partition 5"
0x000001800000-0x000003000000 : "S3C2410 flash partition 6"
0x000003000000-0x000010000000 : "S3C2410 flash partition 7"
dm9000 Ethernet Driver, V1.31
ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
s3c2410-ohci s3c2410-ohci: S3C24XX OHCI
s3c2410-ohci s3c2410-ohci: new USB bus registered, assigned bus number 1
s3c2410-ohci s3c2410-ohci: irq 42, io mem 0x49000000
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 2 ports detected
usbcore: registered new interface driver libusual
usbcore: registered new interface driver usbserial
usbcore: registered new interface driver usbserial_generic
USB Serial support registered for generic
usbserial: USB Serial Driver core
usbcore: registered new interface driver ftdi_sio
USB Serial support registered for FTDI USB Serial Device
ftdi_sio: v1.6.0:USB FTDI Serial Converters Driver
usbcore: registered new interface driver pl2303
USB Serial support registered for pl2303
mousedev: PS/2 mouse device common for all mice
s3c2410_wdt: S3C2410 Watchdog Timer, (c) 2004 Simtec Electronics
s3c2410-wdt s3c2410-wdt: watchdog inactive, reset disabled, irq disabled
TCP: cubic registered
NET: Registered protocol family 17
drivers/rtc/hctosys.c: unable to open rtc device (rtc0)
ALSA device list:
  No soundcards found.
List of all partitions:
1f00              16 mtdblock0  (driver?)
1f01            2048 mtdblock1  (driver?)
1f02            4096 mtdblock2  (driver?)
1f03            2048 mtdblock3  (driver?)
1f04            4096 mtdblock4  (driver?)
1f05           10240 mtdblock5  (driver?)
1f06           24576 mtdblock6  (driver?)
1f07          212992 mtdblock7  (driver?)
No filesystem could mount root, tried:  ext3 ext2 cramfs vfat msdos iso9660 romfs
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(31,3)
Backtrace:
[] (dump_backtrace+0x0/0x10c) from [] (dump_stack+0x18/0x1c)
 r6:c38a9000 r5:ffffffea r4:c381df2c
[] (dump_stack+0x0/0x1c) from [] (panic+0x7c/0x1d0)
[] (panic+0x0/0x1d0) from [] (mount_block_root+0x1e0/0x23c)
 r3:00000003 r2:c381df2c r1:c381df2c r0:c04e4c20
[] (mount_block_root+0x0/0x23c) from [] (mount_root+0x88/0x108)
[] (mount_root+0x0/0x108) from [] (prepare_namespace+0x110/0x1d0)
 r7:c05ac540 r6:c056e764 r5:c056e764 r4:c05ac5a0
[] (prepare_namespace+0x0/0x1d0) from [] (kernel_init+0x164/0x1b8)
 r6:00000008 r5:c056df38 r4:c0574b34
[] (kernel_init+0x0/0x1b8) from [] (do_exit+0x0/0x76c)
    
可以打印出信息了,不过还是不能启动根文件系统。

12. 相关工具

===============
NFS网络烧写内核:
nfs 30000000 192.168.1.10:/work/nfs_root/uImage_newkernel
bootm 30000000   
========
工具搭建:
1. 交叉编译器:arm-linux-gcc-4.3.2.tar.bz2
2. 新的内核:linux-3.4.2.tar.bz2

交叉编译器搭建:
解压到根目录:
    tar xjf arm-linux-gcc-4.3.2.tar.bz2 -C /
修改环境变量:
    vi /etc/environment
    修改:在后面添加新的编译器 /usr/local/arm/4.3.2/bin/
    PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/arm/4.3.2/bin/"

总结:

1. 下载源码树,分析从u-boot跳转到linux内核启动过程
2. 找到与开发板对应的配置文件,配置并编译最新的内核
3. 烧写到开发板,调试,看串口能否正确打印,能否启动内核

阅读(1407) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~