File: startmol

package info (click to toggle)
mol 0.9.61-6
  • links: PTS
  • area: contrib
  • in suites: woody
  • size: 6,140 kB
  • ctags: 8,491
  • sloc: ansic: 50,560; asm: 2,826; sh: 458; makefile: 373; perl: 165; lex: 135; yacc: 131
file content (527 lines) | stat: -rwxr-xr-x 15,566 bytes parent folder | download
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
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
#!/bin/bash
#
# Shell script to start Mac-on-Linux
#
# Usage: startmol [OPTION] [vmlinux]... [System.map]...
#

MOL_OPTS="x"
INSMOD="/sbin/insmod"

# --elf is handled specially
MOL_LONGOPTS="session vt ram test"


###########################################################################
# Extract command line options (some for MOL, some for us)
###########################################################################

LOPTS="" ; OPTS="" ; ARGS=""
while [ "$*" != "" ] ; do
    case $1 in 
	--*) LOPTS="$1 $LOPTS";;
	-*) OPTS="$1 $OPTS" ;;
	*) ARGS="$1 $ARGS" ;;
    esac
    shift 1
done

MOLARGS="" ; FLAGS=""
while getopts ":$MOL_OPTS" x $OPTS ; do
    if [ "$x" == "?" ] ; then
	FLAGS="$OPTARG $FLAGS"
    else
	MOLARGS="-$x $MOLARGS"
    fi
done

for x in $LOPTS ; do
    MATCH=0
    for y in $MOL_LONGOPTS ; do
	{ [ "$x" == "--$y" ] || [ "${x##--$y=*}" == "" ]; } && MATCH=1;
	if [ "$MATCH" == 1 ] ; then
	    MOLARGS="$MOLARGS $x"
	    break;
	fi
    done
    [ "$MATCH" == 0 ] && FLAGS="$FLAGS $x"
done


###########################################################################
# Parse our options
###########################################################################

unset _HELP _VERSION _LOADONLY _MATCH _LIST _ELFFILE _DEBUG
for x in $FLAGS ; do 
    case $x in 
	h|--help)		_HELP=1 ;;
	V|--version)		_VERSION=1 ;;
	l|--loadonly|--load)	_LOADONLY=1 ;;
	--list)			_LIST=1 ;;
	e|--exact)		_MATCH=1 ;;
	a)			_MATCH=0 ;;
	d|--debug)		_DEBUG=1 ;;
	--elf*)			_ELFFILE=${x/--elf=/} ;;
	*)
	    echo -e "Unknown option '$x'\n" ; _HELP=1;  break; ;;
    esac
done

[ "$_HELP" == 1 ] && { 
    echo -ne "Usage: startmol [OPTIONS] [kernelimage]... [System.map]..."\
	    "\nStarts Mac-on-Linux (MOL)\n\n"\
	    " -a                  allow a small kernel module version mismatch\n"\
	    " -d, --debug         run the debugger\n"\
	    " -x,                 wait for the debugger (moldeb) to be started\n"\
	    " -e, --exact         require exact kernel version match\n"\
	    " -h, --help          display this help text and exit\n"\
	    " -l  --loadonly      do not start MOL, just load the kernel modules\n"\
	    " -V, --version       output version information and exit\n"\
            "     --elf=image     load and run statically linked ELF-image inside MOL\n"\
	    "     --list          list available MOL kernel modules\n"\
	    "     --ram=SIZE      RAM size (in megabytes)\n"\
            "     --session=num   run as session num\n"\
            "     --test          run self-test and exit\n"\
            "     --vt=num        use VT<num> for the full-screen video\n"\
	    "\nIf specified, kernelimage must be an image of the running kernel"\
	    "\n(e.g. /usr/src/linux/vmlinux). The System.map file should also correspond"\
	    "\nto the running kernel\n"\
	    "\nFor more information, please visit <http://www.maconlinux.org>.\n"
    exit 1;
}

function get_abs_path()
{
    echo $1 | grep '^/' > /dev/null&& { echo $1; return 0; } 
    echo `pwd`/$1
    return 0
}

# This must be done before we change working directory...
[ "$_ELFFILE" != "" ] && MOLARGS="$MOLARGS --elf=`get_abs_path $_ELFFILE`"
[ "$_DEBUG" == "1" ] && MOLARGS="$MOLARGS -d"

###########################################################################
# extract System.map or kernel binary arguments from the cmdline
###########################################################################

SYMFILES=( $ARGS )

[ "${SYMFILES[*]}" == "" ] && {
    SYMFILES=( /var/tmp/System.map-`uname -r` \
	    /boot/System.map-`uname -r` \
	    /boot/System.map /usr/src/linux/System.map )
}


###########################################################################
# Find out where our binaries and library files are
###########################################################################
#
# Normally, the mol library path is hardcoded or obtained from 
# /etc/molrc. However, when we are started by root we should be 
# aware of the case when MOL is started directly from the source
# tree.

unset MOL_LIB_DIR

if [ $UID -eq 0 ] ; then
    if [ -d "mollib/pci_roms" -a -f "Makefile" ] ; then
	MOLRCGET=`pwd`/emulation/molrcget
	MOL_LIB_DIR=`$MOLRCGET -p` || exit 1
	MOL_BINLIB_DIR="`pwd`/mollib" || exit 1
	MOL_DBG="`pwd`/debugger/moldeb"
	MOL_MOD_DIR="/lib/modules"
	echo "Using binaries in $MOL_BINLIB_DIR and support files in $MOL_LIB_DIR."
    fi
fi
if [ "$MOL_LIB_DIR" == "" ] ; then
    MOLRCGET="molrcget"
    MOL_LIB_DIR=`$MOLRCGET -p` || exit 1
    MOL_BINLIB_DIR=`$MOLRCGET -P` || exit 1
    MOL_DBG="moldeb"
    MOL_MOD_DIR="/lib/modules"
fi

VERS=`cat /proc/version | awk -- '{ print $3 }' | sed s/[a-zA-Z].*// | sed s/\-.*//`
VERS_MAJOR=`echo $VERS | awk -F . -- '{ print $2 }'`
VERS_MINOR=`echo $VERS | awk -F . -- '{ print $3 }'`

# MOL_BINLIB_DIR is used by mol_uname
export MOL_LIB_DIR MOL_BINLIB_DIR
ORGDIR=`pwd`
cd $MOL_BINLIB_DIR

/sbin/lsmod | grep 'mol\>' > /dev/null && MOL_MOD_LOADED=1
/sbin/lsmod | grep 'sheep_net\>' > /dev/null && SHEEP_MOD_LOADED=1


###########################################################################
# Handle some of the switches
###########################################################################

function getres()
{
    $MOLRCGET $* -- $MOLARGS
}
function _mol_uname()
{
    $MOL_BINLIB_DIR/bin/mol_uname $* -- $MOL_MOD_DIR
}

[ "$_VERSION" ] && {
    echo "Mac-on-Linux `getres -V`"
    echo "Copyright (C) 1997-2001 Samuel Rydh <samuel@ibrium.se>"
    exit 1;
}

[ "$_LIST" == "1" ] && {
    echo "---------------------------------"
    echo "Installed modules:"
    echo "---------------------------------"
    _mol_uname -l
    echo "---------------------------------"
    echo "Running kernel:" `_mol_uname -p`
    echo "---------------------------------"
    echo "  -noav = No AltiVec"
    echo "  -smp  = Multiprocessor Kernel"
    echo "---------------------------------"
    exit 1
}


###########################################################################
# Make sure we have a working molrc file
###########################################################################

getres -t || exit $?

###########################################################################
# get_mod_name - lookup the module binary
###########################################################################

function get_mod_name ()
{
    _MOD_DIR=`_mol_uname -e`
    [ $? != 0 ] && {
	[ "$_MATCH" == "" ] && {
	    _MATCH=1
	    getres -b allow_kver_mismatch && _MATCH=0
	}

	[ "$_MATCH" == 1 ] && {
	    echo "===================================================================="
	    echo "  No mol-`getres -V` kernel modules corresponding to the running"
	    echo "  `_mol_uname -p` kernel were found ('startmol --list' displays"
	    echo "  installed version). Recompile the mol kernel modules (recommended)"
	    echo "  or try starting MOL using the '-a' switch. The '-a' flag can be"
	    echo "  made default by adding 'allow_kver_mismatch: yes' to /etc/molrc."
	    echo "===================================================================="
	    return 2
	} 1>&2

	_MOD_DIR=`_mol_uname -f`
	[ $? != 0 ] && {
	    echo "===================================================================="
	    echo "  No kernel module suitable for this kernel was found. The MOL"
	    echo "  kernel modules must be recompiled (refer to www.maconlinux.org"
	    echo "  for instructions). The command 'startmol --list' can be used"
	    echo "  to display installed kernel modules."
	    echo "===================================================================="
	    return 1;
	} 1>&2
    }
    _MOD_DIR="$MOL_MOD_DIR/$_MOD_DIR/misc"

#    echo "Using kernel modules in:" $_MOD_DIR 1>&2 
    [ -f $_MOD_DIR/$1.o ] && {
	echo $_MOD_DIR/$1.o ; 
	return 0;
    }

    echo "The kernel module '$_MOD_DIR/$1.o' appears to be missing." 1>&2
    return 1
}


###########################################################################
# Extract symbols
###########################################################################

# RSYMS - required symbols
RSYMS=( handle_mm_fault next_mmu_context flush_hash_page )

# sym_load_module_helper file required_flag symbols ...
function sym_load_module_helper ()
{
    i=0; ERR=0; XERR=0; FNAME="$1";
    shift 2

    for Y in $* ; do
	    X=`grep ' '$Y'$' $FNAME` || ERR=1
	    X=`echo $X | awk -- '{ print $1 }'`

	    [ $ERR -eq 1 ] && {
		    echo "ERROR: The kernel symbol '$Y' could not be found"
		    XERR=1; ERR=0
	    }
	    #echo $Y" = 0x"$X
	    SYM_STRING=( ${SYM_STRING[*]} msym_$Y=0x$X )
    done
    return $XERR
}

function sym_load_module ()
{
    SYM_STRING=""
    sym_load_module_helper $1 1 ${RSYMS[*]}
    # sym_load_module_helper $1 0 ${OSYMS[*]}
    G_MOD=`get_mod_name molsymglue` || exit 1
    echo -e "Loading MOL symglue kernel module\n   $G_MOD"
    $INSMOD $G_MOD ${SYM_STRING[*]} > /dev/null
}

function symbol_extract ()
{
    for x in ${SYMFILES[*]} ; do

	TMPFILE=$(mktemp /tmp/System.map-XXXXXX)

	# expand relative paths
	y=${x##[!/]*}
	[ "$y" == "" ] && { y=$ORGDIR/$x; }

	[ ! -f $y ] && {
	    echo "The file '$y' is missing"
	    continue
	}
	echo "Examining '$y'"

	# detect and convert vmlinux files by checking the file size
	S=`wc -c $y | sed "s,^ *,," | cut -d" " -f 1`
	[ $S -ge 700000 ] && {
	    rm -f $TMPFILE
	    nm $y | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aU] \)|\(\.\.ng$$\)\|\(LASH[RL]DI\)'\
			| sort > $TMPFILE
	    y=$TMPFILE
	}

	$MOL_BINLIB_DIR/bin/symchecker.pl $y
	[ $? != 0 ] && continue

	CACHE_FILE=$(mktemp /var/tmp/System.map-`uname -r`-XXXXXX)
	[ $CACHE_FILE != $y ] && {
	    echo "Caching kernel symbol file as $CACHE_FILE"
	    rm -f $CACHE_FILE
	    cp $y $CACHE_FILE
	}
	sym_load_module $y && SUCCESS=1
	rm -f $TMPFILE $CACHE_FILE

	[ "$SUCCESS" == "1" ] && return 0;
    done
    return 1
}


###########################################################################
# load the MOL kernel module (if necessary)
###########################################################################

function load_mol_module ()
{
    MOL_MOD=`get_mod_name mol` || exit $?

    [ $UID != 0 ] && echo "Please run 'startmol' as root" && exit 1

    LOADGLUE=0
    /sbin/lsmod | grep 'molsymglue' > /dev/null
    [ $? == 0 ] || {
        # If the following symbols are defined, 'molsymglue' does
	# not need to be loaded.
	#
	# Recent 2.4 kernels:
	#	handle_mm_fault, next_mmu_context, flush_hash_page, 
	#
	# Old 2.4 kernels:
	#	handle_mm_fault, next_mmu_context, mol_interface
	#
	# Otherwise, we must load molsymglue, defining
	#	msym_handle_mm_fault, msym_next_mmu_context, msym_flush_hash_page

	SYMS_NEW=( handle_mm_fault next_mmu_context flush_hash_page )
	SYMS_OLD=( handle_mm_fault next_mmu_context mol_interface )

	for x in ${SYMS_NEW[*]} ; do
	    grep $x /proc/ksyms > /dev/null || LOADGLUE=1
	done
	[ $LOADGLUE != 0 ] && {
	    LOADGLUE=0
	    for x in ${SYMS_OLD[*]} ; do
		grep $x /proc/ksyms > /dev/null || LOADGLUE=1
	    done
	}
    }

    # As a last resort, extract the symbols by hand (molsymglue module)
    [ $LOADGLUE != 0 ] && {
	echo "Certain kernel symbols are missing. Trying to find a valid System.map file"

	symbol_extract
	[ $? != 0 ] && {
	    echo 
	    echo "========================================================================="
	    echo "  Unable to find the kernel symbol file. Start MOL by giving the"
	    echo "  command:"
	    echo 
	    echo "        startmol vmlinux"
	    echo 
	    echo "  where vmlinux is the image of the CURRENTLY running kernel. "
	    echo "  It is also possible to start MOL using the command"
	    echo 
	    echo "        startmol System.map"
	    echo 
	    echo "  where System.map is the symbol file of the running kernel."
	    echo "  For more information, please visit <http://www.maconlinux.org>"
	    echo "========================================================================="
	    echo 
	    exit 1
	}
    }

    echo -e "Loading Mac-on-Linux kernel module:\n   $MOL_MOD"
    $INSMOD $MOL_MOD
    [ $? != 0 ] && {
	echo "===================================================================="
	echo "  Failed to load the module - try recompiling the MOL kernel"
	echo "  module. Instructions (and information about common problems)"
	echo "  are available at <http://www.maconlinux.org>."
	echo "===================================================================="
	echo 
	exit 1
    }
    return 0
}

[ "$MOL_MOD_LOADED" != 1 ] && load_mol_module


###########################################################################
# load the sheep_net ethernet driver
###########################################################################

function load_sheep_net ()
{
    SHEEP_MOD=`get_mod_name sheep_net` || return $?
    [ $UID != 0 ] && {
	echo "*** Error: Must be root to load the sheep_net ethernet driver ***"
	return 1
    }

    echo -e "Loading SheepNet ethernet kernel module:\n   $SHEEP_MOD"
    $INSMOD $SHEEP_MOD 

    [ $? != 0 ] && return 1;

    [ ! -c /dev/sheep_net ] && {
	echo
	echo "WARNING: The ethernet interface /dev/sheep_net is missing."
	echo "Run 'mknod /dev/sheep_net c 10 198' as root to create it"
	echo
    }
}

# XXX: Before loading the module we should verify that it
# is really needed by checking /etc/molrc.

[ "$SHEEP_MOD_LOADED" != 1 ] && load_sheep_net 

[ "$_LOADONLY" == "1" ] && exit 0

# Run any user-specified start scripts

START_SCRIPT=`getres startscript`
[ "$START_SCRIPT" != "" ] && [ -f "$START_SCRIPT" ] && $START_SCRIPT start

###########################################################################
# detect common problems
###########################################################################

LOCKFILE=`getres -L`

[ -f $LOCKFILE ] && {
    ps `cat $LOCKFILE` | grep mol > /dev/null
    if [ $? != 0 ] ; then
	echo "Removing stale lockfile $LOCKFILE"
	rm -f $LOCKFILE
    else 
	echo "Mac-on-Linux is already running with pid `cat $LOCKFILE`"
	echo "according to the lockfile $LOCKFILE."
	exit 1;
    fi
}

getres -b enable_console_video && {
    [ ! -c /dev/fb0 ] && {
	echo "The framebuffer device /dev/fb0 is missing."
	echo "Run 'mknod /dev/fb0 c 29 0' to create it"
	exit 1
    }
    [ ! -f $($MOLRCGET video_modes) ] && {
	echo
	echo "*************************************************************"
	echo " No video modes has been configured. Please run 'molvconfig'"
	echo " as root to setup full screen video or disable console"
	echo " video in the /etc/molrc file"
	echo "*************************************************************"
	exit 1
    }
}

###########################################################################
# run MOL in debugger?
###########################################################################

[ "$_DEBUG" == "1" ] && {
    $MOL_BINLIB_DIR/bin/mol $MOLARGS > /dev/null >& /dev/null
    $MOL_DBG $MOLARGS
    if [ $? -ne 2 ] ; then
	kill -HUP `cat $LOCKFILE`
    fi
    [ -f /etc/mol.sh ] && /etc/mol.sh stop
    exit 0
}


###########################################################################
# run MOL without debugger
###########################################################################

echo "Copyright (C) 1997-2001 Samuel Rydh <samuel@ibrium.se>"

# Never coredump (won't work anyway)
ulimit -c 0

$MOL_BINLIB_DIR/bin/mol $MOLARGS

# give MOL some time to create the lock file
x=0
while [ $x -le 6 ] ; do
    [ -f $LOCKFILE ] && break;
    usleep 500000
    x=`expr $x + 1`
done

[ -f $LOCKFILE ] && {
    MOLPID=`cat $LOCKFILE`
    trap "kill -INT $MOLPID" SIGINT

    while [ -d /proc/$MOLPID ] ; do
	sleep 3;
    done
    [ -f /etc/mol.sh ] && /etc/mol.sh stop
}

exit 0