$CFG::hypervisor = "";
$CFG::hypervisor_params = "serial";
$CFG::genisoimage = "genisoimage";
-$CFG::qemu = 'qemu -cpu coreduo -smp 2';
+$CFG::qemu = 'qemu-system-i386 -cpu coreduo -smp 2';
$CFG::default_target = 'qemu';
%CFG::targets = (
'qemu' => '--qemu',
"tud" => '--server=erwin.inf.tu-dresden.de:~sojka/boot/novaboot --rsync-flags="--chmod=Dg+s,ug+w,o-w,+rX --rsync-path=\"umask 002 && rsync\"" --grub --grub-prefix=(nd)/tftpboot/sojka/novaboot --grub-preamble="timeout 0" --concat --iprelay=141.76.48.80:2324 --scriptmod=s/\\\\bhostserial\\\\b/hostserialpci/g',
"novabox" => '--server=rtime.felk.cvut.cz:/srv/tftp/novaboot --rsync-flags="--chmod=Dg+s,ug+w,o-w,+rX --rsync-path=\"umask 002 && rsync\"" --pulsar --iprelay=147.32.86.92:2324',
"localhost" => '--scriptmod=s/console=tty[A-Z0-9,]+// --server=/boot/novaboot/$NAME --grub2 --grub-prefix=/boot/novaboot/$NAME --grub2-prolog=" set root=\'(hd0,msdos1)\'"',
- "ryuglab" => '--server=pc-sojkam.felk.cvut.cz:/srv/tftp --uboot --uboot-init="mw f0000b00 \${psc_cfg}; sleep 1" --remote-cmd="ssh -t pc-sojkam.felk.cvut.cz \"cu -l /dev/ttyUSB0 -s 115200\"" --remote-expect="Connected." --reset-cmd="ssh -t pc-sojkam.felk.cvut.cz \"dtrrts /dev/ttyUSB0 1 1\""',
+ "ryuglab" => '--server=pc-sojkam.felk.cvut.cz:/srv/tftp --uboot --uboot-init="mw f0000b00 \${psc_cfg}; sleep 1" --remote-cmd="ssh -tt pc-sojkam.felk.cvut.cz \"sterm -d -s 115200 /dev/ttyUSB0\""',
"ryulocal" => '--dhcp-tftp --serial --uboot --uboot-init="dhcp; mw f0000b00 \${psc_cfg}; sleep 1" --reset-cmd="if which dtrrts; then dtrrts $NB_SERIAL 0 1; sleep 0.1; dtrrts $NB_SERIAL 1 1; fi"',
);
my $explicit_target;
GetOptions ("target|t=s" => \$explicit_target);
-my ($amt, @append, $bender, @chainloaders, $concat, $config_name_opt, $dhcp_tftp, $dump_opt, $dump_config, @exiton, @expect_raw, $gen_only, $grub_config, $grub_prefix, $grub_preamble, $grub2_prolog, $grub2_config, $help, $iprelay, $iso_image, $interactive, $kernel_opt, $make, $man, $no_file_gen, $off_opt, $on_opt, $pulsar, $pulsar_root, $qemu, $qemu_append, $qemu_flags_cmd, $remote_cmd, $remote_expect, $reset_cmd, $rom_prefix, $rsync_flags, @scriptmod, $scons, $serial, $server, $stty, $uboot, $uboot_init);
+my ($amt, @append, $bender, @chainloaders, $concat, $config_name_opt, $dhcp_tftp, $dump_opt, $dump_config, @exiton, @expect_raw, $gen_only, $grub_config, $grub_prefix, $grub_preamble, $grub2_prolog, $grub2_config, $help, $ider, $iprelay, $iso_image, $interactive, $kernel_opt, $make, $man, $no_file_gen, $off_opt, $on_opt, $pulsar, $pulsar_root, $qemu, $qemu_append, $qemu_flags_cmd, $remote_cmd, $remote_expect, $reset_cmd, $rom_prefix, $rsync_flags, @scriptmod, $scons, $serial, $server, $stty, $tftp, $tftp_port, $uboot, @uboot_init);
$rsync_flags = '';
$rom_prefix = 'rom://';
"grub-prefix=s" => \$grub_prefix,
"grub2:s" => \$grub2_config,
"grub2-prolog=s" => \$grub2_prolog,
+ "ider" => \$ider,
"iprelay=s" => \$iprelay,
"iso:s" => \$iso_image,
"kernel|k=s" => \$kernel_opt,
"server:s" => \$server,
"strip-rom" => sub { $rom_prefix = ''; },
"stty=s" => \$stty,
- "uboot" => \$uboot,
- "uboot-init=s" => \$uboot_init,
+ "tftp" => \$tftp,
+ "tftp-port=i" => \$tftp_port,
+ "uboot:s" => \$uboot,
+ "uboot-init=s" => \@uboot_init,
"h" => \$help,
"help" => \$man,
);
if (defined $config_name_opt && scalar(@ARGV) > 1) { die "You cannot use --name with multiple scripts"; }
+if ($ider) {
+ $iso_image //= ''; # IDE-R needs an ISO image
+ if (!defined $amt) { die "Error: --ider requires --amt"; }
+}
+
# Default options
if (defined $serial) {
$serial ||= "/dev/ttyUSB0";
my $EOF;
my $last_fn = '';
my ($modules, $variables, $generated, $continuation);
-while (<>) {
+my $skip_reading = defined($on_opt) || defined($off_opt);
+while (!$skip_reading && ($_ = <>)) {
if ($ARGV ne $last_fn) { # New script
die "Missing EOF in $last_fn" if $file;
die "Unfinished line in $last_fn" if $continuation;
push @$modules, $_;
next;
}
+ if (/^run (.*)/) { # run line
+ push @$generated, {command => $1};
+ next;
+ }
die("novaboot: Cannot parse script '$last_fn' line $.. Didn't you forget 'load' keyword?\n");
}
print "novaboot: Created $fn\n";
} elsif (exists $$g{command} && ! $no_file_gen) {
$ENV{SRCDIR} = dirname(File::Spec->rel2abs( $filename, $invocation_dir ));
- system_verbose("( $$g{command} ) > $$g{filename}");
+ if (exists $$g{filename}) {
+ system_verbose("( $$g{command} ) > $$g{filename}");
+ } else {
+ system_verbose($$g{command});
+ }
}
}
}
return $filename;
}
+sub generate_syslinux_config($$$$)
+{
+ my ($filename, $title, $base, $modules_ref) = @_;
+ if ($base && $base !~ /\/$/) { $base = "$base/"; };
+ open(my $fg, '>', $filename) or die "$filename: $!";
+ print $fg "LABEL $title\n";
+ #TODO print $fg "MENU LABEL $human_readable_title\n";
+
+ my ($kbin, $kcmd) = split(' ', @$modules_ref[0], 2);
+
+ if (system("file $kbin|grep 'Linux kernel'") == 0) {
+ my $initrd = @$modules_ref[1];
+ die('To many "load" lines for Linux kernel') if (scalar @$modules_ref > 2);
+ print $fg "LINUX $base$kbin\n";
+ print $fg "APPEND $kcmd\n";
+ print $fg "INITRD $base$initrd\n";
+ } else {
+ print $fg "KERNEL mboot.c32\n";
+ my @append;
+ foreach (@$modules_ref) {
+ s|\brom://([^ ]*)|$rom_prefix$base$1|g; # Translate rom:// files - needed for vdisk parameter of sigma0
+ push @append, "$base$_";
+ print $fg "APPEND ".join(' --- ', @append)."\n";
+ }
+ }
+ #TODO print $fg "TEXT HELP\n";
+ #TODO print $fg "some help here\n";
+ #TODO print $fg "ENDTEXT\n";
+ close($fg);
+ print("novaboot: Created $builddir/$filename\n");
+ return $filename;
+}
+
sub generate_grub2_config($$$$;$$)
{
my ($filename, $title, $base, $modules_ref, $preamble, $prolog) = @_;
{
print "novaboot: Running: ".shell_cmd_string(@_)."\n";
exec(@_);
+ exit(1); # should not be reached
}
sub system_verbose($)
print "Testing \"all\" in $last_fn:\n";
}
-## Connect to the target and check whether is not occupied
+## Connect to the target and check whether it is not occupied
# We have to do this before file generation phase, because file
# generation is intermixed with file deployment phase and we want to
my $exp; # Expect object to communicate with the target over serial line
my ($target_reset, $target_power_on, $target_power_off);
+my ($amt_user, $amt_password, $amt_host, $amt_port);
if (defined $iprelay) {
my $IPRELAY;
system_verbose("stty -F $serial $stty");
open($CONN, "+<", $serial) || die "open $serial: $!";
$exp = Expect->init(\*$CONN);
-} elsif ($remote_cmd) {
+}
+elsif ($remote_cmd) {
print "novaboot: Running: $remote_cmd\n";
$exp = Expect->spawn($remote_cmd);
-} elsif (defined $amt) {
- use LWP::UserAgent;
- use LWP::Authen::Digest;
+}
+elsif (defined $amt) {
+ require LWP::UserAgent;
+ require LWP::Authen::Digest;
sub genXML {
my ($host, $username, $password, $schema, $className, $pstate) = @_;
return sendPOST($host, $username, $password, $content);
}
- my ($user,$amt_password,$host,$port) = ($amt =~ /(?:(.*?)(?::(.*))?@)?([^:]*)(?::([0-9]*))?/);;
- $user ||= "admin";
+ ($amt_user,$amt_password,$amt_host,$amt_port) = ($amt =~ /(?:(.*?)(?::(.*))?@)?([^:]*)(?::([0-9]*))?/);;
+ $amt_user ||= "admin";
$amt_password ||= $ENV{'AMT_PASSWORD'} || die "AMT password not specified";
- $host || die "AMT host not specified";
- $port ||= 16994;
+ $amt_host || die "AMT host not specified";
+ $amt_port ||= 16994;
+
$target_power_off = sub {
- my $result = powerChange($host,$user,$amt_password, "off");
+ $exp->close();
+ my $result = powerChange($amt_host,$amt_user,$amt_password, "off");
die "AMT power off failed (ReturnValue $result)" if $result != 0;
};
$target_power_on = sub {
- my $result = powerChange($host,$user,$amt_password, "on");
+ my $result = powerChange($amt_host,$amt_user,$amt_password, "on");
die "AMT power on failed (ReturnValue $result)" if $result != 0;
};
$target_reset = sub {
- my $result = powerChange($host,$user,$amt_password, "reset");
+ my $result = powerChange($amt_host,$amt_user,$amt_password, "reset");
if ($result != 0) {
- print STDERR "Warning: Cannot reset $host, trying power on. ";
- $result = powerChange($host,$user,$amt_password, "on");
+ print STDERR "Warning: Cannot reset $amt_host, trying power on. ";
+ $result = powerChange($amt_host,$amt_user,$amt_password, "on");
}
die "AMT reset failed (ReturnValue $result)" if $result != 0;
+ };
- sleep(2); # Without pause, connection to AMT machine is
- # initiated before reset and fails after restart
+ my $cmd = "amtterm -u $amt_user -p $amt_password $amt_host $amt_port";
+ print "novaboot: Running: $cmd\n" =~ s/\Q$amt_password\E/???/r;
+ $exp = Expect->spawn($cmd);
+ $exp->expect(10, "RUN_SOL") || die "Expect for 'RUN_SOL' timed out";
- # amtterm must be run here because AMT doesn't allow to
- # reset/on/off computer when somebody is connected
- $exp = Expect->spawn("amtterm -u $user -p $amt_password $host $port");
- };
}
+
if ($remote_expect) {
$exp->expect(10, $remote_expect) || die "Expect for '$remote_expect' timed out";
}
{
my @files = map({ ($file) = m/([^ ]*)/; $file; } @$modules);
# Filter-out generated files
- my @to_build = grep({ my $file = $_; !scalar(grep($file eq $$_{filename}, @$generated)) } @files);
+ my @to_build = grep({ my $file = $_; !scalar(grep($file eq ($$_{filename} || ''), @$generated)) } @files);
system_verbose($scons || $CFG::scons." ".join(" ", @to_build)) if (defined $scons);
system_verbose($make || $CFG::make ." ".join(" ", @to_build)) if (defined $make);
if (defined $iso_image) {
generate_configs("(cd)", $generated, $filename);
my $menu;
- generate_grub_config(\$menu, $config_name, "(cd)", $modules);
+ generate_syslinux_config(\$menu, $config_name, "/", $modules);
$menu_iso .= "$menu\n";
map { ($file,undef) = split; $files_iso{$file} = 1; } @$modules;
}
## Generate ISO image
if (defined $iso_image) {
- open(my $fh, ">menu-iso.lst");
- print $fh "timeout 5\n\n$menu_iso";
+ system_verbose("mkdir -p isolinux");
+ system_verbose('cp /usr/lib/syslinux/isolinux.bin /usr/lib/syslinux/mboot.c32 /usr/lib/syslinux/menu.c32 isolinux');
+ open(my $fh, ">isolinux/isolinux.cfg");
+ if ($#scripts) {
+ print $fh "TIMEOUT 50\n";
+ print $fh "DEFAULT menu\n";
+ } else {
+ print $fh "DEFAULT $config_name\n";
+ }
+ print $fh "$menu_iso";
close($fh);
- my $files = "boot/grub/menu.lst=menu-iso.lst " . join(" ", map("$_=$_", keys(%files_iso)));
+
+ my $files = join(" ", map("$_=$_", (keys(%files_iso), 'isolinux/isolinux.bin', 'isolinux/isolinux.cfg', 'isolinux/mboot.c32', 'isolinux/menu.c32')));
$iso_image ||= "$config_name.iso";
- system_verbose("$CFG::genisoimage -R -b stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -hide-rr-moved -J -joliet-long -o $iso_image -graft-points bin/boot/grub/ $files");
+
+ # Note: We use -U flag below to "Allow 'untranslated' filenames,
+ # completely violating the ISO9660 standards". Without this
+ # option, isolinux is not able to read files names for example
+ # bzImage-3.0.
+ system_verbose("$CFG::genisoimage -R -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -hide-rr-moved -U -o $iso_image -graft-points $files");
print("ISO image created: $builddir/$iso_image\n");
}
return $str
}
-### Qemu
+### Start in Qemu
if (defined $qemu) {
# Qemu
if (defined $iso_image) {
# Boot NOVA with grub (and test the iso image)
- push(@qemu_flags, ('-cdrom', "$config_name.iso"));
+ push(@qemu_flags, ('-cdrom', $iso_image));
} else {
# Boot NOVA without GRUB
my ($dhcpd_pid, $tftpd_pid);
+$tftp=1 if $tftp_port;
+
if (defined $dhcp_tftp)
{
generate_configs("(nd)", $generated, $filename);
# process group (e.g. Ctrl-C on terminal).
$dhcpd_pid = fork();
exec_verbose("sudo dhcpd -d -cf dhcpd.conf -lf dhcpd.leases -pf dhcpd.pid") if ($dhcpd_pid == 0);
- $tftpd_pid = fork();
- exec_verbose("sudo in.tftpd --foreground --secure -v -v -v --pidfile tftpd.pid $builddir") if ($tftpd_pid == 0);
+}
+
+if (defined $dhcp_tftp || defined $tftp) {
+ $tftp_port ||= 69;
+ # Unfortunately, tftpd requires root privileges even with
+ # non-privileged (>1023) port due to initgroups().
+ system_verbose("sudo in.tftpd --listen --secure -v -v -v --pidfile tftpd.pid --address :$tftp_port $builddir");
# Kill server when we die
- $SIG{__DIE__} = sub { system_verbose('sudo pkill --pidfile=dhcpd.pid');
+ $SIG{__DIE__} = sub { system_verbose('sudo pkill --pidfile=dhcpd.pid') if (defined $dhcp_tftp);
system_verbose('sudo pkill --pidfile=tftpd.pid'); };
+
+ # We have to kill tftpd explicitely, because it is not in our process group
+ $SIG{INT} = sub { system_verbose('sudo pkill --pidfile=tftpd.pid'); exit(0); };
+}
+
+### AMT IDE-R
+if (defined $ider) {
+ my $ider_cmd= "amtider -c $iso_image -u $amt_user -p $amt_password $amt_host $amt_port" ;
+ print "novaboot: Running: $ider_cmd\n" =~ s/\Q$amt_password\E/???/r;
+ my $ider_pid = fork();
+ if ($ider_pid == 0) {
+ exec($ider_cmd);
+ die "IDE redirection failed";
+ }
+ # FIXME: This collides with --tftp option. Hopefully, nobody needs
+ # to use both simultaneously.
+ $SIG{__DIE__} = sub { system_verbose('kill $ider_pid'); };
}
-### Serial line or IP relay
+### Reset target (IP relay, AMT, ...)
if (defined $target_reset) {
print "novaboot: Reseting the test box... ";
print "done\n";
}
+### U-boot conversation
if (defined $uboot) {
+ my $uboot_prompt = $uboot || '=> ';
print "novaboot: Waiting for uBoot prompt...\n";
$exp->log_stdout(1);
#$exp->exp_internal(1);
$exp->expect(20,
[qr/Hit any key to stop autoboot:/, sub { $exp->send("\n"); exp_continue; }],
- '=> ') || die "No uBoot prompt deteceted";
- $exp->send("$uboot_init\n") if $uboot_init;
- $exp->expect(10, '=> ') || die "uBoot prompt timeout";
-
- my ($kbin, $kcmd) = split(' ', shift(@$modules), 2);
- my $dtb;
- @$modules = map { if (/\.dtb$/) { $dtb=$_; (); } else { $_ } } @$modules;
- my $initrd = shift @$modules;
-
- my $kern_addr = '800000';
- my $initrd_addr = '-';
- my $dtb_addr = '';
-
- $exp->send("tftp $kern_addr $kbin\n");
- $exp->expect(10,
- [qr/#/, sub { exp_continue; }],
- '=> ') || die "Kernel load failed";
- if (defined $dtb) {
- $dtb_addr = '7f0000';
- $exp->send("tftp $dtb_addr $dtb\n");
- $exp->expect(10,
- [qr/#/, sub { exp_continue; }],
- '=> ') || die "Device tree load failed";
+ $uboot_prompt) || die "No uBoot prompt deteceted";
+ while (@uboot_init) {
+ my $cmd = shift @uboot_init;
+ $exp->send("$cmd\n");
+ $exp->expect(10, $uboot_prompt) || die "uBoot prompt timeout";
}
- if (defined $initrd) {
- $initrd_addr = 'b00000';
- $exp->send("tftp $initrd_addr $initrd\n");
+
+ # Boot the system if there are some load lines in the script
+ if (scalar(@$modules) > 0) {
+ my ($kbin, $kcmd) = split(' ', shift(@$modules), 2);
+ my $dtb;
+ @$modules = map { if (/\.dtb$/) { $dtb=$_; (); } else { $_ } } @$modules;
+ my $initrd = shift @$modules;
+
+ my $kern_addr = '800000';
+ my $initrd_addr = '-';
+ my $dtb_addr = '';
+
+ $exp->send("tftp $kern_addr $kbin\n");
$exp->expect(10,
[qr/#/, sub { exp_continue; }],
- '=> ') || die "Initrd load failed";
+ $uboot_prompt) || die "Kernel load failed";
+ if (defined $dtb) {
+ $dtb_addr = '7f0000';
+ $exp->send("tftp $dtb_addr $dtb\n");
+ $exp->expect(10,
+ [qr/#/, sub { exp_continue; }],
+ $uboot_prompt) || die "Device tree load failed";
+ }
+ if (defined $initrd) {
+ $initrd_addr = 'b00000';
+ $exp->send("tftp $initrd_addr $initrd\n");
+ $exp->expect(10,
+ [qr/#/, sub { exp_continue; }],
+ $uboot_prompt) || die "Initrd load failed";
+ }
+ $exp->send("set bootargs '$kcmd'\n");
+ $exp->expect(5, $uboot_prompt) || die "uBoot prompt timeout";
+ $exp->send("bootm $kern_addr $initrd_addr $dtb_addr\n");
+ $exp->expect(5, "\n") || die "uBoot command timeout";
}
- $exp->send("set bootargs '$kcmd'\n");
- $exp->expect(5, '=> ') || die "uBoot prompt timeout";
- $exp->send("bootm $kern_addr $initrd_addr $dtb_addr\n");
- $exp->expect(5, "\n") || die "uBoot command timeout";
}
+### Serial line interaction
if (defined $exp) {
# Serial line of the target is available
my $interrupt = 'Ctrl-C';
if ($interactive && !@exiton) {
$interrupt = '"~~."';
}
- print "novaboot: Serial line interaction (press $interrupt to interrupt)...\n";
+ my $note = (-t STDIN) ? '' : '- only target->host ';
+ print "novaboot: Serial line interaction $note(press $interrupt to interrupt)...\n";
$exp->log_stdout(1);
if (@exiton) {
$exp->expect(undef, @expect_raw, @exiton);
}
## Kill dhcpc or tftpd
-if (defined $dhcp_tftp) {
+if (defined $dhcp_tftp || defined $tftp) {
die("novaboot: This should kill servers on background\n");
}
=item --no-file-gen
-Do not generate files on the fly (i.e. "<" syntax) except for the
-files generated via "<<WORD" syntax.
+Do not run external commands to generate files (i.e. "<" syntax and
+C<run> keyword). This switch does not influence generation of files
+specified with "<<WORD" syntax.
=item -p, --pulsar[=mac]
used. The I<port> specifies a TCP port for SOL. If not specified, the
default is 16992. Default I<user> is admin.
+=item --ider
+
+Use Intel AMT technology for IDE redirection. This allows the target
+machine to boot from nonvaboot created ISO image.
+
+The experimental I<amtider> utility needed by this option can be
+obtained from https://github.com/wentasah/amtterm.
+
=item --iprelay=I<addr[:port]>
Use TCP/IP relay and serial port to access the target's serial port
be booted via PXE BIOS (or similar mechanism) on the test machine
directly connected by a plain Ethernet cable to your workstation.
-The DHCP and TFTP servers require root privileges and C<novaboot>
+The DHCP and TFTP servers requires root privileges and C<novaboot>
uses C<sudo> command to obtain those. You can put the following to
-I</etc/sudoers> to allow running the necessary commands without
-asking for password.
+I</etc/sudoers> to allow running the necessary commands without asking
+for password.
- Cmnd_Alias NOVABOOT = /bin/ip a add 10.23.23.1/24 dev eth0, /bin/ip l set dev eth0 up, /usr/sbin/dhcpd -d -cf dhcpd.conf -lf dhcpd.leases -pf dhcpd.pid, /usr/sbin/in.tftpd --foreground --secure -v -v -v --pidfile tftpd.pid *, /usr/bin/touch dhcpd.leases, /usr/bin/pkill --pidfile=dhcpd.pid, /usr/bin/pkill --pidfile=tftpd.pid
+ Cmnd_Alias NOVABOOT = /bin/ip a add 10.23.23.1/24 dev eth0, /bin/ip l set dev eth0 up, /usr/sbin/dhcpd -d -cf dhcpd.conf -lf dhcpd.leases -pf dhcpd.pid, /usr/sbin/in.tftpd --listen --secure -v -v -v --pidfile tftpd.pid *, /usr/bin/touch dhcpd.leases, /usr/bin/pkill --pidfile=dhcpd.pid, /usr/bin/pkill --pidfile=tftpd.pid
your_login ALL=NOPASSWD: NOVABOOT
+=item --tftp
+
+Starts a TFTP server on your workstation. This is similar to
+B<--dhcp-tftp> except that DHCP server is not started.
+
+The TFTP server require root privileges and C<novaboot> uses C<sudo>
+command to obtain those. You can put the following to I</etc/sudoers>
+to allow running the necessary commands without asking for password.
+
+ Cmnd_Alias NOVABOOT = /usr/sbin/in.tftpd --listen --secure -v -v -v --pidfile tftpd.pid *, /usr/bin/pkill --pidfile=tftpd.pid
+ your_login ALL=NOPASSWD: NOVABOOT
+
+=item --tftp-port=I<port>
+
+Port to run the TFTP server on. Implies B<--tftp>.
+
=item --iso[=filename]
Generates the ISO image that boots NOVA system via GRUB. If no filename
=item --on, --off
-Switch on/off the target machine. Currently it works only with
-B<--iprelay> or B<--amt>.
+Switch on/off the target machine and exit. The script (if any) is
+completely ignored. Currently it works only with B<--iprelay> or
+B<--amt>.
=item -Q, --qemu[=I<qemu-binary>]
=over 8
-=item --uboot
+=item --uboot[=I<prompt>]
Interact with uBoot bootloader to boot the thing described in the
-novaboot script. Implementation of this option is currently tied to a
-particular board that we use. It may be subject to changes in the
-future!
+novaboot script. I<prompt> specifies the U-Boot's prompt (default is
+"=> ", other common prompts are "U-Boot> " or "U-Boot# ").
+Implementation of this option is currently tied to a particular board
+that we use. It may be subject to changes in the future!
=item --uboot-init
Command(s) to send the U-Boot bootloader before loading the images and
-booting them.
+booting them. This option can be given multiple times. After sending
+commands from each option novaboot waits for U-Boot I<prompt>.
=back
absolute path of the directory containing the interpreted novaboot
script.
+Lines starting with C<run> keyword contain shell commands that are run
+during file generation phase. This is the same as the "< CMD" syntax
+for C<load> keyboard except that the command's output is not
+redirected to a file. The ordering of commands is the same as they
+appear in the novaboot script.
+
Example (Linux):
#!/usr/bin/env novaboot
load bzImage console=ttyS0,115200
+ run make -C buildroot
load rootfs.cpio < gen_cpio buildroot/images/rootfs.cpio "myapp->/etc/init.d/S99myapp"
Example (NOVA User Land - NUL):