3. 构建内核

首先,为客户端构建一个内核。我建议您在服务器上构建它,这将对稍后安装模块很有用。使用 zImage 以减小其大小。包含您需要的一切,但尽量使用尽可能多的模块,因为许多 BOOTP 客户端实现无法加载非常大的内核(至少在 intel x86 架构上)。还要包含 iramdisk 支持、NFS 协议支持、NFS 上的根文件系统支持、对您的 NIC 的支持、通过 BOOTP 的内核级 IP 自动配置;不要为这些使用模块! 然后,如果您计划为多个客户端使用相同的远程根文件系统,请添加对 ext2fs 或其他一些文件系统和 ramdisk 的支持(16 兆字节的 ramdisk 在大多数系统上都可以正常工作)。然后您可以像往常一样修改内核参数(有关此主题的信息,请参阅 BootPrompt-HOWTO),但稍后您将有另一个机会修改内核参数。

然后,如果您计划使用 BOOTP,请将内核 zImage 复制到服务器上。我们假设它位于/tftpboot,其名称为 zImage,您要从此 zImage 为 BOOTP 操作创建的镜像名称为 kernel,并且 nfs 根文件系统将位于/nfsroot.

在服务器上执行以下命令(应安装 mknbi 包)
      # cd /tftpboot
      # chmod 0555 zImage
      # chown root:root zImage
      # mknbi-linux zImage --output=kernel --rootdir=/nfsroot
    

如果您使用的是 LanWorks EPROM,还要执行以下命令(您需要 imggen 实用程序)
      # mv -f kernel tmpkernel
      # imggen -a tmpkernel kernel
      # rm -f tmpkernel
    

您的内核已准备好用于 BOOTP/DHCP/ROM 操作。当然,如果您计划使用本地驱动器,则无需执行此操作。

3.1. 当根文件系统位于 ramdisk 上时

可以使用 ramdisk 作为根文件系统。在这种情况下,用于修改内核二进制镜像的命令略有不同。如果您选择这样做,则必须启用对初始 ramdisk (initrd) 的支持,并且您可能不需要 NFS 支持,或者您可以将其编译为模块。

现在是概述在使用 initrd 时会发生什么的时候了。有关此的完整文档在您的内核源代码树中,位于Documentation/initrd.txt文件中。我必须警告您,我从未尝试过这个 :)。

当启用 initrd 时,引导加载程序首先将内核和初始 ramdisk 加载到内存中。然后,ramdisk 以读写方式挂载为根文件系统。内核查找/linuxrc文件(二进制可执行文件或以 #! 开头的脚本)。当/linuxrc终止时,传统的根文件系统被挂载为/,并执行通常的引导序列。因此,如果您想完全从 ramdisk 运行您的机器,您只需创建一个从/linuxrc/sbin/init的链接,或者在那里编写一个 shell 脚本来执行您喜欢的任何操作,然后关闭计算机。

内核编译完成后,您必须为您的安装构建一个根文件系统。这在“客户端设置,创建根文件系统”部分中进行了解释。我在此假设这已经完成,并且客户端的根文件系统暂时位于/tmp/rootfs。现在您必须创建一个 ramdisk 镜像。一个简单的方法如下

将 ramdisk 镜像保存到某个文件并释放它

上面关于 LanWorks PROM 的内容也适用于您使用 initrd 的情况。然后,您必须使用 mknbi-linux 实用程序修改内核镜像,如上所述。尽管如此,它的调用会与上面的略有不同(我将假设您刚刚编译的 zImage 位于/tftpboot/zImage,而您的初始 ramdisk 镜像位于):
        # cd /tftpboot
        # chmod 0555 zImage
        # chown root:root zImage
	# rdev zImage /dev/ram0
        # mknbi-linux zImage --output=kernel --rootdir=/dev/ram0 /tmp/initrd