Chinaunix首页 | 论坛 | 博客
  • 博客访问: 239113
  • 博文数量: 68
  • 博客积分: 884
  • 博客等级: 准尉
  • 技术积分: 700
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-25 14:34
文章分类

全部博文(68)

文章存档

2016年(3)

2015年(4)

2014年(9)

2013年(8)

2012年(6)

2011年(19)

2010年(19)

我的朋友

分类: LINUX

2011-11-20 15:55:11

Here's an article from IBM for introducing the base knowledge of linux initial ram disk.(Refer to http://www.ibm.com/developerworks/linux/library/l-initrd/index.html), including how to create initramfs & boot system with an initramfs. 

It's very good, however, i think maybe written several years ago. something changes in modern linux --- usually we use single file called vmlinuz-initrd(include kernel & ramfs) to boot system but not separate into 2 file, and you could not generate the customization vmlinuz-initrd according to the reference int the article.

When google "extract initramfs", there are a lot of command such as "gzip -d -9 < vmlinuz-initrd >vmlinuz ; cpio -i < vmlinuz". but it always filed when i try it. Finally, i use 'file vmlinuz' , it's recognized as ELF file not cpio archive ,of course  it's unable to extract by cpio.  Why ELF ?

One reason is that, in modern linux compile script, initial ramdisk is compiled into vmlinuz.o, with all other build-in modules, that mean the ramdisk data is treated as a module(section data) in the final vmlinuz-initd. So, it's impossible to extract ram rootfs from vmlinuz-initrd .

How to generate vmlinuz-initrd with ram rootfs build-in ?

First, in the Linux top-level Makefile, one comment as following:

# Build vmlinux
# ---------------------------------------------------------------------------
# vmlinux is built from the objects selected by $(vmlinux-init) and
# $(vmlinux-main). Most are built-in.o files from top-level directories
# in the kernel tree, others are specified in arch/$(ARCH)/Makefile.
# Ordering when linking is important, and $(vmlinux-init) must be first.
#
# vmlinux
#  ^
#  |
#  +-< $(vmlinux-init)
#  |      +--< init/version.o + more
#  |
#  +--< $(vmlinux-main)
#  |       +--< driver/built-in.o mm/built-in.o + more
#  |
#  +-< kallsyms.o (see description in CONFIG_KALLSYMS section)
#
# vmlinux version (uname -v) cannot be updated during normal
# descending-into-subdirs phase since we do not yet know if we need to
# update vmlinux.
# Therefore this step is delayed until just before final link of vmlinux -
# except in the kallsyms case where it is done just before adding the
# symbols to the kernel.
#

vmlinux-init := $(head-y) $(init-y)
vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)
vmlinux-all := $(vmlinux-init) $(vmlinux-main)
vmlinux-lds := arch/$(SRCARCH)/kernel/vmlinux.lds

Note the $(core-y), defined as

core-y   := usr/ 
core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
core-y := $(patsubst %/, %/built-in.o, $(core-y)


ok, look at usr/, find the Makefile,  initramfs_data.S, gen_init_cpio.c . With these 3 files ,Linux generate the vmlnuz-initrd include ram rootfs:

>>>gen_init_cpio.c : generate the cpio archive from the folder which is specified by CONFIG_INITRAMFS_SOURCE in .config

>>>initramfs_data.S : Place the above archive data in vmlinuz-initrd. the content is:

.section .init.ramfs,"a"
.incbin "usr/initramfs_data.cpio"

these 2 assemble command means : 1) append one section named ".init.ramfs" to objs 2)include the file "usr/initramfs_data.cpio" verbatim at current location. Just compile the .S in order to generate objs with ramfs data location in it. Too simple!

I use objdump this generated objs:

objdump -ah initramfs_data.o

initramfs_data.o: file format elf32-little
initramfs_data.o

Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000000 00000000 00000000 00000040 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00000000 00000000 00000000 00000040 2**4
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 00000000 00000000 00000040 2**4
ALLOC
3 .reginfo 00000018 00000000 00000000 00000040 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .pdr 00000000 00000000 00000000 00000058 2**2
CONTENTS, READONLY
5 .init.ramfs 0012fc00 00000000 00000000 00000058 2**0
  CONTENTS, ALLOC, LOAD, READONLY, DATA

I find the init.ramfs section and the size 0012fc00 is correct size of the cpio archive.the finally step is link this object with all other build-in modules and the vmlinux_main.o to generate vmlinuz-initrd.


阅读(1436) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~