【系统移植】 (三)uboot烧写及使用

【系统移植】 (三)uboot烧写及使用

1.Bootloader介绍

什么是Bootloader

  • Bootloader是硬件启动的引导程序,是运行操作系统的前提;
  • 在操作系统内核或用户应用程序运行之前运行的一小段代码。对软硬件进行相应的初始化和设定,为最终运行操作系统准备好环境;
  • 在嵌入式系统中,整个系统的启动加载任务通常由Bootloader来完成。

Bootloader的特点

  • Bootloader不属于操作系统,一般采用汇编语言和C语言开发。需要针对特定的硬件平台编写。
  • 在移植系统时,首先为开发板移植Bootloader。
  • Bootloader不但依赖于CPU的体系结构,而且依赖于嵌入式系统板级设备的配置。

Bootloader的操作模式

  • **自启动模式:**在这种模式下,Bootloader从目标机上的某个固态存储设备上将操作系统加载到RAM中运行,整个过程并没有用户的介入。
  • **交互模式:**在这种模式下,目标机上的Bootloader将通过串口或网络等通信手段从开发主机(Host)上下载内核映像和根文件系统映像等到RAM中。可以被 Bootloader写到目标机上的固态存储媒质中,或者直接进行系统的引导。也可以通过串口接收用户的命令。

常用bootloader介绍

image-20241219164603440

2.U-boot介绍

u-boot(Universal Boot Loader)是德国DENX小组开发的用于多种嵌入式CPU的bootloader程序。遵循GPL条款。
从FADSROM、8xxROM 、PPCBOOT、Armboot逐步发展演化而来;
当前版本号:参考Makefile。  
http://www.denx.de/wiki/U-Boot/WebHome
U-boot的特点:
代码结构清晰、易于移植(见目录结构)
支持多种处理器体系结构(见arch目录)
支持众多开发板(目前官方包中有200多种,见board目录)
命令丰富、有监控功能
支持网络协议、USB、SD等多种协议和设备
支持文件系统
更新较活跃,使用者多,有助于解决问题

要让开发板上电后进入U-Boot模式,通常有以下几种方法:

  1. 按键中断启动:在开发板上电瞬间,根据串口打印信息,按任意键可以中断启动过程,进入U-Boot命令行界面。这是最常用的方法,适用于大多数开发板。

  2. 修改Bootloader设置:可以通过修改U-Boot的配置文件,增加bootdelay的值,使得开发板上电后有一段时间停留在U-Boot命令行,等待用户操作。例如,修改bootdelay为4秒,然后重新编译并烧录U-Boot到开发板中。

  3. 使用特定按键:部分开发板可能设有特定的按键,用于在上电时触发进入U-Boot模式。这需要参考开发板的用户手册或技术文档。

  4. 通过串口终端工具:连接开发板的串口到PC,并使用串口终端工具(如Minicom、SecureCRT等)设置正确的波特率。在开发板上电时,通过串口终端工具按下任意键,可以进入U-Boot命令行。

请注意,不同开发板的具体操作可能会有所不同,具体方法应参考开发板的用户手册或技术文档。同时,确保在进行任何操作前,了解并遵守相关的安全和操作规程。

3.U-BOOT 命令

命令分类

环境设置、数据传输、存储器访问、加载运行

  • printenv 显示所有环境变量
U-boot # printenv
    baudrate=115200
    ipaddr=192.168.1.100
    ethaddr=12:34:56:78:9A:BC
    serverip=192.168.1.10
      ……
  • setenv 设置新的环境变量
如何删除:后面什么都不加参数,如setenv  myboard
U-boot # setenv  myboard  FS4412
U-boot # printenv
   baudrate=115200
   ipaddr=192.168.1.100
   ethaddr=11:22:33:44:55:66
   serverip=192.168.1.10
   myboard=FS4412
   Environment size: 320/16380 bytes
       
U-boot # setenv  ethaddr  11:22:33:44:55:66
U-boot # setenv  ipaddr  192.168.1.100
U-boot # setenv  serverip  192.168.1.10 
  • saveenv 将当前定义的所有的环境变量值存入flash中
设置的新环境变量要保存。
  • tftp 通过网络下载程序
U-boot # tftp  41000000  application.bin
U-boot # tftp  41000000  zImage

    这些数字是内存地址
  • protect 对Nor Flash写保护
protect  on  0  10000 对区间[0x0, 0x10000]进行写保护
protect  off  0  10000  对上述区间取消写保护
  • erase 擦除Nor FLASH
erase  all    擦除FLASH所有的扇区
erase  0  10000  把FLASH区间 [0x0, 0x10000]擦除
  • Nand相关命令
nand  read  addr  off  size
nand  write  addr  off  size
nand  erase [clean] [off  size] 
  • movi 命令
movi  init ---初始化eMMC并显示相关信息 
movi  read  u-boot/kernel  addr
movi  write  u-boot/kernel  addr
movi  read  rootfs  addr   size
movi  write rootfs  addr   size
  • bootcmd 自启动命令
如果定义了该变量,在自启动模式下将会执行该环境变量中的命令。
U-boot # setenv bootcmd tftp 41000000 uImage\; bootm  41000000
U-boot # saveenv
  • go addr 执行内存中的二进制代码,简单的跳转到指定地址

  • bootm kernel-addr ramdisk-addr dtb-addr

引导内核为内核传参,其中内核和ramdisk通常为mkimage处理过的二进制文件。

4.U-BOOT配置编译

U-Boot的官方下载地址可以通过其官方网站获取。

自己去网站上面去下载,放到ubantu主机上面进行编译

U-Boot的目录结构中,各个目录的分类如下:

  1. 平台相关目录:(芯片的某些引脚换了都要改)

    • arch/:包含与特定处理器架构相关的代码,如ARM、MIPS、x86等。每个子目录包含了针对特定体系结构的引导代码和硬件相关的文件。
    • board/:包含针对不同开发板的代码,每个子目录对应一个具体的开发板或硬件平台。
  2. 平台无关目录

    • common/:包含通用的功能模块和工具函数,供不同架构和开发板共用。
    • cmd/:包含了U-Boot支持的命令列表,每个命令都有对应的源文件和头文件。
    • drivers/:通用设备驱动,如CFI FLASH驱动(目前对INTEL FLASH支持较好)。
    • fs/:包含文件系统的代码,支持嵌入式开发板常见的文件系统。
    • lib/:与处理器体系无关的库文件,如md5、CRC等算法的实现。
    • net/:与网络功能相关的文件目录,有简单4层网络协议栈的实现,如arp、bootp、nfs和tftp等。
  3. 工具和文档目录

    • tools/:包含了用于构建和调试U-Boot的工具,如编译器、调试器等。
    • doc/:包含了U-Boot的文档和说明,如使用手册、开发指南等。
  4. 其他目录

    • include/:包含了U-Boot的头文件,定义了各种数据结构、函数声明和宏定义。
    • api/:存放U-Boot提供的接口函数,供外部应用程序调用。
    • examples/:可在U-Boot下运行的示例程序,如hello_world.c和timer.c。
    • test/:测试脚本和代码。

U-Boot的目录结构设计有助于模块化和组织代码,使得开发者可以更容易地找到特定功能或架构相关的代码。具体目录的详细说明和功能,可以参考U-Boot的官方文档。

4.1编译U-boot

  • U-boot的编译

整个工程通过Makefile来组织编译。顶层目录下的Makefile中包含了开发板的配置信息。从顶层目录开始递归地调用各级子目录下的Makefile,最后链接成u-boot映像。

  • 顶层目录下的 Makefile

它负责u-boot整体配置和编译
在Makefile中指定使用的交叉工具链
配置u-boot: make origen_config
编译: make

U-BOOT编译生成的映像文件

文件名称 说明
u-boot.map U-boot映像的符号表(方便源码跟踪
u-boot U-Boot映像的ELF格式
u-boot.bin U-Boot映像原始的二进制格式(烧录用) 注意exynos4412需加入BL1
u-boot.srec U-Boot映像的S-Record格式

烧录编译产生的镜像 u-boot.bin

初次或开发板代码损坏不能正常启动时,可采用JTAG工具烧录
--专用的烧录工具如h-jtag或DNW等
--在u-boot已经能工作,升级或修正U-boot时,可用U-boot中的命令来烧录
--其它方式 如SD卡  , Fastboot命令
--镜像固化位置
ROM、NOR FLASH、NAND FLASH EMMC等

4.2启动流程

//精简版
1. 上电启动bootloader
    硬件基本初始化
    自搬移到内存
    搬移内核到内存
    传递内核启动参数(parmer_struct 或taglist)
 2. 加载内核
    a. 自解压内核  decompess   //arch/arm/boot/compressed/head.S
    b. 运行内核汇编部分 head.S 入口stext  //arch/arm/kernel/head.S
        检测合法性(CPU 类型,机器类型)
    c. 运行内核C部分  start_kernel  //init/main.c
         CPU,机器参数的安装   setup_arch
         中断,定时,终端,内存等最基本的初始化
         创建核心进程 kernel_init运行,启动多任务调度,原父进程空转cpu_ide 
 3. 挂载rootfs    (mount_root)      
 4. 运行应用程序  //第一个应用程序是init  (由u-boot的bootargs里的init=/linuxrc来指定)  
      a. 运行启动脚本  (run_init_process("/etc/init.d/rcS"))  //由init来解析脚本执行
      b. 其它应用程序 	 //一般添加在脚本的最后(如在rcS末尾加 ./app)

Linux开发板上电启动流程通常涉及以下步骤:

  1. 上电复位(Power-On Reset, POR)

    • 开发板上电后,首先会经历一个上电复位过程,确保系统从一个已知的干净状态开始。
  2. 启动模式选择

    • 根据开发板上的启动模式选择器(如果有的话),选择从哪个设备启动,如SD卡、eMMC、SPI Flash、NAND Flash或网络启动等。
  3. 引导加载程序(Bootloader)

    • 复位后,处理器开始执行固化在ROM(只读存储器)或通过跳线选择的启动设备中的引导加载程序,如U-Boot。
  4. 引导加载程序初始化

    • 引导加载程序初始化硬件,设置时钟、内存控制器、串口等,为操作系统启动做准备。
  5. 环境变量设置

    • 引导加载程序会加载环境变量,这些变量定义了启动参数,如内核映像的位置、启动脚本等。
  6. 加载内核映像

    • 引导加载程序从指定的存储设备加载Linux内核映像到内存中。
  7. 启动内核

    • 内核映像被加载后,引导加载程序将控制权交给内核。内核开始执行,进行更深入的硬件检测和初始化。
  8. 设备树传递

    • 内核启动时需要设备树(Device Tree)来了解硬件配置。设备树通常与内核映像一起被加载。
  9. 根文件系统挂载

    • 内核启动后,会挂载根文件系统,这是操作系统的文件系统,包含所有必要的文件和目录。
  10. 用户空间初始化

    • 内核初始化用户空间,启动init进程,这是用户空间的第一个进程。
  11. 系统服务启动

    • init进程会根据系统的初始化脚本(如Systemd、SysV init或BusyBox的init)启动系统服务和守护进程。
  12. 用户登录

    • 系统服务启动后,系统准备就绪,用户可以通过控制台或图形界面登录系统。

在整个启动过程中,可能会涉及到一些用户交互,比如选择启动项、输入密码等。此外,启动流程的具体步骤可能会因开发板的硬件、引导加载程序的配置和操作系统的不同而有所差异。

{
    
    //----------------------------U-boot 启动源码分析---------------------------
{
    
    //?上电系统从哪里开始,启动代码放在什么位置 
  上电后,有的系统可通过硬件管脚的电平来选择从Nandflash还是从Norflash启动。这里是指定从Nandflash启动的
  启动代码U-boot 是不能放在RAM中的,因掉电就消失了。  
}
{
    
    //?boot第一件是为何是设置为SVC模式
  为安全性,CPU本身提出了多种模式来实现安全性,和效率兼顾。 
  SVC模式就是CPU对资源的一种保护。在普通用户模式是不能访问到的。只有切换到SVC模式才能访问。
}  
{
    
    //?并关闭中断,MMU,看门狗等
  初始时为安全性,把系统单纯化, 排除掉别的干扰,仅仍u-boot实现单纯的搬移代码,
  的功能。 所以关掉中断,避免中断打断带来的保存返回的问题。 关掉MMU,因为u-boot软件是硬件实地址访问。
  根本没有用到内存地址映射。 看门狗如果没关,硬件上默认到时会复位的。 所以要关掉
}
{
    
    //?为何设备初始引导不能用C代码,要用汇编代码
  特殊指令,如操作协处理器, MMC CASH ,切换SVC模式, 等C不能做到。
  另C是需要先准备栈的.
}
{
    
    //?U-BOOT为何要搬移到RAM中运行
  在RAM中速度更快,但因掉电就没了,所以要保存在Nandflash或Norflash中。  
  如果搬移,直接在Norflash上运行也是可以的。 Nandflash因是按块操作的,不太合适直接运行。
}
{
    
    //?U-boot如何传递参数到内核。 移植时要注意哪些
  方式一 采用param_struct:  (我们现在使用的是这种方式) 见common/cmd_boot.c go命令的优化
  方式二 采用taglist:
}  

4.3u-boot启动流程

//阶段一(汇编) 
   设置为SVC模式,关闭中断,MMU,看门狗  //准备
   基本硬件设备初始化  //初始化时钟,串口,flash,内存    见cpu/arm_cortexa8/start.S 的   cpu_init_crit
   自搬移到内存       //copy_uboot_to_ram  或relocate
   设置好栈            //stack_setup
   跳转到第二阶段代码入口  //ldr	pc, _start_armboot
//阶段二(C语言)
   大部分硬件初始化  //lib_arm/board.c/start_armboot  -> init_sequence
   搬移内核到内存     //common/main.c  main_loop -> getenv ("bootcmd")  bootdelay >= 0 && s && !abortboot (bootdelay)) 下的 run_command (bootcmd)
   运行内核

u-boot启动阶段

//-------u-boot启动阶段
		U-Boot 2013.01 (Aug 24 2014 - 12:01:19) for FS4412
		CPU:	Exynos4412@1000MHz
		Board: FS4412
		DRAM:  1 GiB
		WARNING: Caches not enabled
		MMC:   MMC0:	3728 MB
		In:    serial
		Out:   serial
		Err:   serial
		MMC read: dev # 0, block # 48, count 16 ...16 blocks read: OK
		eMMC CLOSE Success.!!
		Checking Boot Mode ... EMMC4.41
		Net:   dm9000
		Hit any key to stop autoboot:  3  2  1  0 

		dm9000 i/o: 0x5000000, id: 0x90000a46 
		DM9000: running in 16 bit mode
		MAC: 11:22:33:44:55:66
		operating at 100M full duplex mode
		Using dm9000 device
		TFTP from server 192.168.9.120; our IP address is 192.168.9.9  //对应bootcmd的 tftp 0x41000000 uImage 
		Filename 'uImage'.
		Load address: 0x41000000
		Loading: *#################################################################
			 #################################################################
			 #################################################################
			 #################################################################
			 #################################################################
			 #################################################################
			 #################################################################
			 #################################################################
			 #################################################################
			 #######
			 69.3 KiB/s
		done
		Bytes transferred = 3028040 (2e3448 hex)
		dm9000 i/o: 0x5000000, id: 0x90000a46 
		DM9000: running in 16 bit mode
		MAC: 11:22:33:44:55:66
		operating at 100M full duplex mode
		Using dm9000 device
		TFTP from server 192.168.9.120; our IP address is 192.168.9.9  //对应bootcmd的 tftp 42000000 exynos4412-fs4412.dtb 
		Filename 'exynos4412-fs4412.dtb'.
		Load address: 0x42000000
		Loading: *#######
			 393.6 KiB/s
		done
		Bytes transferred = 33876 (8454 hex)
		   Booting kernel from Legacy Image at 41000000 ...
		   Image Name:   Linux-3.14.0
		   Image Type:   ARM Linux Kernel Image (uncompressed)
		   Data Size:    3027976 Bytes = 2.9 MiB
		   Load Address: 40008000
		   Entry Point:  40008000
		   Verifying Checksum ... OK
		   Flattened Device Tree blob at 42000000
		   Booting using the fdt blob at 0x42000000
		   Loading Kernel Image ... OK
		   Loading Device Tree to 4fff4000, end 4ffff453 ... OK
		   
		Starting kernel ...   /*启动内核(对应bootmcd的 bootm 41000000 - 42000000)
									如果到这里启动失败,可能原因      
							    1.u-boot参数设置错误   如bootargs 中ttySAC2 设为了ttySAC1  
							    2.uImage 有问题。   换一个OK的试试,或把这个uImage放在别的板上验证下
							    3.内核源码有问题, 加打印信息跟踪和打开内核调试信息开关,   init\main.c  start_kernel()
							        如machine type 不匹配
							    4.硬件相关,如u-boot初始CPU频率,分频不对 
							    */    

Linux内核启动阶段

/-------linux内核启动阶段
		Booting Linux on physical CPU 0xa00
		//init\main.c  start_kernel()
		Linux version 3.14.0 (david@ubuntu) (gcc version 4.6.4 (crosstool-NG hg+default-2685dfa9de14 - tc0002) ) #23 SMP PREEMPT Fri Aug 15 11:30:16 CST 2014
		
		CPU: ARMv7 Processor [413fc090] revision 0 (ARMv7), cr=10c5387d
		
		CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
		
		Machine model: Insignal Origen evaluation board based on Exynos4412
		
		Memory policy: Data cache writealloc
		
		CPU EXYNOS4412 (id 0xe4412011)
		
		Running under secure firmware.
		
		PERCPU: Embedded 7 pages/cpu @eefb6000 s7424 r8192 d13056 u32768
		
		Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 256528
		
		Kernel command line: root=/dev/nfs nfsroot=192.168.9.120:/nfs/rootfs rw console=ttySAC2,115200 init=/linuxrc ip=192.168.9.9  //内核对u-boot传入的bootargs参数的解析
		
		PID hash table entries: 4096 (order: 2, 16384 bytes)
		
		Dentry cache hash table entries: 131072 (order: 7, 524288 bytes)
		
		Inode-cache hash table entries: 65536 (order: 6, 262144 bytes)
		
		Memory: 1016852K/1032192K available (3956K kernel code, 237K rwdata, 1320K rodata, 231K init, 276K bss, 15340K reserved, 270336K highmem)
		
		Virtual kernel memory layout:
		
		    vector  : 0xffff0000 - 0xffff1000   (   4 kB)
		
		    fixmap  : 0xfff00000 - 0xfffe0000   ( 896 kB)
		
		    vmalloc : 0xf0000000 - 0xff000000   ( 240 MB)
		
		    lowmem  : 0xc0000000 - 0xef800000   ( 760 MB)
		
		    pkmap   : 0xbfe00000 - 0xc0000000   (   2 MB)
		
		    modules : 0xbf000000 - 0xbfe00000   (  14 MB)
		
		      .text : 0xc0008000 - 0xc052f41c   (5278 kB)
		
		      .init : 0xc0530000 - 0xc0569d00   ( 232 kB)
		
		      .data : 0xc056a000 - 0xc05a5540   ( 238 kB)
		
		       .bss : 0xc05a554c - 0xc05ea584   ( 277 kB)
		
		SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
		
		Preemptible hierarchical RCU implementation.
		
			RCU restricting CPUs from NR_CPUS=8 to nr_cpu_ids=4.
		
		RCU: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=4
		
		NR_IRQS:16 nr_irqs:16 16
		
		Exynos4x12 clocks: sclk_apll = 500000000, sclk_mpll = 800000000
		
			sclk_epll = 96000000, sclk_vpll = 350000000, arm_clk = 1000000000
		
		sched_clock: 32 bits at 200 Hz, resolution 5000000ns, wraps every 10737418240000000ns
		
		Console: colour dummy device 80x30
		
		Calibrating delay loop... 1992.29 BogoMIPS (lpj=4980736)
		
		pid_max: default: 32768 minimum: 301
		
		Mount-cache hash table entries: 2048 (order: 1, 8192 bytes)
		
		Mountpoint-cache hash table entries: 2048 (order: 1, 8192 bytes)
		
		CPU: Testing write buffer coherency: ok
		
		missing device node for CPU 0
		
		missing device node for CPU 1
		
		missing device node for CPU 2
		
		missing device node for CPU 3
		
		CPU0: thread -1, cpu 0, socket 10, mpidr 80000a00
		
		Setting up static identity map for 0x403c0e10 - 0x403c0e68
		
		CPU1: Booted secondary processor
		
		CPU1: thread -1, cpu 1, socket 10, mpidr 80000a01
		
		CPU2: Booted secondary processor
		
		CPU2: thread -1, cpu 2, socket 10, mpidr 80000a02
		
		CPU3: Booted secondary processor
		
		CPU3: thread -1, cpu 3, socket 10, mpidr 80000a03
		
		Brought up 4 CPUs
		
		SMP: Total of 4 processors activated.
		
		CPU: All CPU(s) started in SVC mode.
		
		devtmpfs: initialized
		
		VFP support v0.3: implementor 41 architecture 3 part 30 variant 9 rev 4
		
		pinctrl core: initialized pinctrl subsystem
		
		regulator-dummy: no parameters
		
		NET: Registered protocol family 16
		
		DMA: preallocated 256 KiB pool for atomic coherent allocations
		
		S3C Power Management, Copyright 2004 Simtec Electronics
		
		EXYNOS4x12 PMU Initialize
		
		EXYNOS: Initializing architecture
		
		bio: create slab <bio-0> at 0
		
		VMEM_VDD_2.8V: 2800 mV 
		
		SCSI subsystem initialized
		
		usbcore: registered new interface driver usbfs
		
		usbcore: registered new interface driver hub
		
		usbcore: registered new device driver usb
		
		s3c-i2c 13860000.i2c: slave address 0x00
		
		s3c-i2c 13860000.i2c: bus frequency set to 19 KHz
		
		sec_pmic 0-0066: No interrupt specified, no interrupts
		
		VDD_ALIVE: failed to apply 1100000uV constraint
		
		s5m8767-pmic s5m8767-pmic: regulator init failed for 0
		
		s3c-i2c 13860000.i2c: i2c-0: S3C I2C adapter
		
		Switched to clocksource mct-frc
		
		NET: Registered protocol family 2
		
		TCP established hash table entries: 8192 (order: 3, 32768 bytes)
		
		TCP bind hash table entries: 8192 (order: 5, 163840 bytes)
		
		TCP: Hash tables configured (established 8192 bind 8192)
		
		TCP: reno registered
		
		UDP hash table entries: 512 (order: 2, 24576 bytes)
		
		UDP-Lite hash table entries: 512 (order: 2, 24576 bytes)
		
		NET: Registered protocol family 1
		
		RPC: Registered named UNIX socket transport module.
		
		RPC: Registered udp transport module.
		
		RPC: Registered tcp transport module.
		
		RPC: Registered tcp NFSv4.1 backchannel transport module.
		
		futex hash table entries: 1024 (order: 4, 65536 bytes)
		
		bounce pool size: 64 pages
		
		ROMFS MTD (C) 2007 Red Hat, Inc.
		
		msgmni has been set to 1458
		
		io scheduler noop registered
		
		io scheduler deadline registered
		
		io scheduler cfq registered (default)
		
		dma-pl330 12680000.pdma: Loaded driver for PL330 DMAC-1315632
		
		dma-pl330 12680000.pdma: 	DBUFF-32x4bytes Num_Chans-8 Num_Peri-32 Num_Events-32
		
		dma-pl330 12690000.pdma: Loaded driver for PL330 DMAC-1315632
		
		dma-pl330 12690000.pdma: 	DBUFF-32x4bytes Num_Chans-8 Num_Peri-32 Num_Events-32
		
		dma-pl330 12850000.mdma: Loaded driver for PL330 DMAC-1315632
		
		dma-pl330 12850000.mdma: 	DBUFF-64x8bytes Num_Chans-8 Num_Peri-1 Num_Events-32
		
		Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
		
		13800000.serial: ttySAC0 at MMIO 0x13800000 (irq = 84, base_baud = 0) is a S3C6400/10
		
		13810000.serial: ttySAC1 at MMIO 0x13810000 (irq = 85, base_baud = 0) is a S3C6400/10
		
		13820000.serial: ttySAC2 at MMIO 0x13820000 (irq = 86, base_baud = 0) is a S3C6400/10
		
		console [ttySAC2] enabled
		
		13830000.serial: ttySAC3 at MMIO 0x13830000 (irq = 87, base_baud = 0) is a S3C6400/10
		
		brd: module loaded
		
		loop: module loaded
		
		dm9000 5000000.ethernet: read wrong id 0x01010101
		
		eth0: dm9000a at f0076000,f0078004 IRQ 167 MAC: 00:0a:2d:a6:55:a2 (platform data)
		
		usbcore: registered new interface driver asix
		
		usbcore: registered new interface driver ax88179_178a
		
		usbcore: registered new interface driver cdc_ether
		
		usbcore: registered new interface driver smsc75xx
		
		usbcore: registered new interface driver smsc95xx
		
		usbcore: registered new interface driver net1080
		
		usbcore: registered new interface driver cdc_subset
		
		usbcore: registered new interface driver zaurus
		
		usbcore: registered new interface driver cdc_ncm
		
		ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
		
		ehci-exynos: EHCI EXYNOS driver
		
		usbcore: registered new interface driver usb-storage
		
		mousedev: PS/2 mouse device common for all mice
		
		input: 100a0000.keypad as /devices/100a0000.keypad/input/input0
		
		device-mapper: ioctl: 4.27.0-ioctl (2013-10-30) initialised: dm-devel@redhat.com
		
		sdhci: Secure Digital Host Controller Interface driver
		
		sdhci: Copyright(c) Pierre Ossman
		
		s3c-sdhci 12530000.sdhci: clock source 2: mmc_busclk.2 (40000000 Hz)
		
		mmc0: no vqmmc regulator found
		
		mmc0: SDHCI controller on samsung-hsmmc [12530000.sdhci] using ADMA
		
		Synopsys Designware Multimedia Card Interface Driver
		
		dwmmc_exynos 12550000.mmc: no vmmc regulator found: -19
		
		dwmmc_exynos 12550000.mmc: Using internal DMA controller.
		
		dwmmc_exynos 12550000.mmc: Version ID is 240a
		
		dwmmc_exynos 12550000.mmc: DW MMC controller at irq 109, 32 bit host data width, 128 deep fifo
		
		dwmmc_exynos 12550000.mmc: 1 slots initialized
		
		usbcore: registered new interface driver usbhid
		
		usbhid: USB HID core driver
		
		TCP: cubic registered
		
		NET: Registered protocol family 17
		
		NET: Registered protocol family 15
		
		Registering SWP/SWPB emulation handler
		
		VMEM_VDD_2.8V: disabling
		
		regulator-dummy: disabling
		
		drivers/rtc/hctosys.c: unable to open rtc device (rtc0)
		
		mmc1: BKOPS_EN bit is not set
		
		dm9000 5000000.ethernet eth0: link down
		
		mmc_host mmc1: Bus speed (slot 0) = 50000000Hz (slot req 52000000Hz, actual 50000000HZ div = 0)
		
		mmc_host mmc1: Bus speed (slot 0) = 100000000Hz (slot req 52000000Hz, actual 50000000HZ div = 1)
		
		mmc1: new high speed DDR MMC card at address 0001
		
		mmcblk0: mmc1:0001 4YMD3R 3.64 GiB 
		
		mmcblk0boot0: mmc1:0001 4YMD3R partition 1 4.00 MiB
		
		mmcblk0boot1: mmc1:0001 4YMD3R partition 2 4.00 MiB
		
		mmcblk0rpmb: mmc1:0001 4YMD3R partition 3 512 KiB
		
		 mmcblk0: p1 p2 p3 p4
		
		 mmcblk0boot1: unknown partition table
		
		 mmcblk0boot0: unknown partition table
		
		dm9000 5000000.ethernet eth0: link up, 100Mbps, full-duplex, lpa 0x45E1
		
		IP-Config: Guessing netmask 255.255.255.0
		
		IP-Config: Complete:
		
		     device=eth0, hwaddr=00:0a:2d:a6:55:a2, ipaddr=192.168.9.9, mask=255.255.255.0, gw=255.255.255.255
		
		     host=192.168.9.9, domain=, nis-domain=(none)
		
		     bootserver=255.255.255.255, rootserver=192.168.9.120, rootpath=
		
		clk: Not disabling unused clocks
		
		VFS: Mounted root (nfs filesystem) on device 0:10.  /*挂载根文件系统(从 nfs filesystem知挂载的是NFS rootfs)
          也可挂载jffs2 ramdisk cramfs等格式rootfs 等               
	          如果到这里启动失败,可能原因
	          1. bootargs 参数设置用问题  ,如设置mtdblock2 写成了mtdblock3, 或路径,名称不对等
	          2. 设为nfs挂载,验证rootfs内容有没问题
	          3. 制作镜像过程有没问题 
	          */			
			
		devtmpfs: mounted
		
		Freeing unused kernel memory: 228K (c0530000 - c0569000)  	
  }	
  
  {
    
    //-------根文件系统阶段(可运行应用程序)
		[root@farsight ]# ls
		a.out    dev      lib      mnt      root     sys      usr
		bin      etc      linuxrc  proc     sbin     tmp      var
		[root@farsight ]# ./a.out
		hello  	
  }	
}		

5.U-BOOT移植

很多厂商uboot都已经做好了,很少需要移植,直接用就可以了。

我们熟悉常用的命令,会搭建环境就可以了

其次我们在公司里不可能是第一个做uboot的人,把公司之前的uboot拿过来与官方的版本进行对比,看那些进行了改动

  • 善用对比软件Beyond
  • 选择官方源码版本下载, 配置编译
    a. 指定交叉编译工具链
    b. 指定cpu 和board(参考最类似配置如origen)
    c. 编译
  • 实现串口信息输出
    a. 跟踪运行路径(led点灯法)
    b. 串口输出(检查uart初始化相关部分代码 见lowlevel_init.s)
  • 网卡移植(实现能用tftp nfs 方便开发调试)
    a. 寄存器地址
    b. 参数设置
  • FLASH移植(实现能下载软件到FLASH,产品能离线运行)

image-20241219211502169

image-20241219213044607

U-Boot的移植是一个涉及多个步骤的过程,特别是当使用某个厂商的CPU并自己配置外设时。以下是一些基本的移植步骤和考虑因素:

  1. 获取源码:首先,您需要获取适用于您所用CPU架构的U-Boot源码。这通常可以从U-Boot的官方网站或芯片厂商的网站获取。

  2. 设置交叉编译环境:移植U-Boot之前,需要设置交叉编译环境,因为您需要在宿主机上编译出能够在目标硬件上运行的代码。

  3. 复制现有板级目录:在U-Boot的board/目录下复制一个现有的板级目录,并重命名以反映您的硬件配置。

  4. 修改Makefile:在新的板级目录中,修改Makefile以包含您的板级特定的配置和编译选项。

  5. 配置CPU和板级设置:在arch/目录下,您可能需要根据您的CPU架构添加或修改初始化代码。同时,在板级目录下,您需要配置与您的硬件相关的初始化代码。

  6. 添加或修改驱动程序:如果您的外设需要特定的驱动程序,您可能需要在drivers/目录下添加或修改驱动代码。

  7. 环境变量设置:设置环境变量,如bootargsbootcmd,以确保U-Boot知道如何引导您的系统。

  8. 编译U-Boot:在完成所有必要的配置后,编译U-Boot。如果编译成功,您将得到一个二进制映像文件,可以烧录到您的开发板上。

  9. 测试:在开发板上测试U-Boot,确保它能够正确引导您的系统。

  10. 调试:如果在引导过程中遇到问题,您可能需要调试U-Boot的代码,查看串口输出,以确定问题所在。

附录

关于如何烧录uboot

将U-Boot编译出来的二进制文件烧录到开发板上,通常需要以下步骤:

  1. 编译U-Boot:确保你已经成功编译了U-Boot,并生成了二进制文件,如u-boot.bin

  2. 准备烧录工具:根据你的开发板和使用的连接方式,准备相应的烧录工具。这可能是通过SD卡、串口、JTAG接口、USB或其他接口。

  3. 连接开发板:将开发板通过适当的方式连接到你的计算机上。

  4. 烧录U-Boot:使用烧录工具将u-boot.bin文件烧录到开发板的存储介质上。这可能涉及到以下操作:

    • 如果是通过SD卡烧录,你可能需要将u-boot.bin文件复制到SD卡上,然后通过开发板的启动模式选择从SD卡启动。
    • 如果是通过串口烧录,你可能需要使用如imxdownloadtftpnfs等工具。
    • 如果是通过JTAG接口,你可能需要使用J-Link等调试器和相应的软件。
  5. 验证烧录:烧录完成后,重启开发板,如果一切设置正确,U-Boot应该能够正常启动。

  6. 解决烧录问题:如果在烧录过程中遇到问题,检查连接、烧录工具的配置以及U-Boot的编译是否正确。

例如,如果你的开发板支持通过SD卡烧录,你可以按照以下步骤操作:

  • u-boot.bin文件复制到格式化为FAT32的SD卡上。
  • 将SD卡插入开发板。
  • 设置开发板为SD卡启动模式。
  • 重启开发板,U-Boot应该能够从SD卡启动。

如果你的开发板需要通过串口烧录,你可能需要使用特定的烧录命令或脚本,这通常可以在开发板的文档或社区找到相关信息。

请注意,具体的烧录步骤可能会因开发板的不同而有所差异,所以最好参考开发板的用户手册或技术文档。