summaryrefslogtreecommitdiff
path: root/sos-code-article4/support/build_image.sh
blob: 43929cdcb6e232a02072877c749cdd9612d4cf14 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#!/bin/sh
# Copyright (C) 2003, David Decotigny

# 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. 

# 1) What does it do ?
#
#  1) Check where Grub is installed (lookup_grub)
#  2) Assign some local variables using the shell script arguments.
#      a) Argument 1 : the destination  (either a file or a drive, like a:)
#      b) Argument 2 : the loader (i.e kernel)
#      c) Argument 3 : options passed to the loader
#      d) Argument 4 : the modules (that can be loaded optionally by Grub)
#  3) Test whether destination is a drive or a file
#  4) Create the directory structure inside the drive
#  5) Copy the loader in the drive
#  6) Generate the 'menu.txt' file used by Grub to generate the boot menu
#  7) Copy all modules
#  8) Copy the menu.txt file
#
# 2) Why is it so complex ?
#    Because it must support various Grub/mtools installations and versions
#
# In fact, this shell script is used in the KOS (kos.enix.org)
# project. This operating system consists in a loader and many many
# modules that are linked together at boot time. It is much more
# complex that a simple monolithic kernel.
#
# For your simple monolithic kernel, you only need to give argument 1
# and 2.

print_usage () {
  echo "Usage: $0 [X:|image] path/to/loader option path/to/modules..."
  echo "       where X: is a valid floppy drive on your computer"
  echo "       where image is any file name"
  exit 1
}

grub_dirs_common="/usr/local/share/grub/i386-freebsd /usr/local/share/grub/i386-pc /usr/share/grub/i386-pc /usr/lib/grub/i386-pc /usr/local/grub /usr/share/grub/i386-redhat /usr/local/src/grub-0.5.94 $HOME/share/grub/i386-pc/"
sbin_grub_path="/usr/local/sbin /usr/sbin /sbin $HOME/sbin"

PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin
export PATH

MTOOLSRC=mtoolsrc
export MTOOLSRC

# Redefined variables
FLOPPY_DRIVE=A:
IMG_FNAME=fd.img

##
## Format disk image
##
init_image () {
  echo "Initialize disk image $IMG_FILE..."
  if [ ! -f $IMG_FNAME ] ; then
    dd if=/dev/zero of=$IMG_FNAME bs=18k count=80 1>/dev/null 2>&1
  fi

  rm -f $MTOOLSRC
  echo "drive u: file=\"$IMG_FNAME\" 1.44M filter" > $MTOOLSRC

  if mformat U: ; then : ; else
    rm -f $MTOOLSRC
    echo "drive u: file=\"$IMG_FNAME\" 1.44M" > $MTOOLSRC
    if mformat U: ; then : ; else
      rm -f $MTOOLSRC
      echo "drive u: file=\"$IMG_FNAME\"" > $MTOOLSRC
      mformat U:
    fi
  fi
}


##
## Format (real) floppy disk
##
init_floppy () {
  echo "Formatting floppy..."
  mformat $FLOPPY_DRIVE || exit 1
}


lookup_grub () {
  # Look for a correct GRUBDIR
  for d in $grub_dirs_common ; do
    if [ -d $d ] ; then
      GRUBDIR=$d
      break
    fi
  done

  # Try to guess with locate
  if [ ! -d "$GRUBDIR" ] ; then
    GRUBDIR=`locate stage2 | head -1 | xargs dirname 2>/dev/null`
  fi

  # Look for a correct sbin/grub
  for d in $sbin_grub_path ; do
    if [ -x $d/grub ] ; then
      SBIN_GRUB=$d/grub
      break
    fi
  done

  if [ -d "$GRUBDIR" -a -x "$SBIN_GRUB" ] ; then 
    echo "Found correct grub installation in $GRUBDIR"
    echo "Found correct /sbin/grub at $SBIN_GRUB"
  else
    echo "Couldn't find a correct grub installation."
    exit 1
  fi
}

##
## setup_disk [drive]
## => setup disk directory structure / copy files
##
setup_disk () {
  echo "Setup destination disk..."

  mmd $1/boot
  mmd $1/boot/grub

  if [ -d $GRUBDIR/stage1 ] ; then
    mcopy $GRUBDIR/stage1/stage1 $1/boot/grub/
    mcopy $GRUBDIR/stage2/stage2 $1/boot/grub/
  else
    mcopy $GRUBDIR/stage1 $1/boot/grub/
    mcopy $GRUBDIR/stage2 $1/boot/grub/
  fi
  mmd $1/system
  mmd $1/modules

  $SBIN_GRUB --batch <<EOT 1>/dev/null 2>/dev/null || exit 1
device (fd0) $IMG_FNAME
install (fd0)/boot/grub/stage1 (fd0) (fd0)/boot/grub/stage2 p (fd0)/boot/grub/menu.txt
quit
EOT
}



#################################################
## Real start
##
#[ "$#" -lt 3 ] && print_usage

lookup_grub

dest="$1" ; shift
loader_fname="$1" ; shift
options="$1" ; shift
modules="$*"

# Init destination disk
case x$dest in
  x*:)
    drive=$dest
    IMG_FNAME=$dest
    FLOPPY_DRIVE=$dest
    init_floppy
    ;;
  x*) 
    drive=U:
    IMG_FNAME=$dest
    init_image
    ;;
esac

# Create directory structure
setup_disk $drive

# Copy the loader
mcopy -bo $loader_fname $drive/system/`basename $loader_fname`

# Generate the menu.txt file
rm -f menu.txt
cat <<EOF > menu.txt
timeout 0 
default 0
title  Simple OS
root   (fd0)
kernel /system/`basename $loader_fname` $options
EOF

# Copy the modules
for f in $modules ; do
    if [ ! -f $f ] ; then
	echo "ERROR: module $f not correctly compiled in."
	exit 1
    fi
    if ! mcopy -bo $f $drive/modules/`basename $f` ; then
	echo "ERROR: module $f could not be transferred to floppy."
	exit 1
    fi
    echo module /modules/`basename $f` >> menu.txt
done

# Transfers the menu.txt file to floppy
mcopy -bo menu.txt $drive/boot/grub/