奇怪了,用 arch/arm/boot/zImage生成uImage, 可以用u-boot的bootm命令启动,但是vmlinux这个文件生成的uImage却不能启动
下面这个生成的uImage可以启动:
mkimage -A arm -O linux -T kernel -C none -a 0x41010000 -e 0x41010040 -d arch/arm/boot/zImage uImage
下面这种方法不行
arm-linux-objcopy -O binary vmlinux vmlinux.bin;
mkimage -A arm -O linux -T kernel -C none -a 0x41010000 -e 0x41010040 -d vmlinux.bin uImage
最近编辑记录 bugfix (2018-01-29 16:17:36)
离线
看下这篇文章有没有帮助, 谷歌自动翻译:
https://free-electrons.com/blog/uncompressed-linux-kernel-on-arm/
如何在ARM上启动未压缩的Linux内核
发表于 2012 年3月8日,由 迈克尔Opdenacker
这是一个快速的帖子,在内核压缩选项的基准测试期间,分享我启动未压缩的Linux内核映像的经验,根本没有任何压缩是这些选项之一。
在没有压缩的情况下启动内核映像有时很有用。尽管内核映像比较大,并且需要更多的时间从存储器复制到RAM,但内核映像不再需要解压缩到RAM中。这对于CPU速度非常慢的系统非常有用,或者在引导阶段存储压缩和未压缩映像的RAM很少。典型的情况是,在处理器开发期间,在最终硅片出来之前,引导由FPGA模拟的CPU。例如,在Linaro Connect期间,我看到11 MHz的Cortex A15芯片启动Q2.11在布达佩斯。在这个时钟频率下,无压缩地启动内核映像节省了几分钟的启动时间,减少了开发和测试时间。请注意,使用这样的硬件仿真器,在开始模拟系统之前,将内核映像复制到RAM是便宜的,因为仿真器从用户给出的文件中完成。
在ARM上构建一个没有压缩的内核映像是很容易的,但是只有一次你知道未压缩的映像在哪里以及该怎么做!对于以前从未这样做的人,我在这里分享快速指示。
要生成未压缩的内核映像,只需运行通常的make命令即可。你需要的文件是arch/arm/boot/Image。
根据你使用的bootloader,这可能就足够了。然而,如果你使用U-boot,你仍然需要把这个图像放在一个uImage容器中,让U-boot知道图像有多大,入口点是什么,压缩或不压缩等细节。问题是你不能运行make uImage任何更多的产生这个容器。这是因为ARM上的Linux没有配置选项来保持内核未压缩,并且该uImage文件将包含压缩的内核。
因此,您必须uImage通过mkimage手动调用该命令来创建。要做到这一点,而不必猜测正确的mkimage参数,我建议运行make V=1 uImage一次:
$ make V = 1 uImage
...
内核:arch / arm / boot / zImage准备就绪
/ bin / bash /home/mike/linux/scripts/mkuboot.sh -A arm -O linux -T kernel -C none -a 0x80008000 -e 0x80008000 -n'Linux-3.3.0-rc6-00164-g4f262ac'-d arch / arm / boot / zImage arch / arm / boot / uImage
图像名称:Linux-3.3.0-rc6-00164-g4f262ac已
创建:Thu Mar 8 13:54:00 2012
图像类型:ARM Linux Kernel Image(未压缩)
数据大小:3351272字节= 3272.73 kB = 3.20 MB
加载地址:80008000
入口点:80008000
映像arch / arm / boot / uImage已准备就绪
如果上面的消息说内核是未压缩的(对应于-C none),不要感到惊讶。如果我们告诉U-boot图像已经被压缩了,那么在启动内核镜像之前,需要把它解压缩到RAM中。
现在,你知道mkimage你需要运行什么命令。刚上调用这个命令Image文件,而不是zImage(你可以直接替换mkuboot.sh的mkimage):
$ mkimage -A arm -O linux -T kernel -C none -a 0x80008000 -e 0x80008000 -n'Linux-3.3.0-rc6-00164-g4f262ac'-d arch / arm / boot / Image arch / arm / boot /的uImage
图像名称:Linux的3.3.0-rc6-00164-g4f262ac
创建:星期四03月08 14点02分27秒2012
图像种类:ARM Linux内核图像(未压缩)
数据大小:6958068字节= 6794.99 KB = 6.64 MB
加载地址: 80008000
入口点:80008000
离线
http://blog.csdn.net/panzhenjie/article/details/48173265
linux kernel编译产生的vmlinux Image zImage之间的关系
linux kernel的编译过程比较复杂,最后生成的给用户使用的kernel文件也是多种多样。
先来看一段编译ARM kernel时命令行最后的输出,主要可以分为5个步骤:
- 生成vmlinux
- 生成arch/arm/boot/Image
- 生成arch/arm/boot/compressed/piggy.gzip
- 生成arch/arm/boot/compressed/vmlinux
- 生成arch/arm/boot/zImage
LD vmlinux
SYSMAP System.map
OBJCOPY arch/arm/boot/Image
Kernel: arch/arm/boot/Image is ready
Building modules, stage 2.
GZIP arch/arm/boot/compressed/piggy.gzip
MODPOST 1 modules
CC arch/arm/boot/compressed/misc.o
CC drivers/scsi/scsi_wait_scan.mod.o
CC arch/arm/boot/compressed/decompress.o
CC arch/arm/boot/compressed/string.o
LD [M] drivers/scsi/scsi_wait_scan.ko
AS arch/arm/boot/compressed/piggy.gzip.o
LD arch/arm/boot/compressed/vmlinux
OBJCOPY arch/arm/boot/zImage
Kernel: arch/arm/boot/zImage is ready
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
我们来逐步分析每一个步骤:
生成vmlinux
vmlinux生成在kernel的根目录下,大小为28MB。链接文件在arch/arm/kernel/vmlinux.lds。
panzhenjie@panzhenjie-vmware:~/workspace/linux-3.5$ ll
......
-rwxrwxr-x 1 panzhenjie panzhenjie 28289095 9月 1 07:27 vmlinux*
1
2
3
这个vmlinux是一个elf格式的文件,通过readelf命令我们可以看到,这个文件的链接地址是0xc0008000。
从第1段.head.text开始到第22段.bss,一共占用了2MB多的空间,而后面20多MB的数据其实都是些不必要的调试信息。
panzhenjie@panzhenjie-vmware:~/workspace/linux-3.5$ readelf -S vmlinux
There are 36 section headers, starting at offset 0x1a09770:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .head.text PROGBITS c0008000 008000 0001c4 00 AX 0 0 4
[ 2] .text PROGBITS c0008200 008200 1948e4 00 AX 0 0 64
[ 3] .rodata PROGBITS c019d000 19d000 072100 00 A 0 0 64
[ 4] __bug_table PROGBITS c020f100 20f100 0028c8 00 A 0 0 1
[ 5] __ksymtab PROGBITS c02119c8 2119c8 003c28 00 A 0 0 4
[ 6] __ksymtab_gpl PROGBITS c02155f0 2155f0 001988 00 A 0 0 4
[ 7] __ksymtab_strings PROGBITS c0216f78 216f78 00b9b8 00 A 0 0 1
[ 8] __param PROGBITS c0222930 222930 000340 00 A 0 0 4
[ 9] __modver PROGBITS c0222c70 222c70 000390 00 A 0 0 4
[10] .ARM.unwind_idx ARM_EXIDX c0223000 223000 00ea60 00 AL 12 0 4
[11] .ARM.unwind_tab PROGBITS c0231a60 231a60 002964 00 A 0 0 4
[12] .init.text PROGBITS c0235000 235000 0182f8 00 AX 0 0 32
[13] .exit.text PROGBITS c024d2f8 24d2f8 000480 00 AX 0 0 4
[14] .init.arch.info PROGBITS c024d778 24d778 000240 00 A 0 0 4
[15] .init.tagtable PROGBITS c024d9b8 24d9b8 000048 00 A 0 0 4
[16] .init.smpalt PROGBITS c024da00 24da00 0001d8 00 A 0 0 4
[17] .init.pv_table PROGBITS c024dbd8 24dbd8 000488 00 A 0 0 1
[18] .init.data PROGBITS c024e060 24e060 0081ac 00 WA 0 0 8
[19] .data..percpu PROGBITS c0257000 257000 001480 00 WA 0 0 64
[20] .data PROGBITS c025a000 25a000 042760 00 WA 0 0 64
[21] .notes NOTE c029c760 29c760 000024 00 AX 0 0 4
[22] .bss NOBITS c029c7c0 29c784 0319ec 00 WA 0 0 64
[23] .comment PROGBITS 00000000 29c784 00002b 01 MS 0 0 1
[24] .ARM.attributes ARM_ATTRIBUTES 00000000 29c7af 00002d 00 0 0 1
[25] .debug_line PROGBITS 00000000 29c7dc 140a16 00 0 0 1
[26] .debug_info PROGBITS 00000000 3dd1f2 10da832 00 0 0 1
[27] .debug_abbrev PROGBITS 00000000 14b7a24 0b90ba 00 0 0 1
[28] .debug_aranges PROGBITS 00000000 1570ae0 006910 00 0 0 8
[29] .debug_ranges PROGBITS 00000000 15773f0 0a11e0 00 0 0 8
[30] .debug_frame PROGBITS 00000000 16185d0 03ef0c 00 0 0 4
[31] .debug_str PROGBITS 00000000 16574dc 088dbd 01 MS 0 0 1
[32] .debug_loc PROGBITS 00000000 16e0299 32934c 00 0 0 1
[33] .shstrtab STRTAB 00000000 1a095e5 00018a 00 0 0 1
[34] .symtab SYMTAB 00000000 1a09d10 0908d0 10 35 30957 4
[35] .strtab STRTAB 00000000 1a9a5e0 060267 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
生成arch/arm/boot/Image
Image文件被除去了一些不必要的调试信息,是一个已经可以使用了的kernel文件了,只有2.7MB。
panzhenjie@panzhenjie-vmware:~/workspace/linux-3.5$ ll arch/arm/boot/
......
-rwxrwxr-x 1 panzhenjie panzhenjie 2705284 9月 1 07:27 Image*
1
2
3
arch/arm/boot/Makefile
$(obj)/Image: vmlinux FORCE
$(call if_changed,objcopy)
@echo ' Kernel: $@ is ready'
1
2
3
4
5
scripts/Kbuild.include
# Execute command if command has changed or prerequisite(s) are updated.
#
if_changed = $(if $(strip $(any-prereq) $(arg-check)), \
@set -e; \
$(echo-cmd) $(cmd_$(1)); \
echo 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd)
1
2
3
4
5
6
7
8
scripts/Makefile.lib
# Objcopy
# ---------------------------------------------------------------------------
quiet_cmd_objcopy = OBJCOPY $@
cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@
1
2
3
4
5
6
7
arch/arm/Makefile
OBJCOPYFLAGS :=-O binary -R .comment -S
1
2
3
生成arch/arm/boot/compressed/piggy.gzip
为了让kernel更小,下一步就是对kernel进行压缩,压缩出来的kernel变成了1.3MB。
panzhenjie@panzhenjie-vmware:~/workspace/linux-3.5$ ll arch/arm/boot/compressed/
......
-rw-rw-r-- 1 panzhenjie panzhenjie 1311566 9月 1 07:27 piggy.gzip
1
2
3
arch/arm/boot/compressed/Makefile
suffix_$(CONFIG_KERNEL_GZIP) = gzip
suffix_$(CONFIG_KERNEL_LZO) = lzo
suffix_$(CONFIG_KERNEL_LZMA) = lzma
suffix_$(CONFIG_KERNEL_XZ) = xzkern
$(obj)/piggy.$(suffix_y): $(obj)/../Image FORCE
$(call if_changed,$(suffix_y))
1
2
3
4
5
6
7
8
9
scripts/Makefile.lib
# Gzip
# ---------------------------------------------------------------------------
quiet_cmd_gzip = GZIP $@
cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -n -f -9 > $@) || \
(rm -f $@ ; false)
1
2
3
4
5
6
7
8
生成arch/arm/boot/compressed/vmlinux
piggy.zip只是对kernel进行了压缩,但是还并不能让我们直接使用。想要使用,必须要加上自解压缩代码。
可以看到,生成出来的elf格式的kernel就比刚才压缩过的kernel大一点而已。
panzhenjie@panzhenjie-vmware:~/workspace/linux-3.5$ ll arch/arm/boot/compressed/
......
-rwxrwxr-x 1 panzhenjie panzhenjie 1404652 9月 1 07:27 vmlinux*
1
2
3
4
arch/arm/boot/compressed/Makefile
$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \
$(addprefix $(obj)/, $(OBJS)) $(lib1funcs) $(ashldi3) FORCE
@$(check_for_multiple_zreladdr)
$(call if_changed,ld)
@$(check_for_bad_syms)
$(obj)/piggy.$(suffix_y).o: $(obj)/piggy.$(suffix_y) FORCE
1
2
3
4
5
6
7
8
9
生成arch/arm/boot/zImage
最后一步,就是剔除掉新的压缩后的kernel中的调试信息,成为一个真正可以使用的带有自解压功能的kernel。
panzhenjie@panzhenjie-vmware:~/workspace/linux-3.5$ ll arch/arm/boot/
......
-rwxrwxr-x 1 panzhenjie panzhenjie 1329592 9月 1 07:27 zImage*
1
2
3
4
arch/arm/boot/Makefile
$(obj)/zImage: $(obj)/compressed/vmlinux FORCE
$(call if_changed,objcopy)
@echo ' Kernel: $@ is ready'
离线
根据 @晕哥 在二楼的转帖,
我把uImage 地址改到 0x40008000, 还是没有什么用.
生成并烧录uImage
arm-linux-objcopy -O binary vmlinux vmlinux.bin
mkimage -A arm -O linux -T kernel -C none -a 0x40007fc0 -e 0x40008000 -d vmlinux.bin uImage
sudo sunxi-fel -p spiflash-write 0x110000 uImage
u-boot的bootcmd命令:
bootcmd=sf probe 0 108000000; sf read 0x40004000 0x100000 0x4000; sf read 0x40008000 0x110000 0xD00000; bootm 0x40007fc0 - 0x40004000
启动:
=> bootm 0x40008000
## Booting kernel from Legacy Image at 40008000 ...
Image Name:
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 10712988 Bytes = 10.2 MiB
Load Address: 40007fc0
Entry Point: 40008000
Verifying Checksum ... OK
Loading Kernel Image ... OKStarting kernel ...
然后就没有然后了...
最近编辑记录 bugfix (2018-01-30 09:46:06)
离线
arm-linux-objcopy -O binary vmlinux vmlinux.bin
mkimage -A arm -O linux -T kernel -C none -a 0x40008000 -e 0x40008000 -d vmlinux.bin uImage
sudo sunxi-fel -p spiflash-write 0x110000 uImage
u-boot的bootcmd命令:
bootcmd=sf probe 0 108000000; sf read 0x40004000 0x100000 0x4000; sf read 0x40008000 0x110000 0xD00000; bootm 0x40008000
仍然没什么用,看来还是洗洗睡吧
离线