ARM uboot 源码分析6 - uboot如何启动内核

news/2024/5/3 13:35:50/文章来源:https://blog.csdn.net/weixin_42109053/article/details/129102794

一、uboot 和内核到底是什么

1、uboot 是一个裸机程序

(1) uboot 的本质就是一个复杂点的裸机程序。和我们在 ARM 裸机全集中学习的每一个裸机程序并没有本质区别

(2) ARM 裸机第十六部分写了个简单的 shell,这东西其实就是个mini 型的 uboot。


2、内核本身也是一个"裸机程序"

(1) 操作系统内核本身就是一个裸机程序,和 uboot、和其他裸机程序并没有本质区别。 正是内核运行起来了之后,才有了称为操作系统的环境,操作系统负责管理所有计算机资源

(2) 区别就是操作系统运行起来后,在软件上分为内核层和应用层,分层后两层的权限不同,内存访问和设备操作的管理上更加精细(内核可以随便访问各种硬件,而应用程序只能被限制的访问硬件和内存地址)。

直观来看:uboot 的镜像是 u-boot.bin,linux 系统的镜像是zImage,这两个东西其实都是两个裸机程序镜像。从系统的启动角度来讲,内核其实就是一个大的复杂点的裸机程序。


3、部署在 SD 卡中特定分区内

(1) 一个完整的软件+硬件的嵌入式系统,静止时(未上电时) bootloader、kernel、rootfs 等必须的软件都以镜像的形式存储在启动介质中( X210 中是 iNand/SD卡);运行时都是在 DDR 内存中运行的,与存储介质无关。

上面 2 个状态都是稳定状态,第 3 个状态是动态过程,即从静止态到运行态的过程,也就是启动过程。


(2) 动态启动过程,就是一个从 SD 卡逐步搬移到 DDR 内存,并且运行启动代码进行相关的硬件初始化和软件架构的建立,最终达到运行时稳定状态。

(3) 静止时,u-boot.bin、zImage、 rootfs 都在 SD 卡中,他们不可能随意存在 SD 卡的任意位置,因此需要对 SD 卡进行一个分区,然后将各种镜像各自存在各自的分区中,这样在启动过程中uboot、内核等就知道到哪里去找谁。(uboot 和 kernel 中的分区表必须一致,同时和 SD 卡的实际使用的分区要一致)。

通过 fastboot 命令,可以侧面知道当前的分区表的情况:

在这里插入图片描述


4、运行时必须先加载到 DDR 中链接地址处

(1) uboot 在第一阶段中进行重定位时,将第二阶段(即整个 uboot 镜像)加载到 DDR 的 0xc3e0_0000 地址处,这个地址就是 uboot 的链接地址

(2) 内核也有类似要求,uboot 启动内核时将内核从 SD 卡读取放到 DDR 中(其实就是个重定位的过程),不能随意放置,必须放在内核的链接地址处,否则启动不起来。譬如我们使用的内核链接地址是 0x30008000


5、内核启动需要必要的启动参数

(1) uboot 是无条件启动的,从零开始启动的

(2) 内核是不能开机自动完全从零开始启动的,内核启动需要别人帮忙。uboot 要帮助内核实现重定位(从 SD 卡到 DDR),uboot 还要给内核提供启动参数


二、启动内核第一步:加载内核到 DDR中

(1) uboot 要启动内核,分为 2 个步骤:
第一步,是将内核镜像从启动介质中加载到 DDR 中;
第二步,是去 DDR 中启动内核镜像。(内核代码根本就没考虑重定位,因为内核知道会有 uboot 之类的把自己加载到 DDR 中链接地址处的,所以内核直接就是从链接地址处开始运行的)。


1、静态内核镜像在哪里?

(1) SD卡/iNand/Nand/NorFlash 等:raw 分区;
常规启动时,各种镜像都在 SD 卡中,因此 uboot 只需要从 SD 卡的 kernel 分区,去读取内核镜像到 DDR 中即可。读取要使用 uboot 的命令来读取(譬如 X210 的 iNand 版本是 movi 命令,X210 的 Nand 版本就是 Nand 命令)

在这里插入图片描述

(2) 这种启动方式来加载 DDR,使用命令:movi read kernel 30008000。其中 kernel 指的 是 uboot 中的 kernel 分区(就是 uboot 中规定的 SD 卡中的一个区域范围,这个区域范围被设计来存放 kernel 镜像,就是所谓的 kernel 分区)

x210 # movi read  kernel  30008000
reading kernel.. 1073, 8192 
MMC read: dev # 0, block # 1073, count 8192 ...8192 blocks read: OK
completed
x210 #  
x210 #  
x210 #  
x210 # bootm 30008000
Boot with zImage
......

在这里插入图片描述


(3) tftp、nfs 等网络下载方式从远端服务器获取镜像
uboot 还支持远程启动,也就是内核镜像不烧录到开发板的 SD 卡中,而是放在主机的服务器中,然后需要启动时 uboot 通过网络从服务器中下载镜像到开发板的 DDR 中。

  1. tftp 服务器是 Windows 主机
  • 将开发板和 Windows 主机通过网线连接起来,并且设置 Windows 主机 ip 地址为 192.168.1.10.在这里插入图片描述

  • 设置 Windows tftp 服务器的 IP 和目录设置。
    在这里插入图片描述

  • 设置开发板的环境变量。
    在这里插入图片描述

  • 使用命令,将 tftp 服务器目录的镜像文件,传输到 DDR 指定地址:tftp 30008000 zImage-android
    在这里插入图片描述

  • 最后,使用命令启动内核镜像:bootm 30008000
    在这里插入图片描述
x210 # bootm 30008000
Boot with zImageStarting kernel ...Uncompressing Linux... done, booting the kernel.
Initializing cgroup subsys cpu
Linux version 3.0.8 (lqm@lqm) (gcc version 4.4.1 (Sourcery G++ Lite 2009q3-67) ) #49 PREEMPT Tue Mar 22 19:35:49 CST 2016
CPU: ARMv7 Processor [412fc082] revision 2 (ARMv7), cr=10c53c7f
CPU: VIPT nonaliasing data cache, VIPT aliasing instruction cache
Machine: X210
Ignoring unrecognised tag 0x41001099
Memory policy: ECC disabled, Data cache writeback
CPU S5PV210/S5PC110 (id 0x43110220)
S3C24XX Clocks, Copyright 2004 Simtec Electronics
S5PV210: PLL settings, A=1000000000, M=667000000, E=96000000 V=54000000
S5PV210: ARMCLK=1000000000, HCLKM=200000000, HCLKD=166750000
HCLKP=133400000, PCLKM=100000000, PCLKD=83375000, PCLKP=66700000
sclk_dmc: source is sclk_a2m (0), rate is 200000000
sclk_onenand: source is hclk_psys (0), rate is 66700000
uclk1: source is mout_mpll (6), rate is 66700000
uclk1: source is mout_mpll (6), rate is 66700000
uclk1: source is mout_mpll (6), rate is 66700000
uclk1: source is mout_mpll (6), rate is 66700000
sclk_mixer: source is sclk_dac (0), rate is 24000000
sclk_fimc: source is ext_xtal (0), rate is 24000000
sclk_fimc: source is ext_xtal (0), rate is 24000000
sclk_fimc: source is ext_xtal (0), rate is 24000000
sclk_cam0: source is xusbxti (1), rate is 12000000
sclk_cam1: source is ext_xtal (0), rate is 12000000
sclk_fimd: source is ext_xtal (0), rate is 24000000
sclk_mmc: source is mout_mpll (6), rate is 47642857
sclk_mmc: source is mout_epll (7), rate is 96000000
sclk_mmc: source is mout_mpll (6), rate is 47642857
sclk_mmc: source is mout_epll (7), rate is 96000000
sclk_mfc: source is sclk_a2m (0), rate is 200000000
sclk_g2d: source is sclk_a2m (0), rate is 200000000
sclk_g3d: source is sclk_a2m (0), rate is 100000000
sclk_csis: source is ext_xtal (0), rate is 24000000
sclk_spi: source is ext_xtal (0), rate is 24000000
sclk_spi: source is ext_xtal (0), rate is 24000000
sclk_pwi: source is ext_xtal (0), rate is 24000000
sclk_pwm: source is ext_xtal (0), rate is 24000000
s5p: 37748736 bytes system memory reserved for mfc at 0x3dc00000, 0-bank base(0x3dc00000)
s5p: 37748736 bytes system memory reserved for mfc at 0x4dbf5000, 1-bank base(0x4dbf5000)
s5p: 25165824 bytes system memory reserved for fimc0 at 0x4c3f5000, 1-bank base(0x4c3f5000)
s5p: 10137600 bytes system memory reserved for fimc1 at 0x4ba4a000, 1-bank base(0x4ba4a000)
s5p: 6291456 bytes system memory reserved for fimc2 at 0x4b44a000, 1-bank base(0x4b44a000)
s5p: 25165824 bytes system memory reserved for jpeg at 0x3c400000, 0-bank base(0x3c400000)
s5p: 12288000 bytes system memory reserved for fimd at 0x4a892000, 1-bank base(0x4a892000)
s5p: 1843200 bytes system memory reserved for pmem_gpu1 at 0x3c23e000, 0-bank base(0x3c23e000)
s5p: 8388608 bytes system memory reserved for g2d at 0x3ba3e000, 0-bank base(0x3ba3e000)
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 89819
Kernel command line: console=ttySAC2,115200 root=/dev/mmcblk0p2 rw init=/linuxrc rootfstype=ext3
PID hash table entries: 2048 (order: 1, 8192 bytes)
Dentry cache hash table entries: 65536 (order: 6, 262144 bytes)
Inode-cache hash table entries: 32768 (order: 5, 131072 bytes)
Memory: 186MB 168MB 0MB = 354MB total
Memory: 350232k/511148k available, 13140k reserved, 0K highmem
Virtual kernel memory layout:vector  : 0xffff0000 - 0xffff1000   (   4 kB)fixmap  : 0xfff00000 - 0xfffe0000   ( 896 kB)DMA     : 0xff000000 - 0xffe00000   (  14 MB)vmalloc : 0xe0800000 - 0xfd000000   ( 456 MB)lowmem  : 0xc0000000 - 0xe0000000   ( 512 MB)modules : 0xbf000000 - 0xc0000000   (  16 MB).init : 0xc0008000 - 0xc0079000   ( 452 kB).text : 0xc0079000 - 0xc06cf6c0   (6490 kB).data : 0xc06d0000 - 0xc0719900   ( 295 kB).bss : 0xc0719924 - 0xc085a250   (1283 kB)
SLUB: Genslabs=11, HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
Preemptible hierarchical RCU implementation.
NR_IRQS:208
VIC @fd000000: id 0x00041192, vendor 0x41
VIC @fd010000: id 0x00041192, vendor 0x41
VIC @fd020000: id 0x00041192, vendor 0x41
VIC @fd030000: id 0x00041192, vendor 0x41
mult[140737]
max_delta_ns[2937815369]
min_delta_ns[30517]
rate[32768]
HZ[200]
Console: colour dummy device 80x30
Calibrating delay loop... 992.87 BogoMIPS (lpj=2482176)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 512
Initializing cgroup subsys debug
Initializing cgroup subsys cpuacct
Initializing cgroup subsys freezer
CPU: Testing write buffer coherency: ok
print_constraints: dummy: 
NET: Registered protocol family 16
S3C Power Management, Copyright 2004 Simtec Electronics
pmstats at 00000000
pmem_start is 0x0
---pmem_start is 0x4a892000
Open OV2655 camema sensor 
smdkc110_setup_clocks: sclk_mmc: source is mout_mpll, rate is 47642857
S5PV210: Initializing architecture
s3c-adc s5pv210-adc: attached adc driver
s3c24xx-pwm s3c24xx-pwm.0: tin at 66700000, tdiv at 66700000, tin=divclk, base 0
print_constraints: pd_tv_supply: 5000 mV normal 
print_constraints: pd_lcd_supply: 5000 mV normal 
print_constraints: pd_g3d_supply: 5000 mV normal 
print_constraints: pd_mfc_supply: 5000 mV normal 
print_constraints: pd_audio_supply: 5000 mV normal 
print_constraints: pd_cam_supply: 5000 mV normal 
bio: create slab <bio-0> at 0
print_constraints: B_PWR_5V: 5000 mV 
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
s3c-i2c s3c2440-i2c.0: slave address 0x10
s3c-i2c s3c2440-i2c.0: bus frequency set to 43 KHz
s3c-i2c s3c2440-i2c.0: i2c-0: S3C I2C adapter
s3c-i2c s3c2440-i2c.1: slave address 0x10
s3c-i2c s3c2440-i2c.1: bus frequency set to 65 KHz
s3c-i2c s3c2440-i2c.1: i2c-1: S3C I2C adapter
s3c-i2c s3c2440-i2c.2: slave address 0x10
s3c-i2c s3c2440-i2c.2: bus frequency set to 65 KHz
machine_constraints_voltage: VALIVE_1.1V: failed to apply 1100000uV constraint
(NULL device *): regulator init failed
s3c-i2c s3c2440-i2c.2: i2c-2: S3C I2C adapter
Advanced Linux Sound Architecture Driver Version 1.0.24.
cfg80211: Calling CRDA to update world regulatory domain
Switching to clocksource clock_source_systimer
Switched to NOHz mode on CPU #0
NET: Registered protocol family 2
IP route cache hash table entries: 4096 (order: 2, 16384 bytes)
TCP established hash table entries: 16384 (order: 5, 131072 bytes)
TCP bind hash table entries: 16384 (order: 6, 327680 bytes)
TCP: Hash tables configured (established 16384 bind 16384)
TCP reno registered
UDP hash table entries: 256 (order: 1, 12288 bytes)
UDP-Lite hash table entries: 256 (order: 1, 12288 bytes)
NET: Registered protocol family 1
PMU: registered new PMU device of type 0
input: s3c-button as /devices/virtual/input/input0
s3c button Initialized!!
Loaded driver for PL330 DMAC-0 s3c-pl330DBUFF-64x8bytes Num_Chans-8 Num_Peri-2 Num_Events-32
Loaded driver for PL330 DMAC-1 s3c-pl330DBUFF-8x4bytes Num_Chans-8 Num_Peri-32 Num_Events-32
Loaded driver for PL330 DMAC-2 s3c-pl330DBUFF-8x4bytes Num_Chans-8 Num_Peri-32 Num_Events-32
ashmem: initialized
NTFS driver 2.1.30 [Flags: R/O].
ROMFS MTD (C) 2007 Red Hat, Inc.
yaffs: yaffs built Jan 18 2016 11:34:32 Installing.
msgmni has been set to 684
io scheduler noop registered
io scheduler deadline registered
io scheduler cfq registered (default)
start plist test
end plist test
win->id=2, pmem_start=0x4af9a000
s3cfb s3cfb: [fb2] dma: 0x4af9a000, cpu: 0xe1000000, size: 0x004b0000
FIMD src sclk = 166750000
s3cfb s3cfb: registered successfully
Start display and show logo
s5pv210-uart.0: ttySAC0 at MMIO 0xe2900000 (irq = 16) is a S3C6400/10
s5pv210-uart.1: ttySAC1 at MMIO 0xe2900400 (irq = 20) is a S3C6400/10
s5pv210-uart.2: ttySAC2 at MMIO 0xe2900800 (irq = 24) is a S3C6400/10
console [ttySAC2] enabled
s5pv210-uart.3: ttySAC3 at MMIO 0xe2900c00 (irq = 28) is a S3C6400/10
x210 led driver
Initial GSensor Driver
input: gsensor as /devices/virtual/input/input1
gsensor's ID: 0x01
Found Gsensor hardware
i2c-core: driver [gsensor-iic] using legacy suspend method
i2c-core: driver [gsensor-iic] using legacy resume method
PA FB = 0x4AF9A000, bits per pixel = 32
screen width=1024 height=600 va=0xdaf9a000 pa=0x4af9a000
xres_virtual = 1024, yres_virtual = 1200, xoffset = 0, yoffset = 0
fb_size=4915200
Back frameBuffer[0].VAddr=db1f2000 PAddr=4b1f2000 size=2457600
brd: module loaded
loop: module loaded
S3C NAND Driver, (c) 2008 Samsung Electronics
Unknown NAND Device.
PPP generic driver version 2.4.2
PPP Deflate Compression module registered
PPP BSD Compression module registered
PPP MPPE Compression module registered
NET: Registered protocol family 24
dm9000 Ethernet Driver, V1.31
eth0: dm9000b at e083c000,e083e004 IRQ 42 MAC: 00:09:c0:ff:ec:48 (platform data)
usbcore: registered new interface driver catc
catc: v2.8:CATC EL1210A NetMate USB Ethernet driver
usbcore: registered new interface driver kaweth
pegasus: v0.6.14 (2006/09/27), Pegasus/Pegasus II USB Ethernet driver
usbcore: registered new interface driver pegasus
rtl8150: v0.6.2 (2004/08/27):rtl8150 based usb-ethernet driver
usbcore: registered new interface driver rtl8150
usbcore: registered new interface driver asix
usbcore: registered new interface driver cdc_ether
usbcore: registered new interface driver dm9601
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
cdc_ncm: 04-Aug-2011
usbcore: registered new interface driver cdc_ncm
ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
failed to find udc vcc source
Failed to power up USB
s5p-ehci s5p-ehci: S5P EHCI Host Controller
s5p-ehci s5p-ehci: new USB bus registered, assigned bus number 1
s5p-ehci s5p-ehci: irq 87, io mem 0xec200000
s5p-ehci s5p-ehci: USB 0.0 started, EHCI 1.00
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 1 port detected
ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
failed to find udc vcc source
Failed to power up USB
s5p-ohci s5p-ohci: EXYNOS OHCI Host Controller
s5p-ohci s5p-ohci: new USB bus registered, assigned bus number 2
s5p-ohci s5p-ohci: irq 87, io mem 0xec300000
hub 2-0:1.0: USB hub found
hub 2-0:1.0: 1 port detected
usbcore: registered new interface driver cdc_acm
cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
Initializing USB Mass Storage driver...
usbcore: registered new interface driver usb-storage
USB Mass Storage support registered.
usbcore: registered new interface driver usbserial
USB Serial support registered for generic
usbcore: registered new interface driver usbserial_generic
usbserial: USB Serial Driver core
USB Serial support registered for GSM modem (1-port)
usbcore: registered new interface driver option
option: v0.7.2:USB Driver for GSM modems
s3c-udc : S3C HS USB Device Controller Driver, (c) 2008-2009 Samsung Electronics
s3c-udc : version 15 March 2009 (DMA Mode)
android_usb gadget: Mass Storage Function, version: 2009/09/11
android_usb gadget: Number of LUNs=1lun0: LUN: removable file: (no medium)
android_usb gadget: android_usb ready
failed to find udc vcc source
Failed to power up USB
Registered gadget driver 'android_usb'
mousedev: PS/2 mouse device common for all mice
cal_x_max=800,cal_y_max=480
samsung-ts s3c64xx-ts: driver attached, registering input device
input: s3c_ts as /devices/virtual/input/input2
==kzalloc success=
usb 1-1: new high speed USB device number 2 using s5p-ehci
hub 1-1:1.0: USB hub found
hub 1-1:1.0: 4 ports detected
=============gsl_load_fw end==============
[GSLX680] Enter gslX680_ts_init
input: gslX680 as /devices/platform/s3c2440-i2c.1/i2c-1/1-0040/input/input3
i2c-core: driver [gslX680] using legacy suspend method
i2c-core: driver [gslX680] using legacy resume method
==gsl_ts_init== ret=0
S3C24XX RTC, (c) 2004,2006 Simtec Electronics
s3c-rtc s3c64xx-rtc: rtc disabled, re-enabling
using rtc device, s3c, for alarms
s3c-rtc s3c64xx-rtc: rtc core: registered s3c as rtc0
i2c /dev entries driver
lirc_dev: IR Remote Control driver registered, major 251 
IR NEC protocol handler initialized
IR RC5(x) protocol handler initialized
IR RC6 protocol handler initialized
IR JVC protocol handler initialized
IR Sony protocol handler initialized
IR RC5 (streamzap) protocol handler initialized
IR LIRC bridge handler initialized
Linux video capture interface: v2.00
mfc_init: <6>S5PC110 MFC Driver, (c) 2009 Samsung ElectronicsS3C JPEG Driver, (c) 2007 Samsung Electronics
JPEG driver for S5PV210
i2c i2c-1: attached s5p_ddc into i2c adapter successfully
S5PC11X HPD Driver, (c) 2010 Samsung Electronics
S5PC11X CEC Driver, (c) 2010 Samsung Electronics
S3C2410 Watchdog Timer, (c) 2004 Simtec Electronics
s3c2410-wdt s3c2410-wdt: watchdog inactive, reset disabled, irq enabled
sdhci: Secure Digital Host Controller Interface driver
sdhci: Copyright(c) Pierre Ossman
s3c-sdhci s3c-sdhci.0: clock source 0: hsmmc (133400000 Hz)
s3c-sdhci s3c-sdhci.0: clock source 2: sclk_mmc (47642857 Hz)
mmc0: no vmmc regulator found
mmc0: SDHCI controller on samsung-hsmmc [s3c-sdhci.0] using ADMA
s3c-sdhci s3c-sdhci.1: clock source 0: hsmmc (133400000 Hz)
s3c-sdhci s3c-sdhci.1: clock source 2: sclk_mmc (96000000 Hz)
mmc1: no vmmc regulator found
mmc1: SDHCI controller on samsung-hsmmc [s3c-sdhci.1] using ADMA
s3c-sdhci s3c-sdhci.2: clock source 0: hsmmc (133400000 Hz)
s3c-sdhci s3c-sdhci.2: clock source 2: sclk_mmc (47642857 Hz)
mmc2: no vmmc regulator found
mmc2: SDHCI controller on samsung-hsmmc [s3c-sdhci.2] using ADMA
s3c-sdhci s3c-sdhci.3: clock source 0: hsmmc (133400000 Hz)
s3c-sdhci s3c-sdhci.3: clock source 2: sclk_mmc (96000000 Hz)
mmc3: no vmmc regulator found
mmc3: SDHCI controller on samsung-hsmmc [s3c-sdhci.3] using ADMA
usbcore: registered new interface driver usbhid
usbhid: USB HID core driver
logger: created 256K log 'log_main'
logger: created 256K log 'log_events'
logger: created 256K log 'log_radio'
logger: created 256K log 'log_system'
mmc0: new high speed MMC card at address 0001
mmcblk0: mmc0:0001 004GE0 3.68 GiB 
mmcblk0boot0: mmc0:0001 004GE0 partition 1 2.00 MiB
mmcblk0boot1: mmc0:0001 004GE0 partition 2 2.00 MiB
Error: Driver 'samsung-audio' is already registered, aborting...
wm8978 probemmcblk0: p1 p2 p3 p4mmcblk0boot1: unknown partition tablemmcblk0boot0: unknown partition table
mmc2: new SDHC card at address 1234
mmcblk1: mmc2:1234 SA08G 7.21 GiB mmcblk1: p1
asoc: wm8978_codec <-> samsung-i2s.0 mapping ok
asoc: wm8978_codec <-> samsung-i2s.0 mapping ok
ALSA device list:#0: smdk
Netfilter messages via NETLINK v0.30.
NF_TPROXY: Transparent proxy support initialized, version 4.1.0
NF_TPROXY: Copyright (c) 2006-2007 BalaBit IT Ltd.
ip_tables: (C) 2000-2006 Netfilter Core Team
TCP cubic registered
NET: Registered protocol family 10
ip6_tables: (C) 2000-2006 Netfilter Core Team
IPv6 over IPv4 tunneling driver
NET: Registered protocol family 17
NET: Registered protocol family 15
lib80211: common routines for IEEE802.11 drivers
VFP support v0.3: implementor 41 architecture 3 part 30 variant c rev 2
regulator_init_complete: pd_cam_supply: incomplete constraints, leaving on
regulator_init_complete: pd_mfc_supply: incomplete constraints, leaving on
regulator_init_complete: pd_tv_supply: incomplete constraints, leaving on
s3c-rtc s3c64xx-rtc: setting system clock to 2023-02-16 12:41:57 UTC (1676551317)
FIMC0 registered successfully
FIMC1 registered successfully
FIMC2 registered successfully
S5PC1XX TVOUT Driver, (c) 2009 Samsung Electronics
s5p-tvout s5p-tvout: hpd status is cable removed
Warning: unable to open an initial console.
Freeing init memory: 452K
init (1): /proc/1/oom_adj is deprecated, please use /proc/1/oom_score_adj instead.
init: cannot open '/initlogo.rle'
EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null)
EXT4-fs (mmcblk0p2): re-mounted. Opts: (null)
EXT4-fs (mmcblk0p2): re-mounted. Opts: (null)
EXT4-fs (mmcblk0p4): warning: maximal mount count reached, running e2fsck is recommended
EXT4-fs (mmcblk0p4): recovery complete
EXT4-fs (mmcblk0p4): mounted filesystem with ordered data mode. Opts: (null)
EXT4-fs (mmcblk0p3): warning: maximal mount count reached, running e2fsck is recommended
EXT4-fs (mmcblk0p3): recovery complete
EXT4-fs (mmcblk0p3): mounted filesystem with ordered data mode. Opts: (null)
EXT4-fs (mmcblk0p1): VFS: Can't find ext4 filesystem
init: cannot find '/system/etc/install-recovery.sh', disabling 'flash_recovery'
android_usb: already disabled
adb_open
mtp_bind_config
adb_bind_config
android_work: did not send uevent (0 0   (null))
/ # PVR_K:(Warning): SysFinalise: Version string: SGX540 S5PC110 [543, drivers/gpu/pvr/s5pc110/sysconfig.c]
win->id=0, pmem_start=0x4a892000
s3cfb s3cfb: [fb0] dma: 0x4a892000, cpu: 0xe3000000, size: 0x00708000
s3cfb s3cfb: [fb1] dma: 0x47000000, cpu: 0xff800000, size: 0x004b0000
init: start ~~~~~~~~ bootanim 
warning: `zygote' uses 32-bit capabilities (legacy support in use)
request_suspend_state: wakeup (3->0) at 23111579551 (2023-02-16 12:42:13.779333833 UTC)
init: sys_prop: permission denied uid:1000  name:rw.HTTP_PROXY
init: start ~~~~~~~~ dhcpcd_eth0:-h android-884fd1bdcfd07e6b eth0 
acc_open
acc_release
RTL871X: rtl8188eu driver version=v4.1.5_7309.20130425
RTL871X: build time: May  8 2014 09:34:58
usbcore: registered new interface driver rtl8188eu
RTL871X: +rtw_drv_halt
usbcore: deregistering interface driver rtl8188eu
RTL871X: -rtw_drv_halt
init: start ~~~~~~~~ up_eth0 
init: untracked pid 2624 exited
init: start ~~~~~~~~ dhcpcd_eth0:-h android-884fd1bdcfd07e6b eth0 
dm9000 dm9000: eth0: link down
ADDRCONF(NETDEV_UP): eth0: link is not ready
ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
dm9000 dm9000: eth0: link up, 100Mbps, full-duplex, lpa 0xCDE1
init: start ~~~~~~~~ dhcpcd_eth0:-h android-884fd1bdcfd07e6b eth0 

分析总结:最终结果要的是内核镜像到 DDR 中特定地址即可,不管内核镜像是怎么到 DDR 中的。以上 2 种方式各有优劣。产品出厂时会设置为从 SD 卡中启动(客户不会还要搭建 tftp 服务器才能用···);tftp 下载远程启动这种方式一般用来开发。


2、镜像要放在 DDR 的什么地址?

(1) 内核一定要放在链接地址处,链接地址去内核源代码的链接脚本或者 Makefile 中去查找。X210 中是 0x30008000


三、zImage和uImage的区别联系

1、bootm 命令对应 do_bootm 函数

(1) 命令名前加 do_ 即可构成这个命令对应的函数,因此当我们 bootm 命令执行时,uboot 实际执行的函数叫 do_bootm 函数,在 cmd_bootm.c

在这里插入图片描述


(2) do_bootm 刚开始定义了一些变量,然后用宏来条件编译执行了 secureboot 的一些代码(主要进行签名认证),先不管他;然后进行了一些一些细节部分操作,也不管他。然后到了 CONFIG_ZIMAGE_BOOT用这个宏来控制进行条件编译一段代码,这段代码是用来支持 zImage 格式的内核启动的

在这里插入图片描述


2、vmlinuz 和 zImage 和 uImage

(1) uboot 经过编译直接生成的 elf 格式的可执行程序是 u-boot,这个程序类似于 windows 下的 exe 格式,在操作系统下是可以直接执行的。但是这种格式不能用来烧录下载

在这里插入图片描述

我们用来烧录下载的是 u-boot.bin,这个东西是由 u-boot 使用 arm-linux-objcopy 工具进行加工(主要目的是去掉一些无用的)得到的。这个 u-boot.bin 就叫镜像(image),镜像就是用来烧录到 iNand 中执行的

在这里插入图片描述


(2) linux 内核经过编译后,也会生成一个 elf 格式的可执行程序,叫 vmlinuxvmlinuz,这个就是原始的、未经任何处理加工的原版内核 elf 文件。

在这里插入图片描述

嵌入式系统部署时烧录的一般不是这个 vmlinuz/vmlinux,而是要用 objcopy 工具去制作成烧录镜像格式(就是 u-boot.bin 这种,但是内核没有 .bin 后缀),经过制作加工成烧录镜像的文件就叫 Image(这个制作烧录镜像主要目的就是缩减大小,节省磁盘)


(3) 原则上, Image 就可以直接被烧录到 Flash 上进行启动执行(类似于 u-boot.bin ),但是实际上并不是这么简单。实际上 linux 的作者们觉得 Image 还是太大了,所以对 Image 进行了压缩,并且在 Image 压缩后的文件的前端附加了一部分解压缩代码。构成了一个压缩格式的镜像就叫 zImage。(因为当年 Image 大小刚好比一张软盘(软盘有 2 种,1.2M 的和 1.44MB 两种)大,为了节省 1 张软盘的钱于是乎设计了这种压缩 Image 成 zImage 的技术)。

(4) uboot 为了启动 linux 内核,还发明了一种内核格式叫 uImage。uImage 是由 zImage 加工得到的,uboot 中有一个工具,可以将 zImage 加工生成 uImage。注意: uImage 不关 linux 内核的事,linux 内核只管生成 zImage 即可,然后 uboot 中的 mkimage 工具再去由 zImage 加工生成 uImage 来给 uboot 启动。这个加工过程其实就是在 zImage 前面加上 64 字节的 uImage 的头信息即可

(4) 原则上,uboot 启动时应该给他 uImage 格式的内核镜像,但是实际上 uboot 中也可以支持 zImage,是否支持就看 x210_sd.h 中是否定义了 LINUX_ZIMAGE_MAGIC 这个宏。所以大家可以看出:有些 uboot 是支持 zImage 启动的,有些则不支持。但是所有的 uboot 肯定都支持 uImage 启动

在这里插入图片描述


3、编译内核得到 uImage 去启动

(1) 如果直接在 kernel 底下去 make uImage 会提示:mkimage command not found。解决方案是去 uboot/tools 下 cp mkimage /usr/local/bin/,复制 mkimage 工具到系统目录下。再去 make uImage 即可。


四、zImage 启动细节

(1) do_bootm 函数中一直到 397 行的 after_header_check 这个符号处,都是在进行镜像的头部信息校验。校验时就要根据不同种类的 image 类型进行不同的校验。所以 do_bootm 函数的核心,就是去分辨传进来的 image 到底是什么类型,然后按照这种类型的头信息格式去校验。校验通过则进入下一步准备启动内核;如果校验失败则认为镜像有问题,所以不能启动。

在这里插入图片描述


1、LINUX_ZIMAGE_MAGIC

(1) 这个是一个定义的魔数,这个数等于 0x016f2818,表示这个镜像是一个 zImage。也就是说,zImage 格式的镜像中,在头部的一个固定位置存放了这个数作为格式标记。如果我们拿到了一个 image,去他的那个位置去取 4 字节,判断它是否等于 LINUX_ZIMAGE_MAGIC,则可以知道这个镜像是不是一个 zImage。

在这里插入图片描述


(2) 启动内核的命令: bootm 0x30008000,所以 do_boom 函数的 argc=2,argv[0]=bootm, argv[1]=0x30008000。
在这里插入图片描述

但是实际 bootm 命令还可以不带参数执行。如果不带参数直接 bootm,则会从 CFG_LOAD_ADDR 地址去执行(定义在 x210_sd.h 中)。

在这里插入图片描述


(3) zImage 头部开始的第 36-49 字节处存放着 zImage 标志魔数,从这个位置取出,然后对比 LINUX_ZIMAGE_MAGIC 。可以用二进制阅读软件来打开 zImage 查看,就可以证明。很多软件都可以打开二进制文件,如 winhex、UltraEditor。

在这里插入图片描述

在这里插入图片描述


2、image_header_t

(1) 这个数据结构是我们 uboot 启动内核使用的一个标准启动数据结构,zImage 头信息也是一个 image_header_t,但是在实际启动之前需要进行一些改造。

hdr->ih_os = IH_OS_LINUX;
hdr->ih_ep = ntohl(addr);

这两句就是在进行改造。

在这里插入图片描述


(2) images 全局变量是 do_bootm 函数中使用,用来完成启动过程的。zImage 的校验过程,其实就是先确认是不是 zImage,确认后再修改 zImage 的头信息到合适,修改后用头信息去初始化 images 这个全局变量,然后就完成了校验。

在这里插入图片描述


五、uImage 启动

1、uImage 启动

在这里插入图片描述

(1) LEGACY(遗留的),在 do_bootm 函数中,这种方式指的就是 uImage 的方式

(2) uImage 方式是 uboot 本身发明的、支持 linux 启动的镜像格式,但是后来这种方式被一种新的方式替代,这个新的方式就是设备树方式(在 do_bootm 方式中叫 FIT)。

(3) uImage 的启动校验主要在 boot_get_kernel 函数中,主要任务就是校验 uImage 的头信息,并且得到真正的 kernel 的起始位置去启动


2、设备树方式内核启动

(1) 设备树方式启动暂时不讲,课程结束后会用补充专题的方式来讲解(很多类似的知识点都会这样处理,譬如前面讲的 MMU)


总结1:uboot 本身设计时只支持 uImage 启动,原来 uboot 的代码也是这样写的。后来有了 fdt 方式之后,就把 uImage 方式命令为 LEGACY 方式,fdt 方式命令为 FIT 方式,于是乎多了写 #if #endif 添加的代码

后来移植的人又为了省事,添加了 zImage 启动的方式,又为了省事把 zImage 启动方式直接写在了 uImage 和 fdt 启动方式之前,于是乎又有了一对 #if #endif。 于是乎整个的代码看起来很恶心。

总结2:第二阶段校验头信息结束,下面进入第三阶段,第三阶段主要任务是启动 linux 内核,调用 do_bootm_linux 函数来完成。

在这里插入图片描述


六、do_bootm_linux 函数

1、找到 do_bootm_linux 函数

在这里插入图片描述
在这里插入图片描述

(1) 函数在 uboot/lib_arm/bootm.c 中。
在这里插入图片描述


2、镜像的 entrypoint

(1) ep 就是 entrypoint 的缩写,就是程序入口。一个镜像文件的起始执行部分不是在镜像的开头(镜像开头有 n 个字节的头信息),真正的镜像文件执行时第一句代码在镜像的中部某个字节处,相当于头部是有一定的偏移量的。这个偏移量记录在头信息中。

在这里插入图片描述


(2) 一般执行一个镜像都是:第一步先读取头信息,然后在头信息的特定地址找MAGIC_NUM,由此来确定镜像种类;第二步对镜像进行校验;第三步再次读取头信息,由特定地址知道这个镜像的各种信息(镜像长度、镜像种类、入口地址);第四步就去 entrypoint 处开始执行镜像。


(3) theKernel = (void (*)(int, int, uint))ep; 将 ep 赋值给 theKernel,则这个函数指针就指向了内存中加载的OS镜像的真正入口地址(就是操作系统的第一句执行的代码)。

在这里插入图片描述


3、机器码的再次确定

(1) uboot 在启动内核时,机器码要传给内核。 uboot 传给内核的机器码是怎么确定的?第一顺序备选是环境变量 machid,第二顺序备选是 gd->bd->bi_arch_num(x210_sd.h 中硬编码配置的)

在这里插入图片描述


4、传参并启动概述

(1) 从 110 行到 144 行,就是 uboot 在给 linux 内核准备传递的参数处理。

在这里插入图片描述


(2) Starting kernel … 这个是 uboot 中最后一句打印出来的东西。这句如果能出现,说明 uboot 整个是成功的,也成功的加载了内核镜像,也校验通过了,也找到入口地址了,也试图去执行了。如果这句后串口就没输出了,说明内核并没有被成功执行。原因一般是:传参(80%)、内核在 DDR 中的加载地址·······

在这里插入图片描述
在这里插入图片描述


七、传参详解

1、tag 方式传参

在这里插入图片描述

(1) struct tag, tag 是一个数据结构,在 uboot 和 linux kernel 中都有定义 tag 数据机构,而且定义是一样的。


(2) tag_header 和 tag_xxx。tag_header 中有这个 tag 的 size 和类型编码,kernel 拿到一个 tag 后,先分析 tag_header 得到 tag 的类型和大小,然后将 tag 中剩余部分当作一个 tag_xxx 来处理

在这里插入图片描述


(3) tag_start 与 tag_end。kernel 接收到的传参是若干个 tag 构成的,这些 tag 由 tag_start 起始,到 tag_end 结束。

在这里插入图片描述


(4) tag 传参的方式是由 linux kernel 发明的,kernel 定义了这种向我传参的方式,uboot 只是实现了这种传参方式,从而可以支持给 kernel 传参。


2、x210_sd.h 中配置传参宏

在这里插入图片描述

(1) CONFIG_SETUP_MEMORY_TAGS,tag_mem,传参内容是内存配置信息。

在这里插入图片描述


(2) CONFIG_CMDLINE_TAG,tag_cmdline,传参内容是启动命令行参数,也就是uboot 环境变量的 bootargs.

在这里插入图片描述


(3) CONFIG_INITRD_TAG

(4) CONFIG_MTDPARTITION,传参内容是 iNand/SD 卡的分区表。

在这里插入图片描述

在这里插入图片描述


(5) 起始 tag 是 ATAG_CORE、结束 tag 是 ATAG_NONE,其他的 ATAG_XXX 都是有效信息 tag。

在这里插入图片描述


思考:内核如何拿到这些 tag
uboot 最终是调用 theKernel 函数来执行 linux 内核的,uboot 调用这个函数(其实就是 linux 内核)时传递了 3 个参数。这 3 个参数就是 uboot 直接传递给 linux 内核的 3 个参数,通过寄存器来实现传参的。(第 1 个参数就放在 r0 中,第二个参数放在 r1 中,第 3 个参数放在 r2 中)第 1 个参数固定为 0,第 2 个参数是机器码,第 3 个参数传递的就是大片传参 tag 的首地址。

在这里插入图片描述


3、移植时注意事项

(1) uboot 移植时,一般只需要配置相应的宏即可。

(2) kernel 启动不成功,注意传参是否成功。传参不成功首先看 uboot 中 bootargs 设置是否正确,其次看 uboot 是否开启了相应宏以支持传参。


八、uboot 启动内核的总结

1、启动 4 步骤

第一步:将内核搬移到 DDR 中;

第二步:校验内核格式、CRC 等;

第三步:准备传参;

第四步:跳转执行内核。


2、涉及到的主要函数是:do_boom 和 do_bootm_linux

3、uboot 能启动的内核格式:zImage、uImage、fdt 方式

4、跳转与函数指针的方式运行内核


源自朱有鹏老师.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_262333.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Hadoop Shell常用命令

Hadoop Shell命令在管理HDFS的时候还是比较常用的&#xff0c;Hadoop Shell命令与shell命令极为相似&#xff0c;但是方便查询&#xff0c;在这里总结分享&#xff0c;大家enjoy~~ 1&#xff0c;cat 语法格式&#xff1a;hadoop fs -cat URI [URI …] 含义&#xff1a;将路径…

【架构师】零基础到精通——架构演进

博客昵称&#xff1a;架构师Cool 最喜欢的座右铭&#xff1a;一以贯之的努力&#xff0c;不得懈怠的人生。 作者简介&#xff1a;一名Coder&#xff0c;软件设计师/鸿蒙高级工程师认证&#xff0c;在备战高级架构师/系统分析师&#xff0c;欢迎关注小弟&#xff01; 博主小留言…

华为OD机试题,用 Java 解【查找接口成功率最优时间段】问题

最近更新的博客 华为OD机试 - 猴子爬山 | 机试题算法思路 【2023】华为OD机试 - 分糖果(Java) | 机试题算法思路 【2023】华为OD机试 - 非严格递增连续数字序列 | 机试题算法思路 【2023】华为OD机试 - 消消乐游戏(Java) | 机试题算法思路 【2023】华为OD机试 - 组成最大数…

【数据库】redis集群环境详解

目录 集群环境 一&#xff0c;集群介绍 1、为什么需要redis集群 2、什么是redis集群 二&#xff0c;数据分片 三&#xff0c; 主从复制模型 四&#xff0c;一致性保证 五&#xff0c;集群搭建 1&#xff0c; 集群结构 2&#xff0c;创建配置文件 &#xff08;1&#…

RebbitMQ 消息队列(简单使用)

消息队列介绍 MQ的优势 1.业务解耦&#xff1a;不同系统消费信息互不关联&#xff0c;灵活增减系统数量&#xff0c;修改某个系统其他系统也不影响 2.异步提速&#xff1a;不同系统之间可同时响应&#xff0c;提升并发量 3.削峰填谷&#xff1a;处理消息高峰期&#xff0c;均摊…

Ubuntu通过kubeadm安装k8s

kubeadm kubeadm是一个构建k8s集群的工具。它提供的kubeadm init和 kubeadm join 两个命令是快速构建k8s集群的最佳实践。 其次&#xff0c;kubeadm工具只为构建最小可用集群&#xff0c;它只关心集群中最基础的组件&#xff0c;至于其他的插件&#xff08;比如dashboard、CNI…

SpringCloud - Gateway网关路由

目录 网关初步介绍 搭建网关服务 路由断言工厂Route Predicate Factory 路由过滤器 GatewayFilter 全局过滤器 GlobalFilter 过滤器执行顺序 网关的cors跨域配置 网关初步介绍 不是所有的请求&#xff0c;都能访问服务&#xff0c;所以需要网关对来访问的请求进行提前判…

java 9 的新特性解读(1)

前言  经过4次跳票&#xff0c;历经曲折的Java 9 终于终于在2017年9月21日发布。  从Java 9 这个版本开始&#xff0c;Java 的计划发布周期是 6 个月&#xff0c;下一个 Java 的主版本将于 2018 年 3 月发布&#xff0c;命名为 Java 18.3&#xff0c;紧接着再过六个月将发布…

CSS 盒子模型【快速掌握知识点】

目录 一、什么是盒子模型 二、边框border-color 三、边框粗细border-width 四、边框样式border-style 五、外边距margin 六、内边距padding 七、圆角边框 八、圆形 九、盒子阴影 一、什么是盒子模型 css盒子模型又称为框模型&#xff0c;盒子的最内部是元素的实际内容…

【Git】与“三年经验”就差个分支操作的距离

前言 Java之父于胜军说过&#xff0c;曾经一位“三年开发经验”的程序员粉丝朋友&#xff0c;刚入职因为不会解决分支问题而被开除&#xff0c;这是不是在警示我们什么呢&#xff1f; 针对一些Git的不常用操作&#xff0c;我们通过例子来演示一遍 1.版本回退 1.1已提交但未p…

notepad++如何快速批量搜索复制,3步搜索+标记所在行+复制书签行

一。缘起 用习惯了 某edit, 突然用notepad很不习惯&#xff0c;至少3处不习惯&#xff1a;列操作&#xff0c;批量复制搜索行&#xff0c;和是txt文件比较。 另外一直坚持认为&#xff0c;不提供快捷键操作的软件不是好软件&#xff1a;&#xff09;当下屏幕对眼睛迫害至深的时…

SGI 空间配置器

前言 空间配置器是 STL 六大组件之一&#xff0c;它总是隐藏在容器的背后&#xff0c;默默工作&#xff0c;默默付出。本文为《STL 源码剖析》读书笔记&#xff0c;主要讨论 SGI 版本空间的配置和释放&#xff0c;对代码进行解读时会改变一些写法&#xff0c;使其更易于阅读。…

企业急需:拥有一个属于自身的知识库!

如今&#xff0c;拥有知识库对任何企业来说都是绝对必要的。特别是在软件即服务方面。如果您真的希望您的 SaaS 业务取得成功&#xff0c;您需要从第一天开始构建知识库。为什么&#xff1f;首先&#xff0c;SaaS 公司有一个货币化模型&#xff0c;专注于他们的每月经常性收入 …

多传感器分布式融合算法——多传感器网络协同目标跟踪和定位

多传感器分布式融合算法 应用&#xff1a; 多传感器网络协同目标跟踪及定位 原创不易&#xff0c;路过的各位大佬请点个赞 主要讲解算法&#xff1a; 多传感器集中式融合算法/分布式融合算法/序贯融合算法 多速率多传感器异步融合算法 多传感器…

PHP程序员适合创业吗?

创业是一件自然而然的事&#xff0c;不需要人为选择。 只要你是一个努力能干主动的人&#xff0c;当你在一个行业深耕5年之后&#xff0c;就会发现人生发展的下一步就是创业。当然如果行业合适的话。 什么叫行业合适呢&#xff1f; 就是创业的成本并不那么高&#xff0c;不需…

js 实现 Logo(图片)根据图片后面的图片颜色而变化成相反的颜色【解决logo固定后 会出现与不同板块的颜色相同导致于看不清logo的情况】

效果展示&#xff1a; <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <meta http-equiv"X-UA-Compatible" content"ieedge"><style type"text/css…

Unreal Engine 虚幻引擎,性能分析,优化(二)

一、CPU 性能分析 如渲染线程中出现 CPU 受限&#xff0c;原因可能是绘制调用过多。这是一个常见问题&#xff0c;美术师通常会将绘制调用进行组合&#xff0c;从而减少消耗&#xff08;如&#xff1a;将多个墙壁组合为一个网格体&#xff09;。实际消耗存在于多个区域中&…

vue3路由守卫

文章目录路由守卫1.全局路由守卫2.组件内守卫3.路由独享守卫提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考路由守卫 全局守卫&#xff08;3个&#xff09; 路由独享守卫&#xff08;1个&#xff09; 组件的守卫&#xff08;3个&#xff09; 路由守卫的…

蓝牙运动耳机哪个好,比较好的运动蓝牙耳机

很多想选择蓝牙运动耳机的朋友都不知道应该如何选择&#xff0c;运动首先需要注意的就是耳机的防水能力以及耳机佩戴舒适度&#xff0c;在运动当中会排出大量的汗水&#xff0c;耳机防水等级做到越高&#xff0c;可以更好地保护耳机不受汗水浸湿&#xff0c;下面就分享五款适合…

《图机器学习》-Graph Neural Network

前言 回顾之前的Node Embedding&#xff1a; 将图中的节点嵌入到d维空间&#xff0c;并确保图中相似的节点能够嵌在一起。 即学习一个编码器ENCENCENC确保图的节点嵌入到embedding space依然能够描述原空间节点之间的相似性。 在Node Embedding中&#xff0c;我们需要设计&…