lintel 发表于 2010-6-9 23:43

【技巧】在openwrt下使用kexec启动硬盘上的linux系统。

本帖最后由 lintel 于 2010-6-10 00:00 编辑

在开始之前,必须了解以下资料:

         kexec 是 Linux 内核的一个特性,让您可以从当前正在运行的内核直接引导到一个新内核而不必通过引导装载程序。
                                                                                                                                                         ----linux内核开发档的说明
         Kexec 有两个组件。第一个是用户空间组件,叫做“kexec-tools”。第二个是真正的内核支持代码。这两部分实现 kexec 的两个主要操作:将新内核装载到内存并重新启动到它。可以容易地获得一个启用 kexec 的内核。只需要下载 kexec-tools 包和特定内核的补丁,编译 kexec-tools 包以得到 kexec工具,并将特定内核的补丁加入到内核树中并重装启动到它。当然,您在编译内核时要确保选中KEXE CALL项。2.6.13内核开始,kexec被正式支持。

         在最近一次更新的openwrt的内核上,已经编译支持了Kexec。这意味着可以在硬盘或者U盘上启动openwrt(不受jffs空间限制,以及opkg-link),debian等常规的发行版linux系统或者特殊的KELF文件

开始Kexec切换内核之前,必须确认内核支持了Kexec,并且安装了kexec-tools。没有的话,请使用opkg命令安装。

下面是默认的帮助:

root@MGB100:/# kexec
No kernel specified
kexec-tools 2.0.1 released 13th August 2009
Usage: kexec ...
Directly reboot into a new kernel
-h, --help         Print this help.
-v, --version      Print the version of kexec.
-f, --force          Force an immediate kexec,
                      don't call shutdown.
-x, --no-ifdown      Don't bring down network interfaces.
                      (if used, must be last option
                     specified)
-l, --load         Load the new kernel into the
                      current kernel.
-p, --load-panic   Load the new kernel for use on panic.
-u, --unload         Unload the current kexec target kernel.
                      If capture kernel is being unloaded
                      specify -p with -u.
-e, --exec         Execute a currently loaded kernel.
-t, --type=TYPE      Specify the new kernel is of this type.
   --mem-min=<addr> Specify the lowest memory address to
                      load code into.
   --mem-max=<addr> Specify the highest memory address to
                      load code into.
   --reuseinitrd    Reuse initrd from first boot.
   --load-preserve-context Load the new kernel and preserve
                      context of current kernel during kexec.
   --load-jump-back-helper Load a helper image to jump back
                      to original kernel.
Supported kernel file types and options:
multiboot-x86
    --command-line=STRING      Set the kernel command line to STRING.
    --reuse-cmdline            Use kernel command line from running system.
    --module="MOD arg1 arg2..."Load module MOD with command-line "arg1..."
                                 (can be used multiple times).
elf-x86
    --command-line=STRING Set the kernel command line to STRING
    --append=STRING       Set the kernel command line to STRING
    --reuse-cmdline       Use kernel command line from running system.
    --initrd=FILE         Use FILE as the kernel's initial ramdisk.
    --ramdisk=FILE      Use FILE as the kernel's initial ramdisk.
    --args-linux          Pass linux kernel style options
    --args-elf            Pass elf boot notes
bzImage
-d, --debug               Enable debugging to help spot a failure.
    --real-mode         Use the kernels real mode entry point.
    --command-line=STRING Set the kernel command line to STRING.
    --append=STRING       Set the kernel command line to STRING.
    --reuse-cmdline       Use kernel command line from running system.
    --initrd=FILE         Use FILE as the kernel's initial ramdisk.
    --ramdisk=FILE      Use FILE as the kernel's initial ramdisk.
beoboot-x86
-d, --debug               Enable debugging to help spot a failure.
    --real-mode         Use the kernels real mode entry point.
nbi-x86
Architecture options:
   --reset-vga               Attempt to reset a standard vga device
   --serial=<port>         Specify the serial port for debug output
   --serial-baud=<baud_rate> Specify the serial port baud rate
   --console-vga             Enable the vga console
   --console-serial          Enable the serial console
   --elf32-core-headers      Prepare core headers in ELF32 format
   --elf64-core-headers      Prepare core headers in ELF64 format

E文比较好的兄弟一眼就可以看出来了。怎么样,这个工具是不是很强大?!

E文不好的兄弟参考下面简单的中文说明:


-l                         载入内核镜像
–command-line   内核启动命令
–initrd                载入initrd镜像
-e                     执行重载内核
--append            替换原有的内核启动命令

我要启动的内核镜像是 bzImage, 而roofs分区是 hda2,initrd是nitrd.img-2.6.32.8, 那么可以这么写:(下面使用 root 用户)

kexec -l bzImage --append="console=ttyS0,38400 rootfstype=ext3 root=/dev/hda2rw"--serial=ttyS0--serial-baud=38400--console-serial   --initrd=initrd.img-2.6.32.8


完成后,就可以使用下面的命令启动你的新内核了。


kexe -e



#载入内核
root@~#kexec -l bzImage --append="console=ttyS0,38400 rootfstype=ext3 root=/dev/hda2rw"--serial=ttyS0--serial-baud=38400--console-serial   --initrd=initrd.img-2.6.32.8

# 执行 kexec 启动内核
root@~# kexec -e
br-lan: port 1(eth1) entering disabled state
kexecStarting new kernel
I'm in purgatory
early_serial_init...ok!

MGB100 Linux 2.6.32 by Lintel
Uncompressing Linux...Done,
booting Kernel!
。。。省略。







下面是修改版的openwrt,可以在硬盘启动的。




解压,然后复制到盒子的硬盘上,bzImage是内核,openwrt.tar是roofs文件。

参考(hda2是我准备安装openwrt的分区,具体根据实际情况。):

cp bzImage /mnt/hda2/
tar -xvf openwrt.tar -C /mnt/hda2

启动命令在hddboot里面,仅供参考。


启动后的文件系统状态:

root@MGB100:~# mount
rootfs on / type rootfs (rw)
/dev/root on / type ext3 (rw,relatime,errors=continue,data=writeback)
proc on /proc type proc (rw,relatime)
sysfs on /sys type sysfs (rw,relatime)
tmpfs on /tmp type tmpfs (rw,nosuid,nodev,relatime,size=15304704,mode=1777)
tmpfs on /dev type tmpfs (rw,relatime,size=512K)
devpts on /dev/pts type devpts (rw,relatime,mode=600)
debugfs on /sys/kernel/debug type debugfs (rw,relatime)
/dev/hda3 on /home type ext3 (rw,sync,relatime,errors=continue,data=writeback)
none on /proc/bus/usb type usbfs (rw,relatime)

root@MGB100:~# df -h
Filesystem                Size      Used Available Use% Mounted on
/dev/root               1.8G   53.7M      1.7G   3% /
/dev/hda3                52.7G      9.6G   40.4G19% /home

root@MGB100:~# fdisk -l
Disk /dev/hda: 60.0 GB, 60011642880 bytes
16 heads, 63 sectors/track, 116280 cylinders
Units = cylinders of 1008 * 512 = 516096 bytes
Disk identifier: 0x4e5e747a
   Device Boot      Start         End      Blocks   IdSystem
/dev/hda1               1         993      500440+82Linux swap / Solaris
/dev/hda2   *         994      4868   1953000   83Linux
/dev/hda3            4869      116280    56151648   83Linux

root@MGB100:~# free
            total         used         free       shared      buffers
Mem:      29892      28704         1188            0         2120
Swap:       500432         2220       498212
Total:       530324      30924       499400




启动debian的参考命令:
kexec -l /mnt/hda2/boot/bzImage --append="console=ttyS0,38400 rootfstype=ext3 root=/dev/hda2rw"--serial=ttyS0--serial-baud=38400--console-serial   --initrd=/mnt/hda2/boot/initrd.img-2.6.32.8
盒子原有的debian会在近期更新,敬请关注。

qiuqiu3 发表于 2010-6-10 09:44

帅呆了:victory:

hackerxxs 发表于 2010-6-10 16:18

楼主好强大啊
前天刚跟我说完
现在就上帖子了
页: [1]
查看完整版本: 【技巧】在openwrt下使用kexec启动硬盘上的linux系统。