r7 - 23 Feb 2007 - 06:09:50 - BenGreenYou are here: TWiki >  Ltsp Web  > BootingFromLocalDevice

Booting from Local Device

This page is for people to post links to articles about booting a thin client from a local device, such as a flash disk, cdrom or hard drive.

Boot from Flash

How it all works

In a normal linux system when an app needs a file the system checks to see if the file is in cache. If it is, good, it's used. If not drivers are tasked to read the file into cache and the app continues.

The magic that Linus et al achieved, when starting to boot a system, is to load the cache with a complete file system. All cache requests will be satisfied. The code is the basis of a normal running system, so is very well checked.

This is called an initramfs. It looks like a ram disk, can use all the memory as it grows, so grow it carefully, but it uses no drivers to access the files.

Refer to Documentation/filesystems/initramfs.txt in a current kernel source directory. This may also be informative http://tigger.ws/wiki/index.php/InitRamFs

LTSP nfs mounts, as Read-Only, the shared file system bits and uses the native ramfs for the /tmp /var etc bits in the initramfs.

The flash LTSP implementation uses the same strategy, mounting a local flash file system into the ramfs instead of nfs mounts. The root file system is mounted Read-Only so it can't wear or be damaged by power-downs or by malicious code.

Introduction

I created a complete flash client around ltsp. I installed my system on an ebox-2300 with 256M flash.

I did a few things to suit me, and have documented what I did, not what I should have done. I left out all the printer stuff, to save a tiny bit of space I left out the modules and mod_tools as well as the zoneinfo data base and terminfo (except for linux) database.

I expect that others using this howto will rectify my omissions. When I started this document would have helped me lots. I hope others will find it helps them.

The Recipe

See the listings at the end for the files used, changed etc.

Create a working Directory on a system that you have installed ltsp on. LBE and make packages could just as well be used. I called mine Black-Box because of the ebox-2300 appearence.

In Black-Box create a ltsp_kernel_kit directory. http://ltsp.mirrors.tds.net/pub/ltsp/utils/ltsp_kernel_kit_4.2u3.tgz

Create a kernel source tree: I used 2.6.17.8.

Create extra with a mirror of any files you want to change and include.

Create an executable build_embedded_root

In the kernel directory (linux-2.6.17.8) copy ../ltsp_kernel_kit/config-2.6.17.8-ltsp-1 to .config

make oldconfig

Now configure your kernel to NOT use modules, to include the drivers for your hardware and to include ide drivers. make xconfig or make menuconfig whatever

make

Copy arch/i386/boot/bzImage to ../extra/boot/bzImage

Change build_initramfs to not reference any modules. Change initramfs/init to mount the flash. (listings) Make a dev/hda1 entry in initramfs/dev (mknod hda1 b 3 1)

In ltsp_kernel_kit run build_initramfs and copy /tmp/initramfs-bla.gz to extra/boot/initramfs.gz

Populate extra with the things you want eg I put in menu.lst ssh leys and changed etc/inittab.base to include ssh, rc.earlysysinit and rc.sysinit to do what was required (listings)

I want to be able to backup the whole directory so I copied /opt/ltsp/pkg_cache to my Black-Box directory as opt/ltsp/pkg_cache.

Run build_embedded_root after modifying it to copy the timezone of your choice to etc/localtime before zoneinfo is rtemoved. Note my build_embedded_root does not prune the terminfo database. I did that by hand.

Note that any files in extra that map to sym-links in the real root system must be removed, else your copy end up in the sym-link and may not exist. eg ensure etc/localtime is a file not a link to zoneinfo which gets removed.

When build_embedded_root completes i386 is an image of the flash root file system that you want. It has also copied extra into place, and made a tar image in /tmp/flash.tar

Boot the target using knoppix. I used 5.1.1 and because the ebox-2300 has only 128M ram I booted in text mode (knoppix 2)

prepare your flash eg

fdisk /dev/hda

mkfs.ext2 /dev/hda1

mount it

mount /dev/hda1 /mnt

cd /mnt

ssh jam@tigger.ws cat /tmp/flash.tar |tar xvf -

and install grub

grub-install --root-directory=/mnt /dev/hda

This works on 5.1.1 fails on earlier versions as /dev/hda is really /dev/ide/host0/target0/lun0/part and grub gets multiply confused.

You can now boot your thin client!

Files in extra

etc/  init*  mnt/  root/  sbin/  usr/  var/

./etc:
inittab.base  localtime  lts.conf  rc.d/  rc.sysinit*  ssh/

./etc/rc.d:
nets*

./etc/ssh:
ssh_host_dsa_key      ssh_host_key      ssh_host_rsa_key
ssh_host_dsa_key.pub  ssh_host_key.pub  ssh_host_rsa_key.pub

./mnt:

./root:
.bash_history  .bash_profile  .bashrc  .ssh/

./root/.ssh:
authorized_keys  id_rsa  id_rsa.pub

./usr:
share/

./usr/share:
i18n/  terminfo/

./usr/share/i18n:
locale/

./usr/share/i18n/locale:
en_US

./usr/share/terminfo:
l/

./usr/share/terminfo/l:
linux

./var:

build_initramfs

#!/bin/bash

PKGVER=2.2
REL=0
PKGFORMAT=0.5

CURDIR=`pwd`
PROMPT="y"
CFG_FILE=config.in

[ -f ${CFG_FILE} ] && . ${CFG_FILE}

KERNEL_SRC=${KERNEL_SRC:-/usr/src/linux-2.6.17.3}
LTSP_TREE=${LTSP_TREE:-/opt/ltsp-4.2}
TFTP_DIR=${TFTP_DIR:-/tftpboot/lts}

MODULE_DEST=/tmp/initramfs.d/lib/modules

#===============================================================================
#
# Functions for prompting the user 
# "Borrowed" from the pcmcia-cs Config script
#
No Changes till
#===============================================================================
#
# Save the answers to make it easier next time
#

echo "#"                                                           >${CFG_FILE}
echo "# config file for LTSP kernel build script (Jim McQuillan)" >>${CFG_FILE}
echo "#"                                                          >>${CFG_FILE}
echo "KERNEL_SRC=${KERNEL_SRC}"                                   >>${CFG_FILE}
echo "LTSP_TREE=${LTSP_TREE}"                                     >>${CFG_FILE}
echo "TFTP_DIR=${TFTP_DIR}"                                       >>${CFG_FILE}

#=========================================================================
#
# Now, calculate some settings
#

for TAG in VERSION PATCHLEVEL SUBLEVEL EXTRAVERSION; do
    eval `sed -ne "/^$TAG/s/[   ]//gp" ${KERNEL_SRC}/Makefile`
done

KERNEL_VER=${VERSION}.${PATCHLEVEL}.${SUBLEVEL}${EXTRAVERSION}

KERNEL_IMG=${KERNEL_SRC}/arch/i386/boot/bzImage
SYSTEM_MAP=${KERNEL_SRC}/System.map

INITRAMFS_IMG=initramfs.ltsp

#=========================================================================
#
# Make sure we have a kernel
#
echo "#####################################################################"
echo ${KERNEL_IMG}
echo
if [ ! -f ${KERNEL_IMG} ]; then
    echo ""
    echo "Kernel not found at: ${KERNEL_IMG}"
    echo ""
    exit 1
fi

#=========================================================================
#
# Setup the temporary location where we insert the kernel modules into
# the initramfs tree.
#

[ -d /tmp/initramfs.d ] && rm -rf /tmp/initramfs.d

mkdir /tmp/initramfs.d

cd initramfs
find ./ -print | cpio -pmud /tmp/initramfs.d
cd ..
  

#=========================================================================
#
# Take the initramfs tree and cpio it into a single file, and gzip it
#

echo "cpio'ing and gzipping the initramfs tree"

cd /tmp/initramfs.d
find ./ -print | cpio -o -H newc | gzip -9 >/tmp/initramfs-${KERNEL_VER}.gz

echo 
echo "finished !"
echo

build_embedded_root

#! /bin/sh
echo "===================== rm -fr i386"
rm -fr i386

echo "====== installing files into i386"
tar xzf opt/ltsp/pkg_cache/ltsp-glibc-1.0-1-i386.tgz
tar xzf opt/ltsp/pkg_cache/ltsp-ltsptree-1.17-0-i386.tgz
tar xzf opt/ltsp/pkg_cache/ltsp-bash-1.1-0-i386.tgz
tar xzf opt/ltsp/pkg_cache/ltsp-busybox-1.1-0-i386.tgz
tar xzf opt/ltsp/pkg_cache/ltsp-udev-1.0-0-i386.tgz
tar xzf opt/ltsp/pkg_cache/ltsp-udev-rules-1.5-0-i386.tgz
tar xzf opt/ltsp/pkg_cache/ltsp-ncurses-1.1-0-i386.tgz
tar xzf opt/ltsp/pkg_cache/ltsp-getltscfg-1.3-0-i386.tgz
tar xzf opt/ltsp/pkg_cache/ltsp-ssh-1.1-0-i386.tgz 
tar xzf opt/ltsp/pkg_cache/ltsp-popt-1.2-0-i386.tgz
tar xzf opt/ltsp/pkg_cache/ltsp-sysvinit-1.1-0-i386.tgz
tar xzf opt/ltsp/pkg_cache/ltsp-ltspinfod-1.2-0-i386.tgz
tar xzf opt/ltsp/pkg_cache/ltsp-e2fsprogs-1.2-0-i386.tgz
tar xzf opt/ltsp/pkg_cache/ltsp-zlib-1.0-1-i386.tgz
tar xzf opt/ltsp/pkg_cache/ltsp-startsess-1.2-0-i386.tgz
tar xzf opt/ltsp/pkg_cache/ltsp-util-linux-1.1-0-i386.tgz
Add the files you want

cd i386
chmod 755 *
chmod 555 proc
chmod 1777 tmp

echo "=================== rmdir oldroot"
rmdir oldroot

echo "================ rm etc/localtime"
rm etc/localtime

echo "======= rm -fr usr/share/zoneinfo"
rm -fr usr/share/zoneinfo

echo "=========== rm -fr usr/share/i18n"
rm -fr usr/share/i18n/*

echo "========= rm -fr usr/share/locale"
rm -fr usr/share/locale

echo "======= rm -fr usr/share/terminfo"
rm -fr usr/share/terminfo/*

echo "======= find . |cpio -pdv ../i386"
cd ../extra
find . |cpio -pd ../i386

echo "========== tar to /tmp/flash.tar"
cd ../i386
tar cf /tmp/flash.tar *

init

#!/bin/sh
#
# init script for initramfs (Initial ram filesystem) for LTSP
#
# Copyright (C) 2005 James A. McQuillan 
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

INITRD_DBG=0

echo "========================================================================="
echo "Running /init"

echo "Mounting /proc"
mount -t proc /proc /proc

[ "${INITRD_DBG}" = "1" ] && exec /bin/sh

echo "Creating new ramdisk to hold our root fs..."
mkdir /newroot

mount -n -t ramfs none /newroot

mkdir /newroot/ideroot

echo "Mounting root filesystem:"
mount -r /dev/hda1 /newroot/ideroot

[ "${INITRD_DBG}" = "2" ] && exec /bin/sh

echo "Setting up the new root ramdisk area..."

#
# Create the directories on our new root filesystem that should NOT
# come from the IDE filesystem that we mount
#
for i in dev home mnt oldroot proc sys tmp var; do
  mkdir /newroot/$i
done

#
# Create symlinks to the items we are need from the IDE mounted filesystem
#
for i in bin etc lib libexec root sbin share usr; do
  ln -s /ideroot/$i   /newroot/$i
done

umount /proc

[ "${INITRD_DBG}" = "3" ] && exec /bin/sh

echo "Doing the switchroot"
exec /sbin/switchroot /newroot

echo "Hmm, switchroot must have failed!!!!"

exit

inittab.base

#
# Copyright (c) 2002 by James A. McQuillan (McQuillan Systems, LLC)
#
# This software is licensed under the Gnu General Public License.
# The full text of which can be found at http://www.LTSP.org/license.txt
#
id:5:initdefault:
si::sysinit:/etc/rc.sysinit

c:345:once:/sbin/sshd

l:5:respawn:/etc/run_ltspinfod
s:0:wait:/bin/sh /etc/rc.shutdown
r:6:wait:/bin/sh /etc/rc.reboot

nets

#!/bin/bash

echo $0
/sbin/ifconfig eth0 ${MY_IP}

menu.lst

default=0
timeout=0
title ThinClient
        root (hd0,0)
        kernel /bzImage ro root=/dev/hda1
        initrd /initramfs.gz

rc.earlysysinit

#!/bin/bash
#
# This script runs AFTER the pivot_root, but BEFORE init runs.
# The primary purpose of this script it to create an /etc/inittab file
# based on entries found in the lts.conf file.
#

PATH=/bin:$PATH; export PATH

cd /

#==============================================================================
#
# We need to do this udev stuff here in the initram, because we need to have
# the device nodes created BEFORE we run /sbin/init. Otherwise, we won't see
# any of any output from our "echo" statements in the /etc/rc.sysinit script.
#

echo "Mounting /sys..."
mount -n -t sysfs none /sys

echo "Mounting /proc..."
mount -n -t proc none /proc

mknod /dev/console c 5 1
mknod /dev/null    c 1 3

echo "Starting udevd..."
/sbin/udevd --daemon

echo "Running udevstart to create initial device nodes..."
/sbin/udevstart

ln -snf /proc/self/fd    /dev/fd
ln -snf /proc/self/fd/0  /dev/stdin
ln -snf /proc/self/fd/1  /dev/stdout
ln -snf /proc/self/fd/2  /dev/stderr
ln -snf /proc/kcore      /dev/core

echo "Mounting devpts..."
mkdir /dev/pts

mount -t devpts devpts /dev/pts

echo "Building /etc/inittab"

eval `/bin/getltscfg -a`

#==============================================================================
# Start with the basic inittab file
#
echo "Creating ramdisk on /tmp"
RAMDISK_SIZE=${RAMDISK_SIZE:-"1024"}
/sbin/mke2fs -q -m0 /dev/rd/0 ${RAMDISK_SIZE}
/bin/mount -n /dev/rd/0 /tmp

cat /etc/inittab.base >/tmp/inittab

#
# Add the SCREEN entries
#
for (( SCREEN=1; SCREEN <= 12; SCREEN++ )); do
  SCREENOPT=`printf "SCREEN_%02d" ${SCREEN}`
  if [ -n "${!SCREENOPT}" ]; then
    echo "s${SCREEN}:5:respawn:/bin/startsess tty${SCREEN} /etc/screen_session"\
             >>/tmp/inittab
  fi
done

echo "Done with early_sysinit"

rc.sysinit

#!/bin/sh
#
# rc.sysinit
#

#==============================================================================
# This script will setup the environment for a diskless workstation, as
# part of the Linux Terminal Server Project (http://www.LTSP.org)
#
PATH=/bin:$PATH; export PATH
. /etc/ltsp_functions

eval `/bin/getltscfg -a`

#==============================================================================
# A place to store information that is retrieved by ltspinfod
#
mkdir /tmp/info

#==============================================================================
# Get the IP address of the default server.  This is used for XDM_SERVER,
# TELNET_HOST and SYSLOG_HOST if any of them are not set explicitly.
# Default to '192.168.0.254' if it is NOT set in the config file.
#
DEFAULT_SERVER=${SERVER:-"192.168.0.254"}
reg_info DEFAULT_SERVER

NFS_SERVER=${NFS_SERVER:-${DEFAULT_SERVER}}
reg_info NFS_SERVER

#==============================================================================
# Setup hostname
#
hostname ${HOSTNAME}
echo "Current hostname: ${HOSTNAME}"
reg_info HOSTNAME

>/tmp/mtab
echo "/dev/hda1     /ideroot    ext2     ro        1 1" >/tmp/fstab

################################################################################
#
# Setup USB modules
#
echo "Checking for USB host controller..."
for MODULE in ehci-hcd uhci-hcd ohci-hcd; do
  modprobe $MODULE >/dev/null 2>&1
done

echo "Checking for USB keyboard and mouse..."
for MODULE in input usbmouse usbkbd; do
  modprobe ${MODULE} >/dev/null 2>&1
done

mount -n -t usbfs none /proc/bus/usb

################################################################################
#
# Setup the resolv.conf file
#

if [ "${SEARCH_DOMAIN}" != "" ]; then
    echo "search ${SEARCH_DOMAIN}"   >/tmp/resolv.conf
fi

DNS_SERVER=${DNS_SERVER:-${DEFAULT_SERVER}}
echo "nameserver ${DNS_SERVER}"   >>/tmp/resolv.conf
reg_info DNS_SERVER

#==============================================================================
#
# Mount filesystems
#

echo "Setting up loopback device"
ifconfig lo 127.0.0.1 netmask 255.0.0.0 broadcast 127.255.255.255

echo "Setting up /var"
mkdir   /tmp/var
mkdir   /var/run
mkdir   /var/log
mkdir   /var/lock
mkdir   /var/lock/subsys
mkdir   /var/lib

chmod 0777 /tmp

mkdir   /tmp/mnt

mkdir   /tmp/.privsep
chown 0:0  /tmp/.privsep
chmod 0700 /tmp/.privsep

#==============================================================================
#
# Check the hostname
#
IPADDR=`getipaddr`
echo "127.0.0.1   localhost"      >/tmp/hosts
echo "${IPADDR}   ${HOSTNAME}"   >>/tmp/hosts
echo "${DEFAULT_SERVER} server"  >>/tmp/hosts


#==============================================================================
#
# Start the syslog daemon
#
SYSLOG_HOST=${SYSLOG_HOST:-${DEFAULT_SERVER}}
reg_info SYSLOG_HOST
echo "Starting syslogd"
#syslog.conf not used
#echo "*.* @${SYSLOG_HOST}" >/tmp/syslog.conf
#syslogd -m 60 -R ${SYSLOG_HOST}
syslogd -m 60 -L
dmesg | logger

#==============================================================================
#
# Run the additional rc files.
# These are to make it easier to integrate additional functionality
# into an ltsp system.  Add your scripts to etc/rc.d, and put the name
# of the script in the lts.conf file, and it will be executed.
#

for (( RCNUM=1; RCNUM<=10; RCNUM++)); do
    RCVAR=`printf "RCFILE_%02d" ${RCNUM}`
    RCFILE=${!RCVAR}
    if [ -n "${RCFILE}" ]; then
        reg_info ${RCVAR}
        if [ -x /etc/rc.d/${RCFILE} ]; then
            /etc/rc.d/${RCFILE}
        else
            echo
            echo "  ERROR: RCFILE_${i} is setup in lts.conf, but"
            echo "  it does not exist in the /etc/rc.d directory"
            echo
            echo -n "Press  to continue "
            read CMD
        fi
    fi
done

echo "rc.sysinit completed, switching to multi-session mode"

echo

Changing the Image using Local Hard Drive Access

Once an image is stored on a local device it may be necessary to alter the image a later date. There are several methods of doing this, but the easiest may be to boot the client into LTSP and then access the local command line from there, either directly on the client, or via ssh.

When the command line has been accessed it will be necessary to mount the local file systems in order to ammend them. LTSP only loads the most necessary drivers, so those for IDE support are not loaded by default. To activate the ide hard drive drivers, use:

modprobe ide-generic

On the local command line. Now the usual set of tools may be used to manipulate the drives contents. Make sure it is cleanly unmounted before reboot your thin client.

Please add to this section any other relevant drivers that activate other local devices.

Edit | Attach | Printable | Raw View | Backlinks: Web, All Webs | History: r7 < r6 < r5 < r4 < r3 | More topic actions
 
Powered by TWiki
This site is powered by the TWiki collaboration platformCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback