LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 3045|回复: 7

LFS下做initrd.img的一些资料

[复制链接]
发表于 2005-3-6 21:50:18 | 显示全部楼层 |阅读模式
提醒一下大家,initrd.img是各厂商的发行版为了避免内核太大而做的一个小一些的RAMdisk,对于LFS来说,不是必需的,因为我们的内核只针对本机硬件编译,内核不会大的。而且直接用vmlinuz启动,速度更快更稳定。
本文只给对initrd.img工作原理感兴趣的朋友看看。
文档共两篇,第二篇有2.6内核的内容。

TITLE:          initrd for LFS
LFS VERSION:    any
AUTHOR:         Jim Gifford <giffordj@linkline.com>

SYNOPSIS:
        How to setup initrd for LFS.

HINT:
$Revision: 1.8 $

Introduction to Initial RAMDisk

This hint will help you configure an LFS system for Initial RAMDisk.
Which will allow you to add modules at start-up instead of compiling them
into the kernel.

The script that is enclosed works with SCSI and USB modules only. IDE
devices are recommened to be built-in the kernel. The script will
auto-detect all SCSI and USB modules and add them to the initial ramdisk.
It will also detect the root from the fstab file

---
Assumptions Made in this document

I have made the following assumptions in this document.
Files have been downloaded.

---
Kernel Configuration

You will need to make sure the following items are configured
in your kernel. With out these, the initrd will not work.

Block Devices

Select Loopback Device Support this can be a module
or built-in.

Select RAM Disk Support this needs to be compiled as
built-in or the initrd will not show up.

Set Default RAM Disk size is 4096 which is the default

Select Initial RAM Disk (initrd) support needs be selected.

---
Needed File System Changes

You will need to create a directory for initrd to use.

The default one that is looked for is /initrd.

To Create this directory use mkdir /initrd

Another change that needs to be made is due to a bug
in busybox itself.

You will need to create a symlink to init and call it
linuxrc

cd /sbin
ln -sf init linuxrc

---
Needed Static Modules

In order for the initrd to work properly during boot up
you will need to create to static programs.

The first one being bash.

busybox
----

Busybox has a Config.h file that needs the following options
enabled to enable them remove the //

#define BB_INSMOD
#define BB_FEATURE_SH_STANDALONE_SHELL

You can configure the rest as you need, but remember have at
least the following enabled to make initrd to work properly.

#define BB_ASH
#define BB_CHROOT
#define BB_ECHO
#define BB_INSMOD
#define BB_MKDIR
#define BB_MODPROBE
#define BB_MOUNT
#define BB_PIVOT_ROOT
#define BB_UMOUNT

To create a static version of bash needed for initrd use
the following commands.

cd /usr/src
tar zxvf /usr/src/busybox-*.tar.gz
cd busy*
make LDFLAGS=-static
cp busybox /bin/busybox

Busybox must be in the /bin directory or the links created
during the initrid will fail.

---
mkinitrd

For those who do not want to type out the script. It is
available on my CVS server at
http://www.jg555.com/cvs/cvsweb.cgi/scripts/mkinitrd-lfs

This script will create the initial RAM Disk image file.
By default this script creates /boot/initrd.img

The default location for this file is /sbin

#!/bin/bash

# mkinitrd for LFS by Jim Gifford <giffordj@linkline.com>
# $Revision: 1.8 $

# Variables
TEMP="$1"

KERNEL_VERSION=""
CONFIG_FILE="/etc/modules.conf"

FSTAB="/etc/fstab"
ROOT_DEVICE=$(awk '/^[ \t]*[^#]/ { if ($2 == "/") { print $1; }}' $FSTAB)

SCSI_MODULES="`grep scsi_hostadapter $CONFIG_FILE | grep -v '^[    ]*#' | awk '{ print $3 }'`"
NEEDED_SCSI="scsi_mod sd_mod"

USB_MODULES="`grep usb-controller $CONFIG_FILE | grep -v '^[    ]*#' | awk '{ print $3 }'`"
NEEDED_USB="usbcore"

MODULES="$NEEDED_SCSI $SCSI_MODULES $NEEDED_USB $USB_MODULES"

IMAGE_SIZE=3000
MOUNT_IMAGE="/tmp/initrd.$$"
IMAGE="/tmp/initrd.img-$$"
MOUNT_POINT="/tmp/initrd.mnt-$$"
LINUXRC="$MOUNT_IMAGE/linuxrc"

# Check for initrd Directory

if ! [ -e /initrd ]
then
mkdir /initrd
fi

# Check for RAM Disk Device

if [ -e /dev/.devfsd ]
then
RAM_DEVICE="rd"
else
RAM_DEVICE="ram0"
fi

# Check for input

if [ "$TEMP" == "" ]
then
KERNEL_VERSION="`uname -r`"
else
KERNEL_VERSION="$TEMP"
fi

INITRD="/boot/initrd-$KERNEL_VERSION.img"

if [ "$TEMP" == "-h" ] || [ "$TEMP" == "--h" ] || [ "$TEMP" == "-help" ] || [ "$TEMP" == "--help" ]
then
echo "usage: mkinitrd kernel_version"
echo "     : mkinitrd will automatically determin kernel version"
exit 1
fi

# Creating LoopBack Device

dd if=/dev/zero of=$IMAGE bs=1k count=$IMAGE_SIZE 2> /dev/null

for device_number in 0 1 2 3 4 5 6 7 8
do
if losetup /dev/loop$device_number $IMAGE 2>/dev/null
then
break
fi
done

if [ "$device_number" = "8" ]
then
rm -rf $MOUNT_POINT $IMAGE
echo "All of your loopback devices are in use!" >&2
exit 1
fi

LOOP_DEVICE=/dev/loop$device_number

echo y | mke2fs $LOOP_DEVICE $IMAGE_SIZE > /dev/null 2> /dev/null

echo "Using loopback device $LOOP_DEVICE"

mkdir -p $MOUNT_POINT
mount -t ext2 $LOOP_DEVICE $MOUNT_POINT || {
     echo "Can't get a loopback device"
     exit 1
   }
# Creating Directories

mkdir -p $MOUNT_IMAGE
mkdir -p $MOUNT_IMAGE/lib
mkdir -p $MOUNT_IMAGE/bin
mkdir -p $MOUNT_IMAGE/etc
mkdir -p $MOUNT_IMAGE/dev
mkdir -p $MOUNT_IMAGE/proc
ln -s /bin $MOUNT_IMAGE/sbin

rm -rf $MOUNT_POINT/lost+found

# Copying Static Programs

cp -a /bin/busybox $MOUNT_IMAGE/bin/busybox
ln -s /bin/busybox $MOUNT_IMAGE/bin/echo
ln -s /bin/busybox $MOUNT_IMAGE/bin/mount
ln -s /bin/busybox $MOUNT_IMAGE/bin/modprobe
ln -s /bin/busybox $MOUNT_IMAGE/bin/mkdir
ln -s /bin/busybox $MOUNT_IMAGE/bin/sh
ln -s /bin/busybox $MOUNT_IMAGE/bin/umount
ln -s /bin/busybox $MOUNT_IMAGE/bin/insmod
ln -s /bin/busybox $MOUNT_IMAGE/bin/pivot_root
cp -a /etc/fstab $MOUNT_IMAGE/etc/fstab
cp -a /etc/modules.conf $MOUNT_IMAGE/etc/modules.conf

# Copying Modules

for MODULE in $MODULES
do
echo "$MODULE" | {
IFS=':' read module options
module=$module
options=$options
DIR_SEARCH1="`ls -1 /lib/modules/$KERNEL_VERSION/kernel/drivers`"
for DIR_1SEARCH in $DIR_SEARCH1
do
cp /lib/modules/$KERNEL_VERSION/kernel/drivers/$DIR_1SEARCH/$module.o $MOUNT_IMAGE/lib > /dev/null 2>&1
DIR_SEARCH2="`ls -1 /lib/modules/$KERNEL_VERSION/kernel/drivers/$DIR_1SEARCH`"
for DIR_2SEARCH in $DIR_SEARCH2
do
cp /lib/modules/$KERNEL_VERSION/kernel/drivers/$DIR_1SEARCH/$DIR_2SEARCH/$module.o $MOUNT_IMAGE/lib > /dev/null 2>&1
done
done
           }
done

for i in console null $RAM_DEVICE tty[1234]
do
cp -a /dev/$i $MOUNT_IMAGE/dev
done

# Creating linuxrc File

echo "#!/bin/sh" > $LINUXRC
echo "" >> $LINUXRC

echo "echo \"Initial RAMDISK Loading Starting...\"" >> $LINUXRC

for MODULE in $MODULES
do
echo "$MODULE" | {
IFS=':' read module
module=$module

echo "Loading module $module"
echo "insmod /lib/$module.o" >> $LINUXRC
}
done

echo "echo \"Initial RAMDISK Loading Completed...\"" >> $LINUXRC
echo "mkdir /new_root" >> $LINUXRC
echo "echo \"Mounting proc...\"" >> $LINUXRC
echo "mount -n -t proc none /proc" >> $LINUXRC
echo "echo 0x0100 > /proc/sys/kernel/real-root-dev" >> $LINUXRC
echo "echo \"Mounting real root dev...\"" >> $LINUXRC
echo "mount -n -o ro $ROOT_DEVICE /new_root" >> $LINUXRC
echo "umount /proc" >> $LINUXRC
echo "cd /new_root" >> $LINUXRC
echo "echo \"Running pivot_root...\"" >> $LINUXRC
echo "pivot_root . initrd" >> $LINUXRC
echo "if [ -c initrd/dev/.devfsd ]" >> $LINUXRC
echo "then" >> $LINUXRC
echo "echo \"Mounting devfs...\"" >> $LINUXRC
echo "mount -n -t devfs none dev" >> $LINUXRC
echo "fi" >> $LINUXRC
echo "if [ \$\$ = 1 ]" >> $LINUXRC
echo "then" >> $LINUXRC
echo "echo \"Running init...\"" >> $LINUXRC
echo "exec chroot . sbin/init dev/console 2>&1" >> $LINUXRC
echo "else" >> $LINUXRC
echo "echo \"Using bug circumvention for busybox...\"" >> $LINUXRC
echo "exec chroot . linuxrc dev/console 2>&1" >> $LINUXRC
echo "fi" >> $LINUXRC

chmod +x $LINUXRC

(cd $MOUNT_IMAGE; tar cf - .) | (cd $MOUNT_POINT; tar xf -)

umount $MOUNT_POINT
losetup -d $LOOP_DEVICE

gzip -9 < $IMAGE > $INITRD
rm -rf $MOUNT_IMAGE $MOUNT_POINT $IMAGE

lilo -v

---
initrd script

The following script needs to placed in /etc/rc.d/init.d.

You will then need to link it to rcsysinit.d.

It is recommended that this script be run right after
mountfs.

To link the script change to the /etc/rc.d/rcsysinit.d
directory and issue the following command.

ln -sf ../init.d/initrd S41initrd

#!/bin/bash
# Begin $rc_base/init.d/initrd

# Based on sysklogd script from LFS-3.1 and earlier.
# Rewritten by Gerard Beekmans  - gerard@linuxfromscratch.org

source /etc/sysconfig/rc
source $rc_functions

echo "Clearing Initial RAM Disk..."
if [ -e /initrd/dev/.devfsd ]
then
      umount /initrd/dev
   fi
   umount /initrd
   /sbin/blockdev --flushbufs /dev/ram0

# End $rc_base/init.d/initrd

---
For Lilo

In order to use the initrd.img file is to add the
following entry to you lilo.conf file.

initrd=/boot/initrd.img

So your lilo.conf should look something like this.

image=/boot/vmlinuz-2.4.18
label=test
initrd=/boot/initrd-2.4.18.img
read-only
append="root=/dev/ram0 init=/linuxrc rw"

If you are just testing. You should make a separate
entry in lilo.conf. This will still allow you to boot.

---
For Grub

In order to use the initrd.img file is to add the
following entry to you menu.lst file.

initrd /boot/initrd-2.4.18.img

So your menu.lst should look something like this.

title test
root (hd0,1)
kernel /boot/vmlinuz-2.4.18
initrd /boot/initrd-2.4.18.img

---
For Syslinux

In order to use the initrd.img file is to add the
following to syslinux.cfg file.

append root=/dev/ram0 initrd=initrd-2.4.18.img

So your syslinux.cfg should look something like this.

label test
kernel vmlinuz
append root=/dev/ram0 initrd=initrd.img

---
Mail suggestions to giffordj@linkline.com

New Version of this document can be viewed from
http://www.jg555.com/cvs
 楼主| 发表于 2005-3-8 21:48:24 | 显示全部楼层
继续:有2.6的内容。
AUTHOR:         Jim Gifford <lfs-hints at jg555.com>

DATE: 2004-06-20

LICENSE: GNU Free Documentation License Version 1.2

SYNOPSIS: initrd for LFS

DESCRIPTION: This hint will assist you in creating a initrd
for your LFS system

PREREQUISITES:  SCSI and USB Modules must be in modules.conf
Linux 2.4/2.6 built with modules.
Ram disk support compiled in
initrd selected
Root Filesystem must be compiled in
Busybox-1.00-pre10
HINT:

Introduction to Initial RAMDisk

This hint will help you configure an LFS system for Initial RAMDisk.
Which will allow you to add modules at start-up instead of compiling them
into the kernel.

The script will auto-detect all SCSI, IDE and USB modules and add them
to the initial ramdisk. It will also detect the root from the fstab file

The above items, upon research are best if configured into the kernel.
You can look at the help of each of the items for more information.

---
Assumptions Made in this document

I have made the following assumptions in this document.
Files have been downloaded.

---
Kernel Configuration for 2.4

You will need to make sure the following items are configured
in your kernel. With out these, the initrd will not work
properly.

Block devices  --->
<M> Loopback device support (or <*>)
<*> RAM disk support
(4096)   Default RAM disk size
  •    Initial RAM disk (initrd) support

    The root and initrd file systems must be compiled into the kernel.

    ---
    Kernel Configuration for 2.6

    You will need to make sure the following items are configured
    in your kernel. With out these, the initrd will not work
    properly.

    Device Drivers  --->
    Block devices  --->
    <M> Loopback device support (or <*>)
    <*> RAM disk support
    (4096)   Default RAM disk size
  •    Initial RAM disk (initrd) support

    The root and initrd file systems must be compiled into the kernel.

    ---
    File Systems

    The new script has 3 choices of file systems.
    ext2, ext3, and cramfs.

    ext2 and ext3 are the most common file systems
    in use, but the initrd is usually bigger.
    My initrd with ext3 was only 412k. Compressed with
    gzip -9

    ---
    Needed Programs

    busybox 1.00-pre10
    ----

    Download From
    http://busybox.net/downloads/busybox-1.00-pre10.tar.bz2

    Information
    http://busybox.net

    Busybox has changed the way the configure the shell. It now
    uses a menu driven option very similar to make menuconfig
    in linux.

    Here is the list of the options needed. Anything else
    will add to the size of your initrd.

    General Configuration --->
  • Support for devfs
    NOTE - only if you using devfs
    Build Options  --->
  • Build BusyBox as a static binary (no shared libs)
    Coreutils  --->
  • echo (basic SUSv3 version taking no options
    Linux Module Utilities  --->
  • insmod
  •      Support version 2.1.x to 2.4.x Linux kernels
    NOTE - only if your using a 2.4 kernel
  •      Support version 2.6.x Linux kernels
    NOTE - only if your using a 2.6 kernel
    Another Bourne-like Shell  --->
  •      Optimize for size instead of speed
  •      Enable alias support
    (0) history size
    Linux System Utilities  --->
  • pivot_root
  • mount

    The build size on my system was 502k, considerably smaller than
    bash.

    After running make menuconfig you will need to run the
    following commands.

    make
    cp busybox /bin/busybox.static

    ---
    mkinitrd

    For those who do not want to type out the script. It is
    available on my CVS server at
    http://svn.jg555.com/viewcvs.cgi ... =1&root=scripts

    This script will create the initial RAM Disk image file.
    By default this script creates /boot/initrd-{kernelversion}.img

    I have sent a mkinitrd file to be placed
    in the hints attachments at
    http://www.linuxfromscratch.org/hints/downloads/attachments.

    The default location for this file is /sbin

    There are options on the new script, it will not just create
    a initrd anymore. The kernel_version= is the only mandatory
    option

    Options are the following:

    Required
            kernel_version={version} = use kernel version

    Optional
    -ide = remove ide modules [-scsi = remove scsi modules]
            -usb = remove usb modules [-cdrom = remove cdrom modules]
    -ide-scsi = remove ide-scsi modules
    -devfs = remove devfs settings from initrd
    initrdfs={ext2|ext3} = use either ext2 or ext3
    -module={module} = remove module
    +module={module} - add module
            root-device={device} - skips auto detection of the root device
    order={scsi,ide,usb,added} - sets the order of modules to be loaded
                                                                                                            
    ---
    initrd script

    The following script needs to placed in /etc/rc.d/init.d.

    You will then need to link it to rcsysinit.d.

    It is recommended that this script be run right after
    mountfs.

    To link the script change to the /etc/rc.d/rcsysinit.d
    directory and issue the following command.

    ln -sf ../init.d/initrd S41initrd

    #!/bin/sh
    # Begin $rc_base/init.d/initrd

    # Based on sysklogd script from LFS-3.1 and earlier.
    # Rewritten by Gerard Beekmans  - gerard@linuxfromscratch.org

    source /etc/sysconfig/rc
    source $rc_functions

    case "$1" in
    start)
    if [ -e /initrd/dev/.devfsd ]
    then
    umount /initrd/dev
    fi

    if [ -e /initrd/proc ]
    then
    umount /initrd/proc
    fi

    if [ -e /initrd/sys ]
    then
    umount /initrd/sys
    fi

    if [ -e /initrd/linuxrc ]
    then
    umount /initrd
    echo "Clearing Initial RAM Disk..."
    blockdev --flushbufs /dev/ram0
    evaluate_retval
    fi
    ;;
    *)
    echo "Usage: $0 {start}"
    exit 1
    ;;
    esac

    # End $rc_base/init.d/initrd

    ---
    For Lilo

    In order to use the initrd.img file is to add the
    following entry to you lilo.conf file.

    initrd=/boot/initrd.img

    So your lilo.conf should look something like this.

    image=/boot/vmlinuz-2.4.23
    label=test
    initrd=/boot/initrd-2.4.23.img
    read-only

    If you are just testing. You should make a separate
    entry in lilo.conf. This will still allow you to boot.

    ---
    For Grub

    In order to use the initrd.img file is to add the
    following entry to you menu.lst file.

    initrd /boot/initrd-2.4.23.img

    So your menu.lst should look something like this.

    title test
    kernel (hd0,1)/boot/vmlinuz-2.4.23
    initrd (hd0,1)/boot/initrd-2.4.23.img

    ---
    For Syslinux

    In order to use the initrd.img file is to add the
    following to syslinux.cfg file.

    append initrd=initrd-2.4.23.img

    So your syslinux.cfg should look something like this.

    label test
    kernel vmlinuz
    append initrd=initrd.img

    ---

    VERSION:        2.11

    CHANGELOG:     2.11 Forgot to update the mkinitrd svn information
    2.10 Version Updates and CVS to SVN Information
    2.9 Fixes Typos
    2.8 Updated initrd script and mkinitrd
    2.7 Updated Configurations
    2.6 More 2.6 Updates -- removed romfs
    2.5 Updated for 2.6 Kernel
    2.4 Added a choice of the Change_Root Method
        and the pivot_root method.
    2.3 Fixed Typos
    2.2 Fixed Typos
    2.1 Forget at add genromfs build information
    2.0 Did more Research - Found easier way to
        do things and smaller.
    1.5 Update CVS Information
    1.4 Updated to New Hint Format
                    1.3 Updated Script
                    1.2 Fixed Typos
                    1.1 Updated Script
                    1.0 Initial Version

    New Version of this document can be viewed from http://svn.jg555.com/viewcvs.cgi/?root=lfs-hints
  • 回复 支持 反对

    使用道具 举报

     楼主| 发表于 2005-3-8 21:54:16 | 显示全部楼层
    回复 支持 反对

    使用道具 举报

    发表于 2005-3-9 16:30:10 | 显示全部楼层
    没看懂..
    还是不知道是怎么做的..
    回复 支持 反对

    使用道具 举报

    发表于 2005-3-9 16:37:47 | 显示全部楼层
    说一下大致原理吧,,
    看了半天, 还是不知道那个脚本是什么来着
    回复 支持 反对

    使用道具 举报

    发表于 2005-3-9 17:56:31 | 显示全部楼层
    man initrd
    /usr/src/linux/Documentation/initrd.txt
    在看看这些就明白了。
    linuxrc就相当于init

    不过从initrd切换到根文件系统上,不太明白
    回复 支持 反对

    使用道具 举报

    发表于 2005-3-9 21:01:57 | 显示全部楼层
    好文章啊!!
    回复 支持 反对

    使用道具 举报

     楼主| 发表于 2005-3-10 00:29:59 | 显示全部楼层
    Post by 6692975

    不过从initrd切换到根文件系统上,不太明白

    initrd.img以RAMdisk运行,加载EXT3模块,mount根文件系统,然后再卸载initrd.img。
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    快速回复 返回顶部 返回列表