123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565 |
-
-
- The Diskless Terminal running from NT server Mini-HOWTO
- Pavel Tkatchouk, ptkatcho@portal.ca
- v0.1, June 19th 1999
-
- Table of Contents
-
- 1. Introduction.
-
- 1.1 What is it for?
- 1.2 Do we need this HOWTO?
- 1.3 A bit of History.
-
- 2. Project description.
-
- 2.1 Packaging.
- 2.2 Image.
- 2.2.1 Kernel.
- 2.2.2 MRFS.
- 2.2.3 Building MRFS.
- 2.3 Remotefs.
- 2.4 Booting sequence.
- 2.4.1 BOOTP, TFTP.
- 2.5 Bootprom.
-
- 3. Resources.
-
- 4. Copyright.
-
- 5. Feedback and credits.
-
-
- 1. Introduction.
-
-
- 1.1. What is it for?
-
- This document describes how to build software distribution to run Java client on diskless
- terminal booted from Microsoft Windows 95/98/NT workstation. Package can also be easily
- modified to be used as Linux terminal or X Windows terminal's software. I found it also
- convenient for setup over the Ethernet of floppyless PS's, hard disk of which for some
- reason can not be accessed (sealed case under warranty, etc.).
-
-
- 1.2. Do we need this HOWTO?
-
- To be honest, I'm not sure. There are few excellent HOWTO's (see 3. Recources) that up until
- recently I considered quite sufficient to build what I've done two years ago. But since my
- project uses MS Windows as a file server vs. traditional NFS there were some know-how's
- involved which number of people wanted to see in some formal document.
-
-
- 1.3. A bit of history.
-
- My project at that time (1996) was to find OS/JVM that will allow to run Java application
- on hardware we manufacture. Hardware is practically generic x86 PC except it has no keyboard,
- hard drive, floppy drive, mouse, but touchscreen over LCD, plus some POS specific peripherals
- (badge reader, credit card reader, etc.). Due to cost consideration it had no any significant
- storage, so OS and Java client along with support binaries, libraries etc. had to be loaded
- remotely. Because our clients are exclusively Windows shops, Server had to be Windows as well.
- During evaluation of different commercial OS'es along with JVM's available it become apparent
- to my surprise that most promising solution was GPL one - Linux.
-
-
- 2. Project description.
-
- 2.1. Packaging.
-
- The whole distribution consists of remote file system (RemoteFS) residing on MS Windows
- server (NT Workstation, NT Server or Windows9x) and tagged bootable image.
-
-
- 2.2. Image.
-
- Image (~1.5MB) is generated by mknbi utility that comes with Etherboot package
- <http://etherboot.sourceforge.net>. It can include minimal root file system (MRFS)
- like in my case (since I had to boot client from MS Windows server and Linux kernel doesn't
- support SMBFS-Root, only NFS-Root. So I had to keep rootfs in the ramdisk). To generate
- image the following script can be used.
-
- #!/bin/sh
- # mkrootnet: makes tagged netbootable image
- # This image includes kernel and minimal root filesystem
- # to do initial boot.
- #
- # Copyright (c) Pavel Tkatchouk 1996. All rights reserved.
- # Permission is granted for this material to be freely
- # used and distributed, provided the source is acknowledged.
- # No warranty of any kind is provided. You use this material
- # at your own risk.
- #
- DEVICEFILENAME="/tmp/file" # temporary file to be used as device
- FSBLOCKS=4096 # uncompressed filesystem size in K
- BOOTDISKDIR="/usr/BOOT/ROOTFS" # root filesystem model
- MOUNT="/mnt2" # temporary mount point
- ROOTFS="/tmp/rootfs" # root filesystem image
- ROOTFSGZ="/tmp/rootfs.gz" # compressed root filesystem image
- KERNEL="/usr/KERNELS/vmlinuz-nt" # kernel image
- KERNELTMP="/tmp/vmlinuz" # temporary copy of kernel image
- BOOTIMAGE="/tmp/img" # tagged image to be booted by client
- # if you want ramisk more than default 4096 set CMDLINE, don't forget to
- # adjust $FSBLOCKS
- # CMDLINE="ramdisk_size=8192" # parameters to pass to the kernel
- #
- echo "check:"
- echo "- if tftp server's download dir mounted to /mnt"
- echo "- loopback device is built-in or loaded"
- echo "\n press Enter when done"
- read tmp
- UPLOAD="/mnt/tmp" # tftp server's dir to upload bootimage
- echo -e "\nZeroing $DEVICEFILENAME of $FSBLOCKS k"
- echo "to be used as device for root filesystem model"
- dd if=/dev/zero of=$DEVICEFILENAME bs=1k count=$FSBLOCKS
- echo -e "\nMaking file system on $DEVICEFILENAME"
- mke2fs -m 0 $DEVICEFILENAME
- echo "Mounting $DEVICEFILENAME as a loopback device"
- mount -o loop -t ext2 $DEVICEFILENAME $MOUNT
- curdir=`pwd`
- cd $BOOTDISKDIR
- echo -e "Copying files from $BOOTDISKDIR to $DEVICEFILENAME, please wait"
- find . -print|cpio -pmd $MOUNT
- echo "Unmounting $MOUNT"
- umount $MOUNT
- cd $curdir
- echo "Copying $DEVICEFILENAME to $ROOTFS"
- dd if=$DEVICEFILENAME of=$ROOTFS bs=1k
- echo "Compressing $ROOTFS, it may take a while"
- echo "Please wait..."
- if [ -f $ROOTFSGZ ];then
- rm -f $ROOTFSGZ
- fi
- gzip -c $ROOTFS>$ROOTFSGZ
- rm -f $ROOTFS
- echo -e "\nCreating netbootable image"
- cp $KERNEL $KERNELTMP
- mknbi -d ram -i rom -r $ROOTFSGZ -k $KERNELTMP -a $CMDLINE -o $BOOTIMAGE
- echo "Uploading $BOOTIMAGE to $UPLOAD"
- cp $BOOTIMAGE $UPLOAD
- echo "Cleaning after ourselves"
- rm -f $KERNELTMP $DEVICEFILENAME $BOOTIMAGE
- echo "All done"
-
-
- In the above script actual image is generated by the following comand
-
- #mknbi -d ram -i rom -r rootfs.gz -k vmlinuz-nt -o img
-
- where:
- rootfs.gz - minimal root file system (MRFS);
- vmlinuz-nt - kernel;
- img - resulting image.
-
-
- Note:
- Default ramdisk size is 4096. It was enough for RedHat4.1 based minimal file system, but
- apparently not enough for 5.2 based. When this happens "end request:I/O error, dev 01:00 ..."
- error shows up. To fix that either use "mknbi -a ramdisk_size=8192" to pass parameter to the
- kernel (doesn't require kernel recompilation), or change /usr/src/linux/drivers/block/rd.c:
- int rd_size= from 4096 to 8192 or whatever and rebuild the kernel.
-
-
- 2.2.1. Kernel.
-
- Kernels 2.0.30 and 2.0.36 have been used by author, although nothing is preventing you from
- experimenting with others. Kernel should include ramdisk support. The following
- <link to .config> configuration has been used to build <link to binary (kernel 2.0.30)>.
- You may find some components unnecessary, just exclude them and rebuild.
-
- Don't forget to change root device after you built the kernel (rdev vmlinuz /dev/rd).
-
- Gotcha's: apparently smbfs is broken in 2.2.x kernels. Symptoms: remote share is mounted
- just fine but after a while fails with "smb_request: result = -32" errmsg. I've heard
- SuSe has fix for that.
-
- 2.2.2. MRFS.
-
- Minimal root file system is required to get Linux up and running along with networking until
- it can mount remote file system to run X/Java from there. After image gets loaded from the
- server MRFS is decompressed into ramdisk. If you can afford a lot of ram on your terminal the
- entire remote file system can be moved to rootfs.gz. That will make your terminal more
- responsive.
-
-
- 2.2.3. Building MRFS.
-
- Some folks found it easier to start from scratch, others use known "minimal" Linux distributions
- (Linux Router, tomsrtbt, etc.), yet others prefer to start from "big" Linuces like I did. Every
- path has it's pro and contras.
-
- Pruning standard distribution (RedHat, Debian, etc.) to your needs might be very time consuming.
- To ease that painful process I have used remotely booted diskless client with NFS-Root (see
- Etherboot's Readme, NFS-Root and NFS-Root-Client mini-HOWTO's, Diskless-HOWTO):
-
- - setup minimal RedHat4.1 install (networked workstation, X, no development, mail, etc., ~117MB);
- - find . -print|cpio -pmd /usr/NFS/ROOTFS - copy entire fs tree to NFS exported dir;
- - mknod /usr/NFS/ROOTFS/dev/nfsroot b 0 255;
- - build vmlinuz-nfs kernel according to NFS-Howto (built-in bootp,rarp,NFS,NFS root,NIC
- driver,RAM disk);
- - rdev vmlinuz-nfs /dev/nfsroot - to set NFS root device;
- - build image for NFS-Root fs:
- #mknbi -d rom -i rom -k vmlinuz-nfs -o nfsImage;
- - boot client while monitoring NFS file requests (by Solaris snoop);
- - copy files from /usr/NFS/ROOTFS to /usr/BOOT/ROOTFS (MRFS model) according to snoop's
- filelist;
- - generate image by mkrootnet script (don't forget to point to the right kernel vmlinuz-nt).
-
- The above trick not only allows to determine the sought files set but also debug boot process
- analyzing NFS messages. I found it convenient to put "read tmp" statements into init scripts
- for debugging. Tracking files up until issuing login gives you <link to rootfs.gz> MRFS (~1MB)
- that can be used to boot Linux from ROM (flash, eprom, DiskOnChip, SanDisk, etc.) as well. All
- the other files requested by client (during starting X, Java, Java client) were put into (link
- to remotefs.zip, ~9MB).
-
-
- To restore MRFS model on your PC from the above rootfs.gz:
- - #cd /tmp
- - #gunzip rootfs.gz
- - #mount -o loop -t ext2 /tmp/rootfs /mnt
- - #cd /mnt
- - #find . -print|cpio -pmd /usr/BOOT/ROOTFS
- - #umount /mnt
-
- Note:
-
- You will have to change attributes of some dirs, files (/etc/mtab, /etc/mtab~, /var/lock/subsys/*,
- /var/run/*, /dev/tty*, etc.) against standard. This is because with standard attribs diskless
- client refused to work. For example I had to change /dev/tty* ownerships to 99:99 from original
- 0:0 or 0:5, to get rid of errmsg "INIT: Id "1" respawning too fast: disabled for 5 minutes".
- Being admin illiterate I just chmod them to 777 and chown to 99:99 to make life easier.
- THIS IS SERIOUS SECURITY VIOLATION!!! Using keyboardless terminal with no daemons running in
- my case reduces the risk, yet I would appreciate very much those more experienced who will help
- to restore the right attribs while keeping the distribution working.
-
- Some "gotcha's" to watch for during MRFS building:
- - standard attributes/ownership of some files don't work;
- - rdev must be set (non-tagged image didn't work, so couldn't use config file to pass parrs
- to the kernel);
- - diskless client writes 99:99 ownership on generated files;
- - "password incorrect" for root, but any other OK and su OK too.
-
-
- 2.3. RemoteFS.
-
- Remotefs.zip file includes everything required by the system that can be located on
- remote file system, i.e after booting has been complete and remote file system mounted.
- In my case it is X Windows System and Java binaries, libraries etc. To use that file on
- MS Windows NT:
- - unzip remotefs.zip to some directory;
- - share this directory read-only as "usr" (or share as some other name and pass this name to
- the client through bootptab configuration file for BOOTP server;
- - create an account username=root, password=linux on NT (can be set in bootptab).
-
- Note:
- There's no symbolic links on NTFS, so UNIX links must be replaced by copies on NTFS.
- To determine potential troublmakers one could use the following:
- - first copy required subset (according to snoop's intercept) from /usr/NFS/ROOTFS to
- /usr/BOOT/REMOTEFS;
- - mount some share from NTFS to /mnt;
- - /usr/BOOT/REMOTEFS#find . -print|cpio -pmd /mnt 2>links;
- In the links file you will find names to work with.
-
-
- 2.4. Booting sequence.
-
- Boot occurs in the following sequence:
- - bootprom sends bootp request,
- - bootp server responds with subnet mask, client's name, client's IP, TFTP server's IP,
- bootfile name and some optional parameters (like NT's username/password to use it's share,
- you could pass some other share name here as say T104="somedir");
- - bootprom downloads image from TFTP server;
- - kernel starts;
- - kernel decompresses MRFS in RAM;
- - system starts init using ramdisk root,
- - mounts remote file system from NT via SMBFS;
- - automatically logins;
- - starts xstart script located on remotefs (/usr/sbin) where you can start any of your
- programs, change parameters, etc. without rebuilding the image.
-
- Below are some config/init sample files from <rootfs.gz>, <remotefs.zip>:
-
- <bootptab, change to link>
- t1:sm=255.255.255.0:sa=192.168.33.150:bf=img:T100="pavelnt4":T101="root":T102="linux"
- touch1:hn=touch1:tc=t1:ha=00A0F00035CD:ip=192.168.33.127
-
- </etc/fstab, change to link>:
- /dev/ram / ext2 defaults 1 1
- /proc /proc proc defaults 0 0
-
- </etc/rc.d/rc.bootp, change to link later>:
- #!/bin/sh
- # Written to simply set the IP stuff up from the
- # bootpc data.
- # Last updated : Mon Mar 10 15:17:01 1997
- #
- # Variables
-
- BOOTPC=/sbin/bootpc
- IFCONFIG=/sbin/ifconfig
- ROUTE=/sbin/route
- BINHOST=/bin/hostname
- DEV=eth0
- ASKSERVER="255.255.255.255"
- TW="--timeoutwait 320"
- RIF="--returniffail"
- RIFMESSAGE="Bootp failed -- disabling network."
- RCONF=/etc/resolv.conf
- EHOSTS=/etc/hosts
- LHOSTS=/etc/hosts.local
- TMPFILE=/tmp/bootp
- # Functions
- # Remove the networking by taking down the interface
- netdown() {
- ${ROUTE} del default
- ${IFCONFIG} ${DEV} down
- }
- ## End of the functions
-
- ## Start of the actual work
- # Bring up minimal networking use 0.0.0.0 as our address as we don't
- # know it yet (Means "Me but I don't know my address or network")
- ${IFCONFIG} ${DEV} up 0.0.0.0
- ${ROUTE} add default dev ${DEV}
-
- # Perform the bootp -- doesn't return unless it gets an answer
- if ${BOOTPC} --dev ${DEV} --server ${ASKSERVER} ${RIF} ${TW} > ${TMPFILE}
- then
- # Take down networking (use the 0.0.0.0 for as short a time as possible)
- netdown
- # Read in the values
- . ${TMPFILE}
-
- # To use in mountsmb script later
- SMBSERVER=${T100}
- # And delete the temporary file
- # rm ${TMPFILE}
- else
- # Take down networking (use the 0.0.0.0 for as short a time as possible)
- netdown
- # give message and quit
- echo ${RIFMESSAGE}
- exit 1
- fi
-
- # Start the loopback interface and add a route to it
- # It's already set by standard init?
- ${IFCONFIG} lo 127.0.0.1
- ${ROUTE} add -net 127.0.0.0
-
- # Setup of IP stuff needs doing first
- #
- if [ -z "${NETMASK}" ] ; then
- # No netmask info, all this is guessed from the IP number
- # If this is wrong for your network FIX the bootpd to know
- # what it should send in the RFC1497 cookie! 11/02/94 JSP
- #
- ${IFCONFIG} ${DEV} up ${IPADDR} broadcast ${BROADCAST}
- ${ROUTE} -n add -net ${NETWORK} dev ${DEV}
- else
- # We will have NETMASK, BROADCAST, and NETWORK defined
- ${IFCONFIG} ${DEV} up ${IPADDR} broadcast ${BROADCAST} netmask ${NETMASK}
- ${ROUTE} -n add -net ${NETWORK} dev ${DEV}
- fi
-
- # Set the hostname from what we got via bootp or reverse lookup
-
- echo "127.0.0.1 loopback localhost">${EHOSTS}
- ${BINHOST} "${HOSTNAME}"
- echo "${IPADDR} ${HOSTNAME}" >>${EHOSTS}
- echo "${SERVER} ${SMBSERVER}" >>${EHOSTS}
-
-
- </etc/rc.d/rc.local, change to link>:
- #!/bin/sh
- # This script will be executed *after* all the other init scripts.
- # You can put your own initialization stuff in here if you don't
- # want to do the full Sys V style init stuff.
- #
- # 07/02/97 Pavel Tkatchouk
- #
- echo "Start networking"
- insmod /lib/8390.o
- insmod /lib/ne.o io=0x300 irq=9
- echo "Install serial"
- insmod /lib/serial.o
- echo "Install touch"
- insmod /lib/touch.o
- echo "Install smbfs"
- insmod /lib/smbfs.o
- echo "Getting TCP/IP parameters from bootp server"
- echo "and start networking"
- /etc/rc.d/rc.bootp
- if [ -f /etc/squirrel-release ]; then
- R=$(cat /etc/squirrel-release)
- else
- R="release 0.02"
- fi
- echo "Mounting remote fs"
- /sbin/mountsmb
- echo "XYZ Inc. Diskless Linux $R"
- echo "Starting X and Java client without login"
- su -c /sbin/xstart root
-
-
- </usr/sbin/xstart, change to link>:
- #!/bin/bash
- #
- # Script to start X and Java client
- # 08/07/97 Pavel Tkatchouk
- #
- # Read bootps response first
- . /tmp/bootp
- # -s 0 to disable screen-saver
- /usr/X11R6/bin/X -s 0 &
- export DISPLAY=:0.0
- # /usr is share mounted from Windows workstation
- cd /usr/program/
- java SomeJavaApp
-
-
- </sbin/mountsmb, change to link>:
- #!/bin/bash
- # mountsmb: mounts remote filesystems from NT workstation
- # using Microsoft's SMB protocol
- #
- # Copyright (c) Pavel Tkatchouk 1997. All rights reserved.
- # Permission is granted for this material to be freely
- # used and distributed, provided the source is acknowledged.
- # No warranty of any kind is provided. You use this material
- # at your own risk.
- #
- # Last edit June 29 8:30 1997
- #
- MOUNTDIR="usr"
- SHRDIR="usr"
- BOOTPRES="/tmp/bootp"
- # Read botpc response
- . ${BOOTPRES}
- # Sharename from NT server, uncomment if you want to use
- # non-hardcoded "usr" but from bootptab
- #SHRDIR=${T104}
- SMBSRV="//${T100}"
- CLIENT="${HOSTNAME}"
- USER="${T101}"
- PASSWORD="${T102}"
- echo -e "\nMounting $SMBSRV/$SHRDIR to /$MOUNTDIR"
- smbmount $SMBSRV/$SHRDIR $MOUNTDIR -c $CLIENT -U $USER -P $PASSWORD
- echo -e "\nDone"
-
- Gotcha's:
- Looks like smbmount client from smbfs package used to mount remote Windows shares to local
- Linux dirs in pre 2.2.x era isn't maintained anymore so you should use one coming with
- Samba package. Also binary smbmount won't work with 2.2.x, so you have to recompile with
- 2.2.x headers following Samba's readme. Yet even that won't guarantee reliable work until
- somebody fixes kernel's smbfs module.
-
- 2.4.1. BOOTP, TFTP.
-
- There are number of BOOTP, TFTP servers for Windows on the market. You could find them
- here:
-
- - www.walusoft.co.uk (Walusoft's tftp);
- - ftp.coast.net/simtel/nt/internet/tftpds12.zip (Millwood AB's tftp);
- - ftp.cabletron.com/pub/snmp/bootftp/boottft2.zip (Cabletron's bootp/tftp combo);
- - www.tellurian.au.com (Tellurian's bootp, tftp, dhcp servers).
- - www.metainfo.com (Metainfo's DHCP server)
- - www.nts.com (Network Telesystems's DHCP server in IPserver package)
-
- My choice was Tellurian's products - very reliable, simple to install, attractively priced
- (fully capable evaluation versions are available).
-
- 2.5. Bootprom.
-
- Ken Yap's Etherboot <etherboot.sourceforge.net> will tell you everything about bootprom.
- Here I just want to mention that normally you would have to put bootprom's code into network
- adapter's PROM. But if your hardware like mine has BIOS programmed in flash you could
- re-program it to add bootprom (some BIOS requires special programmer to do that, others don't)
- as BIOS extension.
-
- This is what I did to add ne.rom (bootprom generated by Etherboot's makerom for NE2000 clone)
- to AMI BIOS on my flash:
-
- - read flash content by programmer into bios.bin binary file;
- - use one of available binary editors (say www.simtel.net/Win95/editors/hxp3005.zip to add
- ne.rom to bios.bin (and to edit ne.rom if necessary);
- - write new bios.bin back to flash.
-
- Notes:
- - makerom generates bootprom for standard EPROM sizes (8k, 16k, 32k, etc.), so if you tight on
- space use -s flag to adjust size (or cut it manually to multiple of 512 bytes blocks, just
- don't forget to adjust extension's length which is coded in Byte 2 and checksum to 8 bits
- of zero;
- - valid absolute addresses for BIOS extensions are from 0xC8000 to 0xF4000 (check with
- motherboard's manufacturer how flash is mapped onto system memory space);
- - Byte 0 must be 0x55, Byte 1 must be 0xAA, Byte 2 must be extension's length in 512 bytes
- blocks;
- - extension BIOS has to start at a 2k boundary;
-
-
- 3. Resources.
-
- FAQ's:
- - tomsrtbt.FAQ (www.toms.net);
-
- HOWTO's:
- - Paul Moody's miniHOWTO (www.linuxembedded.com/pmhowto.html)
- - Diskless;
- - Diskless-HOWTO;
- - NFS-Root;
- - NFS-Root-Client;
- - Bootdisk-HOWTO;
- - BootPrompt-HOWTO;
- - NCD-X-Terminal;
- - Remote-Boot;
- - Remote-X-Apps;
-
- Web:
- - etherboot.sourceforge.net/
- - www.waste.org/~zanshin
- - www.tellurian.com.au.
- - www.toms.net
- - www.trinux.org
- - www.linux.org.uk/ELKS-Home
- - www.embedded.com
- - www.linuxembedded.com
- - www.thinlinux.org
- - www.linuxrouter.org
- - linux-mandrake.com
- - www.disklessworkstations.com
-
- Newsgroups:
- - comp.arch.embedded
-
- Lists:
- - netboot-owner@baghira.han.de
- - linux-embedded@waste.org
-
- Magazines:
- - Circuit Cellar #100 - 105
-
-
- 4. Copyright.
-
- Copyright (c) Pavel Tkatchouk 1999.
- Permission is granted for this material to be freely used and distributed, provided the source
- is acknowledged. Copyright policy is GPL as published by the Free Software Foundation.
-
- No warranty of any kind is provided. You use this material at your own risk.
-
-
-
- 5. Feedback and credits.
-
- Since I am neither have a lot of Linux experience nor native English speaker, there would be
- errors in this document. I would accept any help with gratitude whether in form of proof-reading,
- techical corrections or otherwise. Please send your comments, suggestions and questions to Pavel
- Tkatchouk (ptkatcho@portal.ca)
-
- I wish to thank Pierre Mondie who convinced me to start this document. I'm also very much in
- debt to all those who's work made this project possible:
-
- Ken Yap <ken_yap@users.sourceforge.net> (Etherboot)
- David Newall <www.tellurian.com.au> (Bootpdnt/Ftpdnt)
- (to be continued)
|