




已阅读5页,还剩7页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
分析uboot是如何启动内核的(2011-12-27 19:16:30)转载标签:鏉傝皥1.uboot启动内核的代码缩减如下:s = getenv (bootcmd);debug (# main_loop: bootcmd=%sn, s ? s : );if (bootdelay = 0 & s & !abortboot (bootdelay)run_command (s, 0);2.假设bootcmd = nand read.jffs2 0x30007FC0 kernel; bootm 0x30007FC0 nand read.jffs2 0x30007FC0 kernelnand read.jffs2 0x30007FC0 kernel;从nand读出内核:从哪里读?从kernel分区放到哪里去?-0x30007FC0下面讲解什么是分区:就是将nand划分为几个区域,一般如下:bootloader-params-kernel-root这些分区的划分是在/include/configs/mini2440.h中写死的:#define MTDPARTS_DEFAULT mtdparts=nandflash0:250k0(bootloader), 128k(params), 5m(kernel), -(root)注:0表示从0地址开始,250k的bootloader分区可能对某些uboot不够用,这里只是举例而已。将上面的信息换算成十六进制:#name大小在nand上的起始地址0bootloader0x000400000x000000001params0x000200000x000400002kernel0x002000000x000600003root0xfda000000x00260000那么上面的nand read.jffs2 0x30007FC0 kernel就等价于:nand read.jffs2 0x30007FC0 0x00060000 0x00200000注:这里的read.jffs2并不是指定要什么特定的格式,而是用read.jffs2不需要块/页对齐,所以这个kernel的分区大小可以随意定。 bootm 0x30007FC0关键函数do_bootm()flash上存的内核:uImageuImage = 头部+真正的内核头部的定义如下:typedef struct image_header uint32_tih_magic;uint32_tih_hcrc;uint32_tih_time;uint32_tih_size;uint32_tih_load;uint32_tih_ep;uint32_tih_dcrc;uint8_tih_os;uint8_tih_arch;uint8_tih_type;uint8_tih_comp;uint8_tih_nameIH_NMLEN; image_header_t;我们需要关心的是:uint32_tih_load;uint32_tih_ep;ih_load是加载地址,即内核运行是应该位于的地方ih_ep是入口地址,即内核的入口地址这与uboot是类似的,uboot的加载地址是TEXT_BASE = 0x33F80000;入口地址是start.S中的_start。其实我们把内核中nand读出来的时候是可以放在内核的任何地方的,如0x31000000,0x32000000等等,只要它不破坏uboot所占用的内存空间就可以了,如下图:从0x33F4DF74-0x30000000都是可以用的。那么为什么既然设定好了加载地址和入口地址内核还能随意放呢?那是因为uImage有一个头部!头部里有加载地址和入口地址,当我们用bootm xxx的时候,do_bootm这个函数会先去读uImage的头部以获取该uImage的加载地址和入口地址,当发现该uImage目前所处的内存地址不等于它的加载地址时,该函数会将该uImage移动到它的加载地址上,在代码中体现如下:case IH_COMP_NONE::if (load != image_start)memmove_wd (void *)load, (void *)image_start, image_len, CHUNKSZ);另外,当我们的内核正好处于头部指定的加载地址的话,那么就不用uboot的do_bootm函数来帮我们搬运内核了,这样可以节省启动时间。这就是为什么我们一般都下载uImage到0x30007FC0的原因了!我们所用的内核加载地址是0x30008000,而头部的大小为64个字节,所以将内核拷贝到0x30007FC0时,再加载头部的64个字节,内核正好位于0x30008000处!现在总结bootm做了什么:1.读取头部2.将内核移动到加载地址3.启动内核具体如何启动内核?使用do_bootm_linux(),在/lib_arm/bootm.c定义,因为我们已经知道入口地址了,所以只需跳到入口地址就可以启动linux内核了,但是在这之前需要做一件事uboot传递参数给内核!现在来分析do_bootm_linux()这个函数:theKernel = (void (*)(int, int, uint)images-ep;/先是将入口地址赋值给theKerneltheKernel (0, machid, bd-bi_boot_params);/然后是调用thekernel函数,以0,machid,bd-bi_boot_params作为参数下面分析这三个参数:1.machid就是uboot里设置好的板子的机器码,mini2440的是MACH_TYPE_MINI2440 (1999),内核所设置的机器码和uboot所设置的机器码必须一致才能启动内核2.bd-bi_boot_parmas就是uboot需传递给内核的启动参数所位于的地址3.0暂时还不知道什么作用那么uboot传给内核的启动参数是在哪里设置的呢?其实就是在调用theKernel (0, machid, bd-bi_boot_params);前面的一小段代码里设置的,下面我截取了部分片段:setup_start_tag (bd);setup_revision_tag (¶ms);setup_memory_tags (bd);setup_commandline_tag (bd, commandline);setup_initrd_tag (bd, images-rd_start, images-rd_end);setup_videolfb_tag (gd_t *) gd);setup_end_tag (bd);每一个启动参数对应一个tag结构体,所谓的设置传递参数其实就是初始化这些tag的值,想了解这个结构体以及这些tag的值是如何设置的请看韦东山的书关于uboot移植章节!下面我们看一下setup_start_tag(bd)这个函数先:static void setup_start_tag (bd_t *bd)params = (struct tag *) bd-bi_boot_params;/在board.c中有一句gd-bd-bi_boot_params = 0x30000100,这里设置了参数存放的位置params-hdr.tag = ATAG_CORE;params-hdr.size = tag_size (tag_core);params-u.core.flags = 0;params-u.core.pagesize = 0;params-u.core.rootdev = 0;params = tag_next (params);我们再来看下setup_commandline_tag (bd, commandline);这个函数:static void setup_commandline_tag (bd_t *bd, char *commandline)/ commandline就是我们的bootargschar *p;if (!commandline)return;for (p = commandline; *p = ; p+);if (*p = 0)return;params-hdr.tag = ATAG_CMDLINE;params-hdr.size =(sizeof (struct tag_header) + strlen (p) + 1 + 4) 2;strcpy (params-u.cmdline.cmdline, p);params = tag_next (params);Linux内核启动时就会去读取这些tag参数U-BOOT下使用bootm引导内核方法注: u-boot使用的是打上:/cgi-bin/topic.cgi?forum=3&topic=651&show=0上keety大侠提供的补丁生成的u-boot-1.1.3这段时间不断有人问我u-boot启动内核的问题,记得在上次提供的u-boot源码中提到了go的方案,不过其实u-boot本来有一种更好的方案:bootm花了不少时间,查看了论坛上不少的帖子,认真阅读了bootm的源码,终于使用bootm把内核给跑起来了,现把解决方法介绍如下:一、在开始之前先说明一下bootm相关的东西。1、首先说明一下,S3C2410架构下的bootm只对sdram中的内核镜像文件进行操作(好像AT91架构提供了一段从flash复制内核镜像的代码,不过针对s3c2410架构就没有这段代码,虽然可以在u-boot下添加这段代码,不过好像这个用处不大),所以请确保你的内核镜像下载到sdram中,或者在bootcmd下把flash中的内核镜像复制到sdram中。2、-a参数后是内核的运行地址,-e参数后是入口地址。3、1)如果我们没用mkimage对内核进行处理的话,那直接把内核下载到0x30008000再运行就行,内核会自解压运行(不过内核运行需要一个tag来传递参数,而这个tag建议是由bootloader提供的,在u-boot下默认是由bootm命令建立的)。2)如果使用mkimage生成内核镜像文件的话,会在内核的前头加上了64byte的信息,供建立tag之用。bootm命令会首先判断bootm xxxx 这个指定的地址xxxx是否与-a指定的加载地址相同。(1)如果不同的话会从这个地址开始提取出这个64byte的头部,对其进行分析,然后把去掉头部的内核复制到-a指定的load地址中去运行之(2)如果相同的话那就让其原封不同的放在那,但-e指定的入口地址会推后64byte,以跳过这64byte的头部。二、好,接着介绍使用mkimage生成镜像文件并下载运行的方法。方法一、1、首先,用u-boot/tools/mkimage这个工具为你的内核加上u-boot引导所需要的文件头,具体做法如下:rootlocalhost tftpboot#mkimage -n linux-2.6.14 -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008000 -d zImage zImage.imgImage Name: linux-2.6.14Created: Fri Jan 12 17:14:50 2007Image Type: ARM Linux Kernel Image (uncompressed)Data Size: 1262504 Bytes = 1232.91 kB = 1.20 MBLoad Address: 0x30008000Entry Point: 0x30008000这里解释一下参数的意义: -A = set architecture to arch -O = set operating system to os -T = set image type to type -C = set compression type comp -a = set load address to addr (hex) -e = set entry point to ep (hex) -n = set image name to name -d = use image data from datafile -x = set XIP (execute in place)2、下载内核U-Boot1.1.3(Jan 12 2007 - 16:16:36)U-Boot code: 33F80000 - 33F9BAC0 BSS: - 33F9FBACRAM Configuration:Bank #0: 30000000 64 MBNor Flash: 512 kBNand Flash: 64 MBIn: serialOut: serialErr: serialHit any key to stop autoboot: 0sbc2410=tftp 0x31000000 zImage.img TFTP from server 15; our IP address is 28Filename zImage.img.Load address: 0x31000000Loading: # # # #doneBytes transferred = 1263324 (1346dc hex)3.运行sbc2410=bootm 0x31000000# Booting image at 31000000 . Image Name: linun-2.6.14 Image Type: ARM Linux Kernel Image (uncompressed) Data Size: 1263260 Bytes = 1.2 MB Load Address: 30008000 Entry Point: 30008000 Verifying Checksum . OKOKStarting kernel .Uncompressing Linux.Linux version 2.6.14 (rootluofuchong) (gcc version 3.4.1) #21 Fri Oct 20 17:206CPU: ARM920Tid(wb) 41129200 revision 0 (ARMv4T)Machine: SMDK2410Memory policy: ECC disabled, Data cache writebackCPU S3C2410A (id 0x32410002)S3C2410: core 202.800 MHz, memory 101.400 MHz, peripheral 50.700 MHzS3C2410 Clocks, (c) 2004 Simtec ElectronicsCLOCK: Slow mode (1.500 MHz), fast, MPLL on, UPLL onUSB Control, (c) 2006 sbc2410CPU0: D VIVT write-back cacheCPU0: I cache: 16384 bytes, associativity 64, 32 byte lines, 8 setsCPU0: D cache: 16384 bytes, associativity 64, 32 byte lines, 8 setsBuilt 1 zonelistsKernel command line: console=ttySAC0 root=/dev/nfs nfsroot=15:/frienirq: clearing subpending status 00000002PID hash table entries: 512 (order: 9, 8192 bytes)timer tcon=00500000, tcnt a509, tcfg 00000200,00000000, usec 00001e4cConsole: colour dummy device 80x30Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)Memory: 64MB = 64MB totalMemory: 62208KB available (1924K code, 529K data, 108K init)Mount-cache hash table entries: 512CPU: Testing write buffer coherency: oksoftlockup thread 0 started up.NET: Registered protocol family 16S3C2410: Initialising architectureSCSI subsystem initializedusbcore: registered new driver usbfsusbcore: registered new driver hubS3C2410 DMA Driver, (c) 2003-2004 Simtec ElectronicsDMA channel 0 at c4800000, irq 33DMA channel 1 at c4800040, irq 34DMA channel 2 at c4800080, irq 35DMA channel 3 at c48000c0, irq 36NetWinder Floating Point Emulator V0.97 (double precision)devfs: 2004-01-31 Richard Gooch (rgoochatnf.csiro.au)devfs: devfs_debug: 0x0devfs: boot_options: 0x1yaffs Oct 18 2006 12:39:51 Installing.Console: switching to colour frame buffer device 30x40fb0: s3c2410fb frame buffer devicefb1: Virtual frame buffer device, using 1024K of video memoryled driver initializeds3c2410 buttons successfully loadeds3c2410_serial0 at MMIO 0x50000000 (irq = 70) is a S3C2410s3c2410_serial1 at MMIO 0x50004000 (irq = 73) is a S3C2410s3c2410_serial2 at MMIO 0x50008000 (irq = 76) is a S3C2410io scheduler noop registeredio scheduler anticipatory registeredio scheduler deadline registeredio scheduler cfq registeredRAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksizeusbcore: registered new driver ubCirrus Logic CS8900A driver for Linux (Modified for SMDK2410)eth0: CS8900A rev E at 0xe0000300 irq=53, no eeprom , addr: 08: 0:3E:26:0A:5BS3C24XX NAND Driver, (c) 2004 Simtec Electronicss3c2410-nand: mapped registers at c4980000s3c2410-nand: timing: Tacls 10ns, Twrph0 30ns, Twrph1 10nsNAND device: Manufacturer ID: 0xec, Chip ID: 0x76 (Samsung NAND 64MiB 3,3V 8-bi)Scanning device for bad blocksBad eraseblock 1884 at 0x01d70000Creating 4 MTD partitions on NAND 64MiB 3,3V 8-bit:0x00000000-0x00020000 : vivi0x00020000-0x00030000 : param0x00030000-0x00200000 : kernel0x00200000-0x04000000 : rootusbmon: debugfs is not availables3c2410-ohci s3c2410-ohci: S3C24XX OHCIs3c2410-ohci s3c2410-ohci: new USB bus registered, assigned bus number 1s3c2410-ohci s3c2410-ohci: irq 42, io mem 0x49000000hub 1-0:1.0: USB hub foundhub 1-0:1.0: 2 ports detectedInitializing USB Mass Storage driver.usbcore: registered new driver usb-storageUSB Mass Storage support registered.usbcore: registered new driver usbmousedrivers/usb/input/usbmouse.c: v1.6:USB HID Boot Protocol mouse drivermice: PS/2 mouse device common for all mices3c2410 TouchScreen successfully loadedUDA1341 audio driver initializedNET: Registered protocol family 2IP route cache hash table entries: 1024 (order: 0, 4096 bytes)TCP established hash table entries: 4096 (order: 2, 16384 bytes)TCP bind hash table entries: 4096 (order: 2, 16384 bytes)TCP: Hash tables configured (established 4096 bind 4096)TCP reno registeredTCP bic registeredNET: Registered protocol family 1IP-Config: Complete: device=eth0, addr=28, mask=, gw=, host=luofuchong, domain=, nis-domain=(none), bootserver=, rootserver=15, rootpath=Looking up port of RPC 100003/2 on 15Looking up port of RPC 100005/1 on 15VFS: Mounted root (nfs filesystem).Mounted devfs on /devFreeing init memory: 108Kinit started: BusyBox v1.1.3 (2006.09.20-14:52+0000) multi-call binaryStarting pid 696, console /dev/tts/0: /etc/init.d/rcSPlease press Enter to activate this console.方法二、1、首先,用u-boot/tools/mkimage这个工具为你的内核加上u-boot引导所需要的文件头,具体做法如下:rootlocalhost tftpboot#mkimage -n linux-2.6.14 -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008040 -d zImage zImage.imgImage Name: linux-2.6.14Created: Fri Jan 12 17:14:50 2007Image Type: ARM Linux Kernel Image (uncompressed)Data Size: 1262504 Bytes = 1232.91 kB = 1.20 MBLoad Address: 0x30008000Entry Point: 0x300080402、下载内核U-Boot1.1.3(Jan 12 2007 - 16:16:36)U-Boot code: 33F80000 - 33F9BAC0 BSS: - 33F9FBACRAM Configuration:Bank #0: 30000000 64 MBNor Flash: 512 kBNand Flash: 64 MBIn: serialOut: serialErr: serialHit any key to stop autoboot: 0sbc2410=tftp 0x30008000 zImage.img TFTP from server 15; our IP address
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 平常养护工程施工技术规范
- AutoCAD工程制图实教程 (2024版)课件 模块三 绘制多面图形
- 幽门螺旋杆菌诊疗课件
- 巡视巡察课件教学
- 巡察工作法课件
- 岩石风化的公开课课件
- 岩土特性课件
- 尧帝凿井课件
- 输液泵的使用和管理课件
- LED照明灯具研发生产与销售合同范本
- GB/T 6093-2001几何量技术规范(GPS)长度标准量块
- GB/T 22751-2008台球桌
- 中国近代史试题库
- 电路学课件:1-6 电压源和电流源
- 奥的斯GeN2-故障查找手册-1-CN
- 村民森林防火承诺书
- 税法(第三版)项目一任务三增值税应纳税额的计算
- 系统数据导出确认单
- Q∕SY 01004-2016 气田水回注技术规范
- TSG Z8002-2022 特种设备检验人员考核规则
- QC∕T 900-1997 汽车整车产品质量检验评定方法
评论
0/150
提交评论