接觸嵌入式開發(fā)也有兩年多了,每天看著同樣的啟動信息似乎都有些麻木了,但上次尋找網(wǎng)絡(luò)驅(qū)動時(shí)pan總就是從啟動信息中追溯到了驅(qū)動源文件,于是想了解一下這些啟動信息,對之前感覺熟悉但又不知甚解的東西做一個(gè)簡單的跟蹤,對以后的工作學(xué)習(xí)應(yīng)該也有幫助。
Flash映射起始地址 進(jìn)入0xf00000 uboot image
(該地址應(yīng)該是由0x0000處的硬件配置字決定的)
Uboot是上電后執(zhí)行的第一段程序,主要用于初始化處理器及外設(shè),啟動內(nèi)核。
U-Boot 1.3.0-rc2 (Oct 19 2007 - 16:58:40)
U-Boot版本信息
U-Boot
image的入口點(diǎn)是start.S匯編代碼,設(shè)置一些寄存器,時(shí)鐘等操作都是在匯編中完成,然后進(jìn)入board_init_f順序執(zhí)行下面的系列初始化函數(shù),board_init_f位于u-boot-1.3.0-
rc3/lib_ppc/board.c中,是uboot所有C代碼的第一處入口點(diǎn),注意到這時(shí)候uboot是運(yùn)行在rom中,只能使用很小的堆棧,并且無法修改全局變量。
MPC8272 Reset Status:
External Soft, External Hard
代碼在
u-boot-1.3.0-rc3/cpu/mpc8260/cpu_init.c函數(shù)prt_8260_rsr()中
MPC8272 Clock
Configuration
- Bus-to-Core Mult 4x, VCO Div 2, 60x Bus Freq 25-75 , Core Freq
100-300
- dfbrg 1, corecnf 0x1a, busdf 3, cpmdf 1, plldf 0, pllmf 3, pcidf
5
- vco_out 400000000, scc_clk 100000000, brg_clk 25000000
- cpu_clk 400000000, cpm_clk 200000000, bus_clk 100000000
- pci_clk 33333333
打印出了主板,cpu的一些指標(biāo)信息,代碼在u-boot-1.3.0-rc3/cpu/mpc8260/speed.c函數(shù)prt_8260_clks()中
board_init_f完成一部分初始化工作后又跳轉(zhuǎn)到匯編中,初始化堆棧,控制器等,再次進(jìn)入C代碼段是在board.c的board_init_r中,這時(shí)候已經(jīng)是加載在內(nèi)存中執(zhí)行,可以正常得使用堆棧了。
CPU: MPC8272 (HiP7 Rev 14,
Mask 1.0 1K50M) at 400 MHz
Board: MSC7119RDK
I2C: ready
DRAM: 128 MB
FLASH: 16 MB
In: serial
Out: serial
Err: serial
Net: FCC1 ETHERNET, FCC2 ETHERNET
以上信息是由board_init_r函數(shù)檢測,初始化,并打印,初始化看門狗之后進(jìn)入common\main.c的main_loop函數(shù)中。
Hit any key to stop autoboot:
0
main_loop會延時(shí)一小段時(shí)間,按鍵進(jìn)入u-boot設(shè)置,沒有按鍵則進(jìn)入正常啟動流程,延時(shí)時(shí)間可以在此處修改。
Uboot設(shè)置中有兩項(xiàng)主要配置,引導(dǎo)著接下來的啟動過程。
1. bootcmd=bootm FF020000
無按鍵時(shí)就是執(zhí)行該命令,uboot之前將flash的kernel映射在FF020000內(nèi)存地址上,bootm也指向FF020000就能順利啟動linux內(nèi)核。
2. bootargs=root=/dev/mtdblock3 rootfstype=jffs2 noinitrd
init=/etc/preinit console=ttyCPM0,115200n8
Linux內(nèi)核啟動參數(shù),指定了根文件系統(tǒng)塊(mtdblock3),文件系統(tǒng)類型(jffs2),內(nèi)核執(zhí)行的初始化進(jìn)程名(preinit),串口參數(shù)。(之前有一次串口出問題,就是因?yàn)閏onsolo的值配錯(cuò)了),Linux內(nèi)核啟動參數(shù)也有其他挺好玩的應(yīng)用,都可以在此修改,比如設(shè)置panic=N,可以讓內(nèi)核在崩潰N秒后才重啟。
## Booting image at ff020000
...
Image Name: Linux-2.6.14
Image Type: PowerPC Linux Kernel Image (gzip compressed)
Data Size: 1170641 Bytes = 1.1 MB
Load Address: 00000000
Entry Point: 00000000
Verifying Checksum ... OK
Uncompressing Kernel Image ... OK
以上信息是bootm的執(zhí)行函數(shù)do_bootm打印的(common\cmd_bootm.c),實(shí)際上就是二進(jìn)制內(nèi)核文件的開頭幾個(gè)字節(jié),而且注意到我們的內(nèi)核是壓縮內(nèi)核,需要一次解壓過程,解壓后執(zhí)行do_bootm_linux函數(shù)啟動Linux內(nèi)核。
-----------------------------------------Linux內(nèi)核啟動分割線---------------------------------
Linux內(nèi)核的入口在init/main.c的start_kernel()函數(shù)中,初始化調(diào)度,中斷,定時(shí)器等系列初始化操作都在該函數(shù)中。它主要完成剩余的與硬件平臺相關(guān)的初始化工作,在進(jìn)行一系列與內(nèi)核相關(guān)的初始化后,調(diào)用第一個(gè)用戶進(jìn)程-init
進(jìn)程并等待用戶進(jìn)程的執(zhí)行,這樣整個(gè) Linux 內(nèi)核便啟動完畢。
Linux version 2.6.14
(huangzc@compiling-server) (gcc version 4.1.2) #3 PREEMPT Mon Dec7
13:58:26 CST 2009 以上信息保存在linux_banner常量中(init/version.c)
Freescale StarCore PowerPC
port
setup_arch()函數(shù)打印(arch/ppc/kernel/setup.c),ppc_md.setup_arch()回調(diào)原型在arch/ppc/syslib/m8260_setup.c的m8260_setup_arch(void)函數(shù)中,上述常量信息在arch/ppc/platforms/Msc7119rdk.h中,該文件是設(shè)備相關(guān)的,平臺移植時(shí)的一大工作量應(yīng)該就是修改這類文件。
setup_arch()函數(shù)是與體系結(jié)構(gòu)相關(guān)的第一個(gè)初始化工作,對不同的體系結(jié)構(gòu)來說該函數(shù)有不同的定義。它首先通過檢測出來的處理器類型進(jìn)行處理器內(nèi)核的初始化,然后通過
bootmem_init()函數(shù)根據(jù)系統(tǒng)定義的 meminfo 結(jié)構(gòu)進(jìn)行內(nèi)存結(jié)構(gòu)的初始化,最后調(diào)用paging_init()開啟
MMU,創(chuàng)建內(nèi)核頁表,映射所有的物理內(nèi)存和
IO空間。
Staring set led to default
state
led初始化,set_default_led()函數(shù)中(arch/ppc/kernel/setup.c)
arch/ppc/syslib/m82xx_pci.c:
The PCI bus is 33333333 Mhz.
Waiting 1 second after deasserting RST...
pq2_find_bridges()函數(shù)調(diào)用pq2ads_setup_pci()完成pci初始化(arch/ppc/syslib/m82xx_pci.c)。
Built 1 zonelists
build_all_zonelists函數(shù)打印(mm/page_alloc.c)
Kernel command line:
root=/dev/mtdblock3 rootfstype=jffs2 noinitrd init=/etc/preinit
console=ttyCPM0,115200n8
start_kernel()重新打印出了Linux內(nèi)核啟動參數(shù),內(nèi)核啟動異常時(shí)可以先核對該參數(shù)是否正確。
PID hash table entries: 1024
(order: 10, 16384 bytes)
pidhash_init()函數(shù)打印(kernel/pid.c),由函數(shù)也可以看出,進(jìn)程id的分配查找用的是哈希算法
Warning: real time clock
seems stuck!
time_init()函數(shù)打印(kernel/time.c),初始化系統(tǒng)時(shí)鐘。
Console: colour dummy device
80x25
console_init打印(drivers/char/tty_io.c),也是調(diào)用了系列回調(diào)。
Dentry cache hash table
entries: 32768 (order: 5, 131072 bytes)
Inode-cache hash table entries: 16384 (order: 4, 65536
bytes)
alloc_large_system_hash()函數(shù)打印(mm/page_alloc.c),分別在fs/dcache.c和fs/inode.c中調(diào)用。
Memory: 127232k available
(1900k kernel code, 584k data, 96k init, 0k highmem)
mem_init()函數(shù)打印(mm/init.c)
Mount-cache hash table
entries: 512
mnt_init()函數(shù)打印(fs/namespace.c)
NET: Registered protocol
family 16
net/netlink/af_netlink.c模塊初始化,調(diào)用sock_register注冊函數(shù)注冊netlink系列回調(diào)
PCI: Probing PCI
hardware
arch/ppc/kernel/pci.c模塊初始化,調(diào)用pcibios_init()函數(shù)打印
PCI: Cannot allocate resource
region 0 of device 0000:00:00.0
PCI: Cannot allocate resource region 1 of device
0000:00:00.0
在pcibios_init()函數(shù)中pcibios_allocate_resources打印。因?yàn)槲覀儼鍥]有提供PCI支持,所以alloc失???
Generic PHY: Registered new
driver PHY模塊初始化,注冊了Generic
PHY這個(gè)通用PHY設(shè)備(drivers/net/phy/phy_device.c)
SCSI subsystem
initialized SCSI模塊初始化,注冊了scsi的系列函數(shù)方法(drivers/scsi/scsi.c)
JFFS2 version 2.2. (NAND) (C)
2001-2003 Red Hat, Inc.
jffs2文件系統(tǒng)初始化,通過register_filesystem等函數(shù)注冊文件系統(tǒng)(fs/jffs2/super.c)
yaffs Dec 7 2009 13:57:00
Installing.
yaffs(yaffs2)文件系統(tǒng)初始化,打印的時(shí)間即為編譯時(shí)間(fs/yaffs2/yaffs_fs.c)
Initializing Cryptographic
API
crypto模塊初始化,完成crypto的系列內(nèi)核函數(shù)(crypto/api.c)
Generic RTC Driver
v1.07
rtc模塊初始化,注冊基于misc的字符設(shè)備(drivers/char/genrtc.c)
Serial: CPM driver $Revision:
1.1.1.1 $ ttyCPM0 at MMIO
0xf0011a80 (irq = 4) is a CPM UART
serial模塊初始化,通過tty_register_driver注冊(driver/serial/cpm_uart/cpu_uart_core.c),并通過uart_configure_port()完成配置。
io scheduler noop
registered
io調(diào)度模塊初始化,通過elv_register函數(shù)注冊(drivers/block/noop-iosched.c)
Uniform Multi-Platform E-IDE
driver Revision: 7.00alpha2
ide: Assuming 33MHz system bus speed for PIO modes; override with
idebus=xx
IDE phys mem : fe000000...fe000200 (size 00000200)
ide模塊初始化(drivers/ide/ide.c),先通過ide_system_bus_speed獲取總線速率,然后調(diào)用init_ide_data初始化ide相關(guān)數(shù)據(jù)
hda: SanDisk SDCFJ-1024, CFA
DISK drive
ide0 at 0xfe001000-0xfe001007,0xfe00200c on irq 52
ideprobe模塊初始化(drivers/ide/ide-probe.c),do_identify()函數(shù)打印hda相關(guān)信息,init_irq()注冊相關(guān)中斷
hda: max request size:
128KiB
hda: 2001888 sectors (1024 MB) w/1KiB Cache, CHS=1986/16/63
hda: cache flushes not supported
hda: hda1
idedisk模塊初始化(drivers/ide/ide-disk.c),調(diào)用idedisk_setup()檢測相關(guān)數(shù)據(jù)
SVX8016 flash device: 1000000
at ff000000
drivers/mtd/maps/msc7119rdk.c模塊初始化,flash大小等信息都定義在msc7119rdk.h中
SVX8016: Found 1 x16 devices
at 0x0 in 16-bit bank
drivers/mtd/chips/cfi_probe.c函數(shù)cfi_probe_chip()打印
Amd/Fujitsu Extended Query
Table at 0x0040
driver/mtd/chips/cfi_util.c函數(shù)cfi_read_pri()打印
SVX8016: CFI does not contain
boot bank location. Assuming top.
number of CFI chips: 1
cfi_cmdset_0002: Disabling erase-suspend-program due to code
brokenness.
drivers/mtd/chips/cfi_cmdset_0002.c函數(shù)cfi_cmdset_0002()和cfi_amdstd_setup()打印。
Creating 7 MTD partitions on
"SVX8016":
0x00f00000-0x00f40000 : "uboot image"
0x00f40000-0x00f80000 : "uboot env"
0x00020000-0x00160000 : "kernel"
0x00160000-0x00f00000 : "file system"
0x00020000-0x00f00000 : "kernel+fs"
0x00f80000-0x01000000 : "config"
0x00000000-0x01000000 : "binary"
msc7119rdk模塊調(diào)用函數(shù)add_mtd_partitions()完成mtd分區(qū)(drivers/mtd/mtdpart.c),從這里就可以看出8032
flash上的分區(qū)分布。整理如下圖:

|