Ⅰ linux的uboot啟動映像,zImage和uImage的區別
zImage是ARM Linux常用的一種壓縮映像文件,uImage是U-boot專用的映像文件,它是在zImage之前加上一個長度為0x40的「頭」,說明這個映像文件的類型、載入位置、生成時間、大小等信息。換句話說,如果直接從uImage的0x40位置開始執行,zImage和uImage沒有任何區別。另外,Linux2.4內核不支持uImage,Linux2.6內核加入了很多對嵌入式系統的支持,但是uImage的生成也需要設置。
vmlinux 編譯出來的最原始的內核文件,未壓縮。zImage是vmlinux經過gzip壓縮後的文件。bzImage bz表示「big zImage」,不是用bzip2壓縮的。兩者的不同之處在於,zImage解壓縮內核到低端內存(第一個640K),bzImage解壓縮內核到高端內存(1M以上)。如果內核比較小,那麼採用zImage或bzImage都行,如果比較大應該用bzImage。
uImage是U-boot專用的映像文件,它是在zImage之前加上一個長度為0x40的tag。vmlinuz是bzImage/zImage文件的拷貝或指向bzImage/zImage的鏈接。initrd是「initialramdisk」的簡寫。一般被用來臨時的引導硬體到實際內核vmlinuz能夠接管並繼續引導的狀態。vmlinux是內核文件,zImage是一般情況下默認的壓縮內核映像文件,壓縮vmlinux,加上一段解壓啟動代碼得到,只能從0X0地址運行。
uImage是u-boot使用bootm命令引導的Linux壓縮內核映像文件格式,使用工具mkimage對普通的壓縮內核映像文件(zImage)加工而得。可以由bootm命令從任意地址解壓啟動內核。由於bootloader一般要佔用0X0地址,所以,uImage相比zImage的好處就是可以和bootloader共存。
Ⅱ irix系統怎麼清除 root密碼
bootm命令是用來引導經過u-boot的工具mkimage打包後的kernel image的,什麼叫做經過u-boot的工具mkimage打包後的kernel image,這個就要看mkimage的代碼,看看它做了些什麼,雖然我很希望大家不要偷懶,認真地去看看,但是我知道還是有很多人懶得去做這件,那麼我就j將分析mkimage代碼後得到的總結告訴大家,mkimage做了些什麼,怎麼用這個工具。 mkimage的用法 uboot源代碼的tools/目錄下有mkimage工具,這個工具可以用來製作不壓縮或者壓縮的多種可啟動映象文件。 mkimage在製作映象文件的時候,是在原來的可執行映象文件的前面加上一個0x40位元組的頭,記錄參數所指定的信息,這樣uboot才能識別這個映象是針對哪個CPU體系結構的,哪個OS的,哪種類型,載入內存中的哪個位置, 入口點在內存的那個位置以及映象名是什麼 root@Glym:/tftpboot# ./mkimage Usage: ./mkimage -l image -l ==> list image header information ./mkimage -A arch -O os -T type -C comp -a addr -e ep -n name -d data_file[:data_file...] image -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) 參數說明: -A 指定CPU的體系結構: 取值 表示的體系結構 alpha Alpha arm ARM x86 Intel x86 ia64 IA64 mips MIPS mips64 MIPS 64 Bit ppc PowerPC s390 IBM S390 sh SuperH sparc SPARC sparc64 SPARC 64 Bit m68k MC68000 -O 指定操作系統類型,可以取以下值: openbsd、netbsd、freebsd、4_4bsd、linux、svr4、esix、solaris、irix、sco、dell、ncr、lynxos、vxworks、psos、qnx、u-boot、rtems、artos -T 指定映象類型,可以取以下值: standalone、kernel、ramdisk、multi、firmware、script、filesystem -C 指定映象壓縮方式,可以取以下值: none 不壓縮 gzip 用gzip的壓縮方式 bzip2 用bzip2的壓縮方式 -a 指定映象在內存中的載入地址,映象下載到內存中時,要按照用mkimage製作映象時,這個參數所指定的地址值來下載 -e 指定映象運行的入口點地址,這個地址就是-a參數指定的值加上0x40(因為前面有個mkimage添加的0x40個位元組的頭) -n 指定映象名 -d 指定製作映象的源文件 mkimage 解壓內核源碼包,編輯Makefile 設置 cross_compile:=[編譯器的絕對路徑] ;這個絕對路徑既上面2.95.3放到的路徑 進入內核文件夾,執行下面命令 [root@hostname]# make clean [root@hostname]# make dep [root@hostname]# make [root@hostname]# [編譯器的絕對路徑]/bin/arm-linux-obj -O binary -S vmlinux linux.bin ;編譯器的絕對路徑也是上面說到的路徑 [root@hostname]# gzip linux.bin 下面的比較重要了,主要是u-boot的安裝,這個在H9200的手冊上說的很不清楚 [root@hostname]# tar xzvf u-boot-1.0.0.tar.gz ;解壓u-boot [root@hostname]# cd u-boot-1.0.0 [root@hostname]# make distclean [root@hostname]# make at91rm9200dk_config [root@hostname]# make all 然後在/usr/local下建立uboot文件夾將u-boot-1.0.0下的所有文件都復制到uboot下 [root@hostname]# [uboot的絕對路徑]/tools/mkimage -A arm -O linux -C gzip -a 0x20008000 -e 0x20008000 -d linux.bin.gz uImage ;這里的絕對路徑是/usr/local/uboot vmlinux linux.bin linux.bin.gz uImage(uboot製作的image) mkimage -a -e -a參數後是內核的運行地址,-e參數後是入口地址。 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的頭部。 QUESTIONS 1. I have built a vmlinux image but I can boot it. 2: The mkimage tool, ARMboot's tftp command, and the bootm command require certain load and entry addresses. I'm confused which ones to chose. ANSWERS 1. I have built a vmlinux image but I can boot it. -------------------------------------------------- ARMboot is designed to boot Images as created by the mkimage tool, that comes with ARMboot and is automatically built, too. You cannot directly load the vmlinux image, as it expects a number of prerequisits such as special register contents etc. 2. The mkimage tool, ARMboot's tftp command, and the bootm command require certain load and entry addresses. I'm confused which ones to chose. -------------------------------------------------------------------------- Well, there are 3 different addresses: 1. Kernel Load Address. This is the address, where the kernel was linked to when you built the vmlinux and can be found in arch/arm/Makefile. The default for it is: ifeq ($(CONFIG_CPU_32),y) PROCESSOR = armv TEXTADDR = 0xC0008000 LDSCRIPT = arch/arm/vmlinux-armv.lds.in endif Provide this as "-a" parameter to mkimage. 2. Kernel Entry Point. This is the address, where ARMboot jumps to to enter the Kernel. It usually is the same as the kernel load address. Provide this as "-e" parameter to mkimage. 3. The Network Download Address. This is where you download the mkimage File. This address MUST BE different to the Kernel Load Address, and should be sufficiently far away to allow ARMboot to relocate the image to the final Kernel Load Address. Loading to the 5th MB within the RAM is usually a good idea, eg. if the RAM begins at 0xc0000000, you can do this: LART # tftp c0400000 linux.img ARP broadcast 1 eth addr: 00:02:03:04:05:06 TFTP from server 192.168.1.1; our IP address is 192.168.1.2 Filename 'image.img'. Load address: 0xc0400000 Loading: ##################################################################done Bytes transferred = 567252 (8a7d4 hex) LART # bootm c0400000 Image Name: Linux 2.4.18 Created: Mon Jun 24 12:00:01 2002 Image Type: ARM Linux Kernel Image (gzip compressed) Data Size: 567188 Bytes = 553 kB = 0 MB Load Address: 0xc0008000 Entry Point: 0xc0008000 Verifying Checksum ... OK Loading Kernel Image ... OK Starting kernel ... Linux version 2.4.18 (mag@mag) (gcc version 2.95.3 20010315 (release)) #4 Mon Jun 17 20:35:32 CST 2002
Ⅲ uboot 命令如何引導linux
U-Boot 除了 Bootloader 的系統引導功能,它還有用戶命令介面,具備多種引導內核啟動的方式。常用的 go 和 bootm 命令可以直接引導 Linux 內核映像啟動。
U-Boot,全稱 Universal Boot Loader,是遵循GPL條款的開放源碼項目。從FADSROM、8xxROM、PPCBOOT逐步發展演化而來。其源碼目錄、編譯形式與Linux內核很相似,事實上,不少U-Boot源碼就是根據相應的Linux內核源程序進行簡化而形成的,尤其是一些設備的驅動程序,這從U-Boot源碼的注釋中能體現這一點。
Ⅳ 如何實現uboot和linux之間的參數傳遞
U-boot會給Linux Kernel傳遞很多參數,如:串口,RAM,videofb等。而Linux kernel也會讀取和處理這些參數。兩者之間通過struct tag來傳遞參數。U-boot把要傳遞給kernel的東西保存在struct tag數據結構中,啟動kernel時,把這個結構體的物理地址傳給kernel;Linux kernel通過這個地址,用parse_tags分析出傳遞過來的參數。
本文主要以U-boot傳遞RAM和Linux kernel讀取RAM參數為例進行說明。
1、u-boot給kernel傳RAM參數
./common/cmd_bootm.c文件中(指Uboot的根目錄),bootm命令對應的do_bootm函數,當分析uImage中信息發現OS是Linux時,調用./lib_arm/bootm.c文件中的do_bootm_linux函數來啟動Linux kernel。
在do_bootm_linux函數中:
void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],\
ulong addr, ulong *len_ptr, int verify)
{
......
#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
defined (CONFIG_CMDLINE_TAG) || \
defined (CONFIG_INITRD_TAG) || \
defined (CONFIG_SERIAL_TAG) || \
defined (CONFIG_REVISION_TAG) || \
defined (CONFIG_LCD) || \
defined (CONFIG_VFD)
setup_start_tag (bd); //初始化tag結構體開始
#ifdef CONFIG_SERIAL_TAG
setup_serial_tag (¶ms);
#endif
#ifdef CONFIG_REVISION_TAG
setup_revision_tag (¶ms);
#endif
#ifdef CONFIG_SETUP_MEMORY_TAGS
setup_memory_tags (bd); //設置RAM參數
#endif
#ifdef CONFIG_CMDLINE_TAG
setup_commandline_tag (bd, commandline);
#endif
#ifdef CONFIG_INITRD_TAG
if (initrd_start && initrd_end)
setup_initrd_tag (bd, initrd_start, initrd_end);
#endif
#if defined (CONFIG_VFD) || defined (CONFIG_LCD)
setup_videolfb_tag ((gd_t *) gd);
#endif
setup_end_tag (bd); //初始化tag結構體結束
#endif
......
......
theKernel (0, machid, bd->bi_boot_params);
//傳給Kernel的參數= (struct tag *)型的bd->bi_boot_params
//bd->bi_boot_params在board_init 函數中初始化,如對於at91rm9200,初始化在at91rm9200dk.c的board_init中進 行:bd->bi_boot_params=PHYS_SDRAM + 0x100;
//這個地址也是所有taglist的首地址,見下面的setup_start_tag函數
}
對於setup_start_tag和setup_memory_tags函數說明如下。
函數setup_start_tag也在此文件中定義,如下:
static void setup_start_tag (bd_t *bd)
{
params = (struct tag *) bd->bi_boot_params;
//初始化(struct tag *)型的全局變數params為bd->bi_boot_params的地址,之後的setup tags相關函數如下面的setup_memory_tags就把其它tag的數據放在此地址的偏移地址上。
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);
}
RAM相關參數在bootm.c中的函數setup_memory_tags中初始化:
static void setup_memory_tags (bd_t *bd)
{
int i;
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
params->hdr.tag = ATAG_MEM;
params->hdr.size = tag_size (tag_mem32);
params->u.mem.start = bd->bi_dram[i].start;
params->u.mem.size = bd->bi_dram[i].size;
params = tag_next (params);
} //初始化內存相關tag
}
2、Kernel讀取U-boot傳遞的相關參數
對於Linux Kernel,ARM平台啟動時,先執行arch/arm/kernel/head.S,此文件會調用arch/arm/kernel/head- common.S和arch/arm/mm/proc-arm920.S中的函數,並最後調用start_kernel:
......
b start_kernel
......
init/main.c中的start_kernel函數中會調用setup_arch函數來處理各種平台相關的動作,包括了u-boot傳遞過來參數的分析和保存:
start_kernel()
{
......
setup_arch(&command_line);
......
}
其中,setup_arch函數在arch/arm/kernel/setup.c文件中實現,如下:
void __init setup_arch(char **cmdline_p)
{
struct tag *tags = (struct tag *)&init_tags;
struct machine_desc *mdesc;
char *from = default_command_line;
setup_processor();
mdesc = setup_machine(machine_arch_type);
machine_name = mdesc->name;
if (mdesc->soft_reboot)
reboot_setup("s");
if (__atags_pointer)
//指向各種tag起始位置的指針,定義如下:
//unsigned int __atags_pointer __initdata;
//此指針指向__initdata段,各種tag的信息保存在這個段中。
tags = phys_to_virt(__atags_pointer);
else if (mdesc->boot_params)
tags = phys_to_virt(mdesc->boot_params);
if (tags->hdr.tag != ATAG_CORE)
convert_to_tag_list(tags);
if (tags->hdr.tag != ATAG_CORE)
tags = (struct tag *)&init_tags;
if (mdesc->fixup)
mdesc->fixup(mdesc, tags, &from, &meminfo);
if (tags->hdr.tag == ATAG_CORE) {
if (meminfo.nr_banks != 0)
squash_mem_tags(tags);
save_atags(tags);
parse_tags(tags);
//處理各種tags,其中包括了RAM參數的處理。
//這個函數處理如下tags:
__tagtable(ATAG_MEM, parse_tag_mem32);
__tagtable(ATAG_VIDEOTEXT, parse_tag_videotext);
__tagtable(ATAG_RAMDISK, parse_tag_ramdisk);
__tagtable(ATAG_SERIAL, parse_tag_serialnr);
__tagtable(ATAG_REVISION, parse_tag_revision);
__tagtable(ATAG_CMDLINE, parse_tag_cmdline);
}
init_mm.start_code = (unsigned long) &_text;
init_mm.end_code = (unsigned long) &_etext;
init_mm.end_data = (unsigned long) &_edata;
init_mm.brk = (unsigned long) &_end;
memcpy(boot_command_line, from, COMMAND_LINE_SIZE);
boot_command_line[COMMAND_LINE_SIZE-1] = '\0';
parse_cmdline(cmdline_p, from); //處理編譯內核時指定的cmdline或u-boot傳遞的cmdline
paging_init(&meminfo, mdesc);
request_standard_resources(&meminfo, mdesc);
#ifdef CONFIG_SMP
smp_init_cpus();
#endif
cpu_init();
init_arch_irq = mdesc->init_irq;
system_timer = mdesc->timer;
init_machine = mdesc->init_machine;
#ifdef CONFIG_VT
#if defined(CONFIG_VGA_CONSOLE)
conswitchp = &vga_con;
#elif defined(CONFIG_DUMMY_CONSOLE)
conswitchp = &mmy_con;
#endif
#endif
early_trap_init();
}
對於處理RAM的tag,調用了parse_tag_mem32函數:
static int __init parse_tag_mem32(const struct tag *tag)
{
......
arm_add_memory(tag->u.mem.start, tag->u.mem.size);
......
}
__tagtable(ATAG_MEM, parse_tag_mem32);
上述的arm_add_memory函數定義如下:
static void __init arm_add_memory(unsigned long start, unsigned long size)
{
struct membank *bank;
size -= start & ~PAGE_MASK;
bank = &meminfo.bank[meminfo.nr_banks++];
bank->start = PAGE_ALIGN(start);
bank->size = size & PAGE_MASK;
bank->node = PHYS_TO_NID(start);
}
如上可見,parse_tag_mem32函數調用arm_add_memory函數把RAM的start和size等參數保存到了meminfo結構的meminfo結構體中。最後,在setup_arch中執行下面語句:
paging_init(&meminfo, mdesc);
對沒有MMU的平台上調用arch/arm/mm/nommu.c中的paging_init,否則調用arch/arm/mm/mmu.c中的paging_init函數。這里暫不分析mmu.c中的paging_init函數。
3、關於U-boot中的bd和gd
U-boot中有一個用來保存很多有用信息的全局結構體 --gd_t(global data縮寫),其中包括了bd變數,可以說gd_t結構體包括了u-boot中所有重要全局變數。最後傳遞給內核的參數,都是從gd和bd中來的,如上 述的setup_memory_tags函數的作用就是用bd中的值來初始化RAM相應的tag。
對於ARM平台這個結構體的定義大致如下:
include/asm-arm/global_data.h
typedef struct global_data {
bd_t *bd;
unsigned long flags;
unsigned long baudrate;
unsigned long have_console; /* serial_init() was called */
unsigned long reloc_off; /* Relocation Offset */
unsigned long env_addr; /* Address of Environment struct */
unsigned long env_valid; /* Checksum of Environment valid? */
unsigned long fb_base; /* base address of frame buffer */
void **jt; /* jump table */
} gd_t;
在U-boot中使用gd結構之前要用先用宏DECLARE_GLOBAL_DATA_PTR來聲明。這個宏的定義如下:
include/asm-arm/global_data.h
#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r8")
從這個宏的定義可以看出,gd是一個保存在ARM的r8寄存器中的gd_t結構體的指針。
說明:本文的版本為U-boot-1.3.4、Linux-2.6.28,平台是ARM。
Ⅳ linux mkimages 文件在哪
下載:
兩種途徑得到mkImage工具uImage,
解決方法:
方法一:
安裝mkimage工具,載ubuntu11.10下執行以下命令進行安裝:
#sudo apt-get install uboot-mkimage
方法二:
編譯uboot源碼,編譯成功後載uboot/tools目錄下會生成mkimgage工具,將mkimage工具拷貝到/usr/bin/目錄下即可。
使用:
uboot源代碼的tools/目錄下有mkimage工具,這個工具可以用來製作不壓縮或者壓縮的多種可啟動映象文件。
mkimage在製作映象文件的時候,是在原來的可執行映象文件的前面加上一個0x40位元組的頭,記錄參數所指定的信息,這樣uboot才能識別這個映象是針對哪個CPU體系結構的,哪個OS的,哪種類型,載入內存中的哪個位置, 入口點在內存的那個位置以及映象名是什麼
root@Glym:/tftpboot# ./mkimage
Usage: ./mkimage -l image
-l ==> list image header information
./mkimage -A arch -O os -T type -C comp -a addr -e ep -n name -d data_file[:data_file...] image
-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)
參數說明:
-A 指定CPU的體系結構:
取值 表示的體系結構
alpha Alpha
arm A RM
x86 Intel x86
ia64 IA64
mips MIPS
mips64 MIPS 64 Bit
ppc PowerPC
s390 IBM S390
sh SuperH
sparc SPARC
sparc64 SPARC 64 Bit
m68k MC68000
-O 指定操作系統類型,可以取以下值:
openbsd、netbsd、freebsd、4_4bsd、linux、svr4、esix、solaris、irix、sco、dell、ncr、lynxos、vxworks、psos、qnx、u-boot、rtems、artos
-T 指定映象類型,可以取以下值:
standalone、kernel、ramdisk、multi、firmware、script、filesystem
-C 指定映象壓縮方式,可以取以下值:
none 不壓縮
gzip 用gzip的壓縮方式
bzip2 用bzip2的壓縮方式
-a 指定映象在內存中的載入地址,映象下載到內存中時,要按照用mkimage製作映象時,這個參數所指定的地址值來下載
-e 指定映象運行的入口點地址,這個地址就是-a參數指定的值加上0x40(因為前面有個mkimage添加的0x40個位元組的頭)
-n 指定映象名
-d 指定製作映象的源文件
U-BOOT下使用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引導所需要的文件頭,具體做法如下:
[root@localhost tftpboot]#mkimage -n 'linux-2.6.14' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008000 -d zImage zImage.img
Image Name: linux-2.6.14
Created: Fri Jan 12 17:14:50 2007
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 1262504 Bytes = 1232.91 kB = 1.20 MB
Load Address: 0x30008000
Entry 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-Boot 1.1.3 (Jan 12 2007 - 16:16:36)
U-Boot code: 33F80000 -> 33F9BAC0 BSS: -> 33F9FBAC
RAM Configuration:
Bank #0: 30000000 64 MB
Nor Flash: 512 kB
Nand Flash: 64 MB
In: serial
Out: serial
Err: serial
Hit any key to stop autoboot: 0
sbc2410=>tftp 0x31000000 zImage.img
TFTP from server 192.168.1.115; our IP address is 192.168.1.128
Filename 'zImage.img'.
Load address: 0x31000000
Loading: #################################################################
#################################################################
#################################################################
####################################################
done
Bytes 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 ... OK
OK
Starting kernel ...
Uncompressing Linux.............................................................Linux version 2.6.14 (root@luofuchong) (gcc version 3.4.1) #21 Fri Oct 20 17:206CPU: ARM920Tid(wb) [41129200] revision 0 (ARMv4T)
Machine: SMDK2410
Memory policy: ECC disabled, Data cache writeback
CPU S3C2410A (id 0x32410002)
S3C2410: core 202.800 MHz, memory 101.400 MHz, peripheral 50.700 MHz
S3C2410 Clocks, (c) 2004 Simtec Electronics
CLOCK: Slow mode (1.500 MHz), fast, MPLL on, UPLL on
USB Control, (c) 2006 sbc2410
CPU0: D VIVT write-back cache
CPU0: I cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
CPU0: D cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
Built 1 zonelists
Kernel command line: console="ttySAC0" root="/dev/nfs" nfsroot="192".168.1.115:/frien"irq: clearing subpending status 00000002
PID hash table entries: 512 (order: 9, 8192 bytes)
timer tcon="00500000", tcnt a509, tcfg 00000200,00000000, usec 00001e4c
Console: colour mmy device 80x30
Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)
Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)
Memory: 64MB = 64MB total
Memory: 62208KB available (1924K code, 529K data, 108K init)
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
softlockup thread 0 started up.
NET: Registered protocol family 16
S3C2410: Initialising architecture
SCSI subsystem initialized
usbcore: registered new driver usbfs
usbcore: registered new driver hub
S3C2410 DMA Driver, (c) 2003-2004 Simtec Electronics
DMA channel 0 at c4800000, irq 33
DMA channel 1 at c4800040, irq 34
DMA channel 2 at c4800080, irq 35
DMA channel 3 at c48000c0, irq 36
NetWinder Floating Point Emulator V0.97 (double precision)
devfs: 2004-01-31 Richard Gooch ([email protected])
devfs: devfs_debug: 0x0
devfs: boot_options: 0x1
yaffs Oct 18 2006 12:39:51 Installing.
Console: switching to colour frame buffer device 30x40
fb0: s3c2410fb frame buffer device
fb1: Virtual frame buffer device, using 1024K of video memory
led driver initialized
s3c2410 buttons successfully loaded
s3c2410_serial0 at MMIO 0x50000000 (irq = 70) is a S3C2410
s3c2410_serial1 at MMIO 0x50004000 (irq = 73) is a S3C2410
s3c2410_serial2 at MMIO 0x50008000 (irq = 76) is a S3C2410
io scheler noop registered
io scheler anticipatory registered
io scheler deadline registered
io scheler cfq registered
RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize
usbcore: registered new driver ub
Cirrus Logic CS8900A driver for Linux (Modified for SMDK2410)
eth0: CS8900A rev E at 0xe0000300 irq="53", no eeprom , addr: 08: 0:3E:26:0A:5B
S3C24XX NAND Driver, (c) 2004 Simtec Electronics
s3c2410-nand: mapped registers at c4980000
s3c2410-nand: timing: Tacls 10ns, Twrph0 30ns, Twrph1 10ns
NAND device: Manufacturer ID: 0xec, Chip ID: 0x76 (Samsung NAND 64MiB 3,3V 8-bi)Scanning device for bad blocks
Bad eraseblock 1884 at 0x01d70000
Creating 4 MTD partitions on "NAND 64MiB 3,3V 8-bit":
0x00000000-0x00020000 : "vivi"
0x00020000-0x00030000 : "param"
0x00030000-0x00200000 : "kernel"
0x00200000-0x04000000 : "root"
usbmon: debugfs is not available
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
Initializing USB Mass Storage driver...
usbcore: registered new driver usb-storage
USB Mass Storage support registered.
usbcore: registered new driver usbmouse
drivers/usb/input/usbmouse.c: v1.6:USB HID Boot Protocol mouse driver
mice: PS/2 mouse device common for all mice
s3c2410 TouchScreen successfully loaded
UDA1341 audio driver initialized
NET: Registered protocol family 2
IP 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 registered
TCP bic registered
NET: Registered protocol family 1
IP-Config: Complete:
device=eth0, addr="192".168.1.128, mask="255".255.255.0, gw="192".168.1.1,
host="luofuchong", domain=, nis-domain=(none),
bootserver="192".168.1.1, rootserver="192".168.1.115, rootpath=
Looking up port of RPC 100003/2 on 192.168.1.115
Looking up port of RPC 100005/1 on 192.168.1.115
VFS: Mounted root (nfs filesystem).
Mounted devfs on /dev
Freeing init memory: 108K
init started: BusyBox v1.1.3 (2006.09.20-14:52+0000) multi-call binary
Starting pid 696, console /dev/tts/0: '/etc/init.d/rcS'
Please press Enter to activate this console.
方法二、
1、首先,用u-boot/tools/mkimage這個工具為你的內核加上u-boot引導所需要的文件頭,具體做法如下:
[root@localhost tftpboot]#mkimage -n 'linux-2.6.14' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008040 -d zImage zImage.img
Image Name: linux-2.6.14
Created: Fri Jan 12 17:14:50 2007
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 1262504 Bytes = 1232.91 kB = 1.20 MB
Load Address: 0x30008000
Entry Point: 0x30008040
2 、下載內核
U-Boot 1.1.3 (Jan 12 2007 - 16:16:36)
U-Boot code: 33F80000 -> 33F9BAC0 BSS: -> 33F9FBAC
RAM Configuration:
Bank #0: 30000000 64 MB
Nor Flash: 512 kB
Nand Flash: 64 MB
In: serial
Out: serial
Err: serial
Hit any key to stop autoboot: 0
sbc2410=>tftp 0x30008000 zImage.img
TFTP from server 192.168.1.115; our IP address is 192.168.1.128
Filename 'zImage.img'.
Load address: 0x30008000
Loading: #################################################################
#################################################################
#################################################################
####################################################
done
Bytes transferred = 1263324 (1346dc hex)
3.運行
sbc2410=>bootm 0x30008000
## Booting image at 30008000 ...
Image Name: linux-2.6.14
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 1261056 Bytes = 1.2 MB
Load Address: 30008000
Entry Point: 30008040
Verifying Checksum ... OK
XIP Kernel Image ... OK
Ⅵ 怎麼讓Uboot中設置的IP能夠在Linux啟動後讀到
U-boot會給LinuxKernel傳遞很多參數,如:串口,RAM,videofb等。而Linuxkernel也會讀取和處理這些參數。兩者之間通過structtag來傳遞參數。U-boot把要傳遞給kernel的東西保存在structtag數據結構中,啟動kernel時,把這個結構體的物理地址傳給kernel;Linuxkernel通過這個地址,用parse_tags分析出傳遞過來的參數。本文主要以U-boot傳遞RAM和Linuxkernel讀取RAM參數為例進行說明。1、u-boot給kernel傳RAM參數./common/cmd_bootm.c文件中(指Uboot的根目錄),bootm命令對應的do_bootm函數,當分析uImage中信息發現OS是Linux時,調用./lib_arm/bootm.c文件中的do_bootm_linux函數來啟動Linuxkernel。在do_bootm_linux函數中:voiddo_bootm_linux(cmd_tbl_t*cmdtp,intflag,intargc,char*argv[],\ulongaddr,ulong*len_ptr,intverify){#ifdefined(CONFIG_SETUP_MEMORY_TAGS)||\defined(CONFIG_CMDLINE_TAG)||\defined(CONFIG_INITRD_TAG)||\defined(CONFIG_SERIAL_TAG)||\defined(CONFIG_REVISION_TAG)||\defined(CONFIG_LCD)||\defined(CONFIG_VFD)setup_start_tag(bd);//初始化tag結構體開始#ifdefCONFIG_SERIAL_TAGsetup_serial_tag(¶ms);#endif#ifdefCONFIG_REVISION_TAGsetup_revision_tag(¶ms);#endif#ifdefCONFIG_SETUP_MEMORY_TAGSsetup_memory_tags(bd);//設置RAM參數#endif#ifdefCONFIG_CMDLINE_TAGsetup_commandline_tag(bd,commandline);#endif#ifdefCONFIG_INITRD_TAGif(initrd_start&&initrd_end)setup_initrd_tag(bd,initrd_start,initrd_end);#endif#ifdefined(CONFIG_VFD)||defined(CONFIG_LCD)setup_videolfb_tag((gd_t*)gd);#endifsetup_end_tag(bd);//初始化tag結構體結束#endiftheKernel(0,machid,bd->bi_boot_params);//傳給Kernel的參數=(structtag*)型的bd->bi_boot_params//bd->bi_boot_params在board_init函數中初始化,如對於at91rm9200,初始化在at91rm9200dk.c的board_init中進行:bd->bi_boot_params=PHYS_SDRAM+0x100;//這個地址也是所有taglist的首地址,見下面的setup_start_tag函數}對於setup_start_tag和setup_memory_tags函數說明如下。函數setup_start_tag也在此文件中定義,如下:staticvoidsetup_start_tag(bd_t*bd){params=(structtag*)bd->bi_boot_params;//初始化(structtag*)型的全局變數params為bd->bi_boot_params的地址,之後的setuptags相關函數如下面的setup_memory_tags就把其它tag的數據放在此地址的偏移地址上。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);}RAM相關參數在bootm.c中的函數setup_memory_tags中初始化:staticvoidsetup_memory_tags(bd_t*bd){inti;for(i=0;ihdr.tag=ATAG_MEM;params->hdr.size=tag_size(tag_mem32);params->u.mem.start=bd->bi_dram[i].start;params->u.mem.size=bd->bi_dram[i].size;params=tag_next(params);}//初始化內存相關tag}2、Kernel讀取U-boot傳遞的相關參數對於LinuxKernel,ARM平台啟動時,先執行arch/arm/kernel/head.S,此文件會調用arch/arm/kernel/head-common.S和arch/arm/mm/proc-arm920.S中的函數,並最後調用start_kernel:bstart_kernelinit/main.c中的start_kernel函數中會調用setup_arch函數來處理各種平台相關的動作,包括了u-boot傳遞過來參數的分析和保存:start_kernel(){setup_arch(&command_line);}其中,setup_arch函數在arch/arm/kernel/setup.c文件中實現,如下:void__initsetup_arch(char**cmdline_p){structtag*tags=(structtag*)&init_tags;structmachine_desc*mdesc;char*from=default_command_line;setup_processor();mdesc=setup_machine(machine_arch_type);machine_name=mdesc->name;if(mdesc->soft_reboot)reboot_setup("s");if(__atags_pointer)//指向各種tag起始位置的指針,定義如下://unsignedint__atags_pointer__initdata;//此指針指向__initdata段,各種tag的信息保存在這個段中。tags=phys_to_virt(__atags_pointer);elseif(mdesc->boot_params)tags=phys_to_virt(mdesc->boot_params);if(tags->hdr.tag!=ATAG_CORE)convert_to_tag_list(tags);if(tags->hdr.tag!=ATAG_CORE)tags=(structtag*)&init_tags;if(mdesc->fixup)mdesc->fixup(mdesc,tags,&from,&meminfo);if(tags->hdr.tag==ATAG_CORE){if(meminfo.nr_banks!=0)squash_mem_tags(tags);save_atags(tags);parse_tags(tags);//處理各種tags,其中包括了RAM參數的處理。//這個函數處理如下tags:__tagtable(ATAG_MEM,parse_tag_mem32);__tagtable(ATAG_VIDEOTEXT,parse_tag_videotext);__tagtable(ATAG_RAMDISK,parse_tag_ramdisk);__tagtable(ATAG_SERIAL,parse_tag_serialnr);__tagtable(ATAG_REVISION,parse_tag_revision);__tagtable(ATAG_CMDLINE,parse_tag_cmdline);}init_mm.start_code=(unsignedlong)&_text;init_mm.end_code=(unsignedlong)&_etext;init_mm.end_data=(unsignedlong)&_edata;init_mm.brk=(unsignedlong)&_end;memcpy(boot_command_line,from,COMMAND_LINE_SIZE);boot_command_line[COMMAND_LINE_SIZE-1]='\0';parse_cmdline(cmdline_p,from);//處理編譯內核時指定的cmdline或u-boot傳遞的cmdlinepaging_init(&meminfo,mdesc);request_standard_resources(&meminfo,mdesc);#ifdefCONFIG_SMPsmp_init_cpus();#endifcpu_init();init_arch_irq=mdesc->init_irq;system_timer=mdesc->timer;init_machine=mdesc->init_machine;#ifdefCONFIG_VT#ifdefined(CONFIG_VGA_CONSOLE)conswitchp=&vga_con;#elifdefined(CONFIG_DUMMY_CONSOLE)conswitchp=&mmy_con;#endif#endifearly_trap_init();}對於處理RAM的tag,調用了parse_tag_mem32函數:staticint__initparse_tag_mem32(conststructtag*tag){arm_add_memory(tag->u.mem.start,tag->u.mem.size);}__tagtable(ATAG_MEM,parse_tag_mem32);上述的arm_add_memory函數定義如下:staticvoid__initarm_add_memory(unsignedlongstart,unsignedlongsize){structmembank*bank;size-=start&~PAGE_MASK;bank=&meminfo.bank[meminfo.nr_banks++];bank->start=PAGE_ALIGN(start);bank->size=size&PAGE_MASK;bank->node=PHYS_TO_NID(start);}如上可見,parse_tag_mem32函數調用arm_add_memory函數把RAM的start和size等參數保存到了meminfo結構的meminfo結構體中。最後,在setup_arch中執行下面語句:paging_init(&meminfo,mdesc);對沒有MMU的平台上調用arch/arm/mm/nommu.c中的paging_init,否則調用arch/arm/mm/mmu.c中的paging_init函數。這里暫不分析mmu.c中的paging_init函數。3、關於U-boot中的bd和gdU-boot中有一個用來保存很多有用信息的全局結構體--gd_t(globaldata縮寫),其中包括了bd變數,可以說gd_t結構體包括了u-boot中所有重要全局變數。最後傳遞給內核的參數,都是從gd和bd中來的,如上述的setup_memory_tags函數的作用就是用bd中的值來初始化RAM相應的tag。對於ARM平台這個結構體的定義大致如下:include/asm-arm/global_data.htypedefstructglobal_data{bd_t*bd;unsignedlongflags;unsignedlongbaudrate;unsignedlonghave_console;/*serial_init()wascalled*/unsignedlongreloc_off;/*RelocationOffset*/unsignedlongenv_addr;/*AddressofEnvironmentstruct*/unsignedlongenv_valid;/*ChecksumofEnvironmentvalid?*/unsignedlongfb_base;/*baseaddressofframebuffer*/void**jt;/*jumptable*/}gd_t;在U-boot中使用gd結構之前要用先用宏DECLARE_GLOBAL_DATA_PTR來聲明。這個宏的定義如下:include/asm-arm/global_data.h#defineDECLARE_GLOBAL_DATA_PTRregistervolatilegd_t*gdasm("r8")從這個宏的定義可以看出,gd是一個保存在ARM的r8寄存器中的gd_t結構體的指針。說明:本文的版本為U-boot-1.3.4、Linux-2.6.28,平台是ARM。
Ⅶ bad magic number 是什麼錯誤哦
啟動移植的內核錯誤
boot1.2中的bootcmd參數,u-boot1.3.1 bootm卻不能引導,報bad magic number,看了bootm的相關資料,得知,如果我們沒用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的頭部。
Bootm在沒有參數時,是採用rat2440.h中的#define CFG_LOAD_ADDR 的位址的,而我用bootm就是沒有使用參數,所以出錯了。正確的做法應該是用nand read命令將內核從nand flash中讀到記憶體的某一位址中(注意不要與其他已分配的記憶體沖突),然後再用bootm 加位址參數,即可引導,也可以在上述的檔中,將CFG_LOAD_ADDR的位址定義為此位址,再用bootm就可以了.我設定bootcmd環境變數為 tftp 0x31000000 uImage; bootm 0x31000000,注意位址不能為0x30008000,否則報錯
Ⅷ 如何從uboot讀取mac,然戶傳遞到內核中
U-boot會給Linux Kernel傳遞很多參數,如:串口,RAM,videofb等。而Linux kernel也會讀取和處理這些參數。兩者之間通過struct tag來傳遞參數。U-boot把要傳遞給kernel的東西保存在struct tag數據結構中,啟動kernel時,把這個結構體的物理地址傳給kernel;Linux kernel通過這個地址,用parse_tags分析出傳遞過來的參數。
本文主要以U-boot傳遞RAM和Linux kernel讀取RAM參數為例進行說明。
1、u-boot給kernel傳RAM參數
./common/cmd_bootm.c文件中(指Uboot的根目錄),bootm命令對應的do_bootm函數,當分析uImage中信息發現OS是Linux時,調用。/lib_arm/bootm.c文件中的do_bootm_linux函數來啟動Linux kernel。
在do_bootm_linux函數中:
void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],\
ulong addr, ulong *len_ptr, int verify)
{
……
#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
defined (CONFIG_CMDLINE_TAG) || \
defined (CONFIG_INITRD_TAG) || \
defined (CONFIG_SERIAL_TAG) || \
defined (CONFIG_REVISION_TAG) || \
defined (CONFIG_LCD) || \
defined (CONFIG_VFD)
setup_start_tag (bd); //初始化tag結構體開始
#ifdef CONFIG_SERIAL_TAG
setup_serial_tag (?ms);
#endif
#ifdef CONFIG_REVISION_TAG
setup_revision_tag (?ms);
#endif
#ifdef CONFIG_SETUP_MEMORY_TAGS
setup_memory_tags (bd); //設置RAM參數
#endif
#ifdef CONFIG_CMDLINE_TAG
setup_commandline_tag (bd, commandline);
#endif
#ifdef CONFIG_INITRD_TAG
if (initrd_start && initrd_end)
setup_initrd_tag (bd, initrd_start, initrd_end);
#endif
#if defined (CONFIG_VFD) || defined (CONFIG_LCD)
setup_videolfb_tag ((gd_t *) gd);
#endif
setup_end_tag (bd); //初始化tag結構體結束
#endif
……
……
theKernel (0, machid, bd->bi_boot_params);
//傳給Kernel的參數= (struct tag *)型的bd->bi_boot_params
//bd->bi_boot_params在board_init 函數中初始化,如對於at91rm9200,初始化在at91rm9200dk.c的board_init中進 行:bd->bi_boot_params=PHYS_SDRAM + 0x100;
//這個地址也是所有taglist的首地址,見下面的setup_start_tag函數
}
對於setup_start_tag和setup_memory_tags函數說明如下。
函數setup_start_tag也在此文件中定義,如下:
static void setup_start_tag (bd_t *bd)
{
params = (struct tag *) bd->bi_boot_params;
//初始化(struct tag *)型的全局變數params為bd->bi_boot_params的地址,之後的setup tags相關函數如下面的setup_memory_tags就把其它tag的數據放在此地址的偏移地址上。
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);
}
RAM相關參數在bootm.c中的函數setup_memory_tags中初始化:
static void setup_memory_tags (bd_t *bd)
{
int i;
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
params->hdr.tag = ATAG_MEM;
params->hdr.size = tag_size (tag_mem32);
params->u.mem.start = bd->bi_dram[i].start;
params->u.mem.size = bd->bi_dram[i].size;
params = tag_next (params);
} //初始化內存相關tag
}
2、Kernel讀取U-boot傳遞的相關參數
對於Linux Kernel,ARM平台啟動時,先執行arch/arm/kernel/head.S,此文件會調用arch/arm/kernel/head- common.S和arch/arm/mm/proc-arm920.S中的函數,並最後調用start_kernel:
……
b start_kernel
……
init/main.c中的start_kernel函數中會調用setup_arch函數來處理各種平台相關的動作,包括了u-boot傳遞過來參數的分析和保存:
start_kernel()
{
……
setup_arch(&command_line);
……
}
其中,setup_arch函數在arch/arm/kernel/setup.c文件中實現,如下:
void __init setup_arch(char **cmdline_p)
{
struct tag *tags = (struct tag *)&init_tags;
struct machine_desc *mdesc;
char *from = default_command_line;
setup_processor();
mdesc = setup_machine(machine_arch_type);
machine_name = mdesc->name;
if (mdesc->soft_reboot)
reboot_setup("s");
if (__atags_pointer)
//指向各種tag起始位置的指針,定義如下:
//unsigned int __atags_pointer __initdata;
//此指針指向__initdata段,各種tag的信息保存在這個段中。
tags = phys_to_virt(__atags_pointer);
else if (mdesc->boot_params)
tags = phys_to_virt(mdesc->boot_params);
if (tags->hdr.tag != ATAG_CORE)
convert_to_tag_list(tags);
if (tags->hdr.tag != ATAG_CORE)
tags = (struct tag *)&init_tags;
if (mdesc->fixup)
mdesc->fixup(mdesc, tags, &from, &meminfo);
if (tags->hdr.tag == ATAG_CORE) {
if (meminfo.nr_banks != 0)
squash_mem_tags(tags);
save_atags(tags);
parse_tags(tags);
//處理各種tags,其中包括了RAM參數的處理。
//這個函數處理如下tags:
__tagtable(ATAG_MEM, parse_tag_mem32);
__tagtable(ATAG_VIDEOTEXT, parse_tag_videotext);
__tagtable(ATAG_RAMDISK, parse_tag_ramdisk);
__tagtable(ATAG_SERIAL, parse_tag_serialnr);
__tagtable(ATAG_REVISION, parse_tag_revision);
__tagtable(ATAG_CMDLINE, parse_tag_cmdline);
}
init_mm.start_code = (unsigned long) &_text;
init_mm.end_code = (unsigned long) &_etext;
init_mm.end_data = (unsigned long) &_edata;
init_mm.brk = (unsigned long) &_end;
memcpy(boot_command_line, from, COMMAND_LINE_SIZE);
boot_command_line[COMMAND_LINE_SIZE-1] = '\0';
parse_cmdline(cmdline_p, from); //處理編譯內核時指定的cmdline或u-boot傳遞的cmdline
paging_init(&meminfo, mdesc);
request_standard_resources(&meminfo, mdesc);
#ifdef CONFIG_SMP
smp_init_cpus();
#endif
cpu_init();
init_arch_irq = mdesc->init_irq;
system_timer = mdesc->timer;
init_machine = mdesc->init_machine;
#ifdef CONFIG_VT
#if defined(CONFIG_VGA_CONSOLE)
conswitchp = &vga_con;
#elif defined(CONFIG_DUMMY_CONSOLE)
conswitchp = &mmy_con;
#endif
#endif
early_trap_init();
}
對於處理RAM的tag,調用了parse_tag_mem32函數:
static int __init parse_tag_mem32(const struct tag *tag)
{
……
arm_add_memory(tag->u.mem.start, tag->u.mem.size);
……
}
__tagtable(ATAG_MEM, parse_tag_mem32);
上述的arm_add_memory函數定義如下:
static void __init arm_add_memory(unsigned long start, unsigned long size)
{
struct membank *bank;
size -= start & ~PAGE_MASK;
bank = &meminfo.bank[meminfo.nr_banks++];
bank->start = PAGE_ALIGN(start);
bank->size = size & PAGE_MASK;
bank->node = PHYS_TO_NID(start);
}
如上可見,parse_tag_mem32函數調用arm_add_memory函數把RAM的start和size等參數保存到了meminfo結構的meminfo結構體中。最後,在setup_arch中執行下面語句:
paging_init(&meminfo, mdesc);
對沒有MMU的平台上調用arch/arm/mm/nommu.c中的paging_init,否則調用arch/arm/mm/mmu.c中的paging_init函數。這里暫不分析mmu.c中的paging_init函數。
Ⅸ mkimage 命令可以製作根文件系統鏡像么
bootm命令是用來引導經過u-boot的工具mkimage打包後的kernel image的,什麼叫做經過u-boot的工具mkimage打包後的kernel image,這個就要看mkimage的代碼,看看它做了些什麼,雖然我很希望大家不要偷懶,認真地去看看,但是我知道還是有很多人懶得去做這件,那麼我就j將分析mkimage代碼後得到的總結告訴大家,mkimage做了些什麼,怎麼用這個工具。
mkimage的用法
uboot源代碼的tools/目錄下有mkimage工具,這個工具可以用來製作不壓縮或者壓縮的多種可啟動映象文件。
mkimage在製作映象文件的時候,是在原來的可執行映象文件的前面加上一個0x40位元組的頭,記錄參數所指定的信息,這樣uboot才能識別這個映象是針對哪個CPU體系結構的,哪個OS的,哪種類型,載入內存中的哪個位置, 入口點在內存的那個位置以及映象名是什麼
root@Glym:/tftpboot# ./mkimage
Usage: ./mkimage -l image
-l ==> list image header information
./mkimage -A arch -O os -T type -C comp -a addr -e ep -n name -d data_file[:data_file...] image
-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)
參數說明:
-A 指定CPU的體系結構:
取值 表示的體系結構
alpha Alpha
arm ARM
x86 Intel x86
ia64 IA64
mips MIPS
mips64 MIPS 64 Bit
ppc PowerPC
s390 IBM S390
sh SuperH
sparc SPARC
sparc64 SPARC 64 Bit
m68k MC68000
-O 指定操作系統類型,可以取以下值:
openbsd、netbsd、freebsd、4_4bsd、linux、svr4、esix、solaris、irix、sco、dell、ncr、lynxos、vxworks、psos、qnx、u-boot、rtems、artos
-T 指定映象類型,可以取以下值:
standalone、kernel、ramdisk、multi、firmware、script、filesystem
-C 指定映象壓縮方式,可以取以下值:
none 不壓縮
gzip 用gzip的壓縮方式
bzip2 用bzip2的壓縮方式
-a 指定映象在內存中的載入地址,映象下載到內存中時,要按照用mkimage製作映象時,這個參數所指定的地址值來下載
-e 指定映象運行的入口點地址,這個地址就是-a參數指定的值加上0x40(因為前面有個mkimage添加的0x40個位元組的頭)
-n 指定映象名
-d 指定製作映象的源文件
mkimage
解壓內核源碼包,編輯Makefile
設置 cross_compile:=[編譯器的絕對路徑] ;這個絕對路徑既上面2.95.3放到的路徑
進入內核文件夾,執行下面命令
[root@hostname]# make clean
[root@hostname]# make dep
[root@hostname]# make
[root@hostname]# [編譯器的絕對路徑]/bin/arm-linux-obj -O binary -S vmlinux linux.bin ;編譯器的絕對路徑也是上面說到的路徑
[root@hostname]# gzip linux.bin
下面的比較重要了,主要是u-boot的安裝,這個在H9200的手冊上說的很不清楚
[root@hostname]# tar xzvf u-boot-1.0.0.tar.gz ;解壓u-boot
[root@hostname]# cd u-boot-1.0.0
[root@hostname]# make distclean
[root@hostname]# make at91rm9200dk_config
[root@hostname]# make all
然後在/usr/local下建立uboot文件夾將u-boot-1.0.0下的所有文件都復制到uboot下
[root@hostname]# [uboot的絕對路徑]/tools/mkimage -A arm -O linux -C gzip -a 0x20008000 -e 0x20008000 -d linux.bin.gz uImage ;這里的絕對路徑是/usr/local/uboot
vmlinux linux.bin linux.bin.gz uImage(uboot製作的image)
mkimage -a -e
-a參數後是內核的運行地址,-e參數後是入口地址。
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的頭部。
QUESTIONS
1. I have built a vmlinux image but I can boot it.
2: The mkimage tool, ARMboot's tftp command, and the bootm command require
certain load and entry addresses. I'm confused which ones to chose.
ANSWERS
1. I have built a vmlinux image but I can boot it.
--------------------------------------------------
ARMboot is designed to boot Images as created by the mkimage tool, that
comes with ARMboot and is automatically built, too. You cannot directly load
the vmlinux image, as it expects a number of prerequisits such as special
register contents etc.
2. The mkimage tool, ARMboot's tftp command, and the bootm command require
certain load and entry addresses. I'm confused which ones to chose.
--------------------------------------------------------------------------
Well, there are 3 different addresses:
1. Kernel Load Address. This is the address, where the kernel was linked
to when you built the vmlinux and can be found in arch/arm/Makefile.
The default for it is:
ifeq ($(CONFIG_CPU_32),y)
PROCESSOR = armv
TEXTADDR = 0xC0008000
LDSCRIPT = arch/arm/vmlinux-armv.lds.in
endif
Provide this as "-a" parameter to mkimage.
2. Kernel Entry Point. This is the address, where ARMboot jumps to to
enter the Kernel. It usually is the same as the kernel load address.
Provide this as "-e" parameter to mkimage.
3. The Network Download Address. This is where you download the mkimage
File. This address MUST BE different to the Kernel Load Address, and
should be sufficiently far away to allow ARMboot to relocate the
image to the final Kernel Load Address. Loading to the 5th MB
within the RAM is usually a good idea, eg. if the RAM begins at
0xc0000000, you can do this:
LART # tftp c0400000 linux.img
ARP broadcast 1
eth addr: 00:02:03:04:05:06
TFTP from server 192.168.1.1; our IP address is 192.168.1.2
Filename 'image.img'.
Load address: 0xc0400000
Loading:
##################################################################done
Bytes transferred = 567252 (8a7d4 hex)
LART # bootm c0400000
Image Name: Linux 2.4.18
Created: Mon Jun 24 12:00:01 2002
Image Type: ARM Linux Kernel Image (gzip compressed)
Data Size: 567188 Bytes = 553 kB = 0 MB
Load Address: 0xc0008000
Entry Point: 0xc0008000
Verifying Checksum ... OK
Loading Kernel Image ... OK
Starting kernel ...
Linux version 2.4.18 (mag@mag) (gcc version 2.95.3 20010315 (release)) #4 Mon Jun 17 20:35:32 CST 2002