GetOptions ("target|t=s" => \$explicit_target);
# Variables for command line options
-my ($amt, @append, $bender, @chainloaders, $concat, $config_name_opt, $dhcp_tftp, $dump_opt, $dump_config, @exiton, $exiton_timeout, @expect_raw, $final_eol, $gen_only, $grub_config, $grub_prefix, $grub_preamble, $grub2_prolog, $grub2_config, $help, $ider, $interaction, $iprelay, $iprelay_cmd, $iso_image, $interactive, $kernel_opt, $make, $man, $netif, $no_file_gen, $off_opt, $on_opt, $pulsar, $pulsar_root, $qemu, $qemu_append, $qemu_flags_cmd, @remote_cmd, $remote_expect, $remote_expect_silent, $remote_expect_timeout, $reset, @reset_cmd, $reset_send, $rom_prefix, $rsync_flags, @scriptmod, $scons, $serial, $server, $stty, $tftp, $tftp_port, $uboot, %uboot_addr, $uboot_cmd, @uboot_init);
+my ($amt, @append, $bender, @chainloaders, $concat, $config_name_opt, $dhcp_tftp, $dump_opt, $dump_config, @exiton, $exiton_timeout, @expect_raw, $final_eol, $gen_only, $grub_config, $grub_prefix, $grub_preamble, $grub2_prolog, $grub2_config, $help, $ider, $interaction, $iprelay, $iprelay_cmd, $iso_image, $interactive, $kernel_opt, $make, $man, $netif, $no_file_gen, $off_opt, $on_opt, $pulsar, $pulsar_root, $qemu, $qemu_append, $qemu_flags_cmd, @remote_cmd, $remote_expect, $remote_expect_silent, $remote_expect_timeout, $reset, @reset_cmd, $reset_send, $rom_prefix, $rsync_flags, @scriptmod, $scons, $serial, $server, $stty, $tftp, $tftp_port, $uboot, %uboot_addr, $uboot_cmd, @uboot_init, $uboot_stop_key);
my ($target_reset, $target_power_on, $target_power_off);
);
$rsync_flags = '';
$rom_prefix = 'rom://';
-$stty = 'raw -crtscts -onlcr 115200';
+$stty = 'raw -crtscts -onlcr -echo 115200';
$reset = 1; # Reset target by default
$interaction = 1; # Perform target interaction by default
$final_eol = 1;
"prefix|grub-prefix=s" => \$grub_prefix,
"pulsar-root=s" => \$pulsar_root,
"pulsar|p:s" => \$pulsar,
+ "remote-expect=s"=> \$remote_expect,
+ "remote-expect-silent=s"=> sub { $remote_expect=$_[1]; $remote_expect_silent=1; },
+ "remote-expect-timeout=i"=> \$remote_expect_timeout,
"uboot-addr=s" => \%uboot_addr,
"uboot-cmd=s" => \$uboot_cmd,
+ "uboot-stop-key=s" => \$uboot_stop_key,
"uboot-init=s" => sub { push @uboot_init, { command => $_[1] }; },
"uboot:s" => \$uboot,
);
"qemu-append=s" => \$qemu_append,
"qemu-flags|q=s" => \$qemu_flags_cmd,
"remote-cmd=s" => sub { @remote_cmd = ($_[1]); },
- "remote-expect=s"=> \$remote_expect,
- "remote-expect-silent=s"=> sub { $remote_expect=$_[1]; $remote_expect_silent=1; },
- "remote-expect-timeout=i"=> \$remote_expect_timeout,
"reset!" => \$reset,
"reset-cmd=s" => sub { @reset_cmd = ($_[1]); },
"reset-send=s" => \$reset_send,
$hostname = "";
}
my $files = join(" ", map({ ($file) = m/([^ ]*)/; $file; } ( @$modules, @bootloader_configs, @$copy)));
- map({ my $file = (split)[0]; die "$file: $!" if ! -f $file; } @$modules);
+ map({ my $file = (split)[0]; die "Not a file: $file: $!" if ! -e $file || -d $file; } @$modules);
my $istty = -t STDOUT && ($ENV{'TERM'} || 'dumb') ne 'dumb';
my $progress = $istty ? "--progress" : "";
if ($files) {
### Reset target (IP relay, AMT, ...)
if (defined $target_reset && $reset) {
- print STDERR "novaboot: Reseting the test box... ";
+ print STDERR "novaboot: Resetting the test box... ";
&$target_reset();
print STDERR "done\n";
if (defined $exp) {
$exp->log_stdout(1);
#$exp->exp_internal(1);
$exp->expect(20,
- [qr/Hit any key to stop autoboot:/, sub { $exp->send("\n"); exp_continue; }],
+ [qr/Hit any key to stop autoboot:/, sub {
+ $exp->send($uboot_stop_key // "\n");
+ exp_continue; }],
$uboot_prompt) || die "No U-Boot prompt deteceted";
foreach my $cmdspec (@uboot_init) {
my ($cmd, $timeout);
@$modules = map { if (/\.dtb$/) { $dtb=$_; (); } else { $_ } } @$modules;
my $initrd = shift @$modules;
- if (defined $kbin) {
+ if (defined $kbin && $kbin ne '/dev/null') {
die "No '--uboot-addr kernel' given" unless $uboot_addr{kernel};
$exp->send("tftpboot $uboot_addr{kernel} $prefix$kbin\n");
$exp->expect(15,
Configuration file syntax is described in section L</"CONFIGURATION
FILES">.
+Novaboot newcomers may be confused by a large number of configuration
+options. Understanding all these options is not always needed,
+depending on the used setup. The L<figure from the doc directory
+|https://github.com/wentasah/novaboot/blob/master/doc/typical-setups.svg>
+shows different setups that vary in how much effort is needed
+configure novaboot for them. The setups are:
+
+=over 3
+
+=item A: Laptop and target device only
+
+This requires to configure everything on the laptop side, including a
+serial line connection (L</--serial>, L</--remote-cmd>, ...), power
+on/off/reset commands (L</--reset-cmd>, ...), TFTP server
+(L</--server>, L</--prefix>...), device IP addresses, etc.
+
+=item B: Laptop, target device and external TFTP server
+
+Like the previous setup, but the TFTP (and maybe DHCP) configuration
+is handled by a server. Novaboot users need to understand where to
+copy their files to the TFTP server (L</--server>) and which IP
+addresses their target will get, but do not need to configure the
+servers themselves.
+
+=item C: Novaboot server running novaboot-shell
+
+With this setup, the configuration is done on the server. Users only
+need to know the SSH account (L</--ssh>) used to communicate between
+novaboot and novaboot server. The server is implemented as a
+restricted shell (L<novaboot-shell(1)>) on the server. No need to give
+full shell access to novaboot users on the server.
+
+=back
+
=head2 Simple examples of using C<novaboot>:
To boot Linux (files F<bzImage> and F<rootfs.cpio> in current
=item --remote-expect=I<string>
-Wait for reception of I<string> after establishing the remote
-connection. This option is needed when novaboot should wait for
-confirmation before deploying files to the target, e.g. to not
-overwrite other user's files when they are using the target.
+Wait for reception of I<string> after establishing the remote serial
+line connection. Novaboot assumes that after establishing the serial
+line connection, the user running novaboot has exclusive access to the
+target. If establishing of the serial line connection happens
+asynchronously (e.g. running a command remotely via SSH), we need this
+option to wait until the exclusive access is confirmed by the remote
+side.
+
+Depending on target configuration, this option can solve two practical
+problems: 1) Overwriting of files deployed by another user currently
+using the target. 2) Resetting the target board before serial line
+connection is established and thus missing bootloader interaction.
+
+Example of usage with the L<sterm
+tool|https://rtime.felk.cvut.cz/gitweb/sojka/sterm.git>:
+
+ --remote-cmd='ssh -tt example.com sterm -v /dev/ttyUSB0' --remote-expect='sterm: Connected'
=item --remote-expect-silent=I<string>
Disable U-Boot interaction previously enabled with B<--uboot>.
+=item --uboot-stop-key=I<key>
+
+Character, which is sent as a response to U-Boot's "Hit any key to
+stop autoboot" message. The default value is newline, but some devices
+(e.g. TP-Link TD-W8970) require a specific key to be pressed.
+
=item --uboot-init
Command(s) to send the U-Boot bootloader before loading the images and
=item --exiton-timeout=I<seconds>
By default B<--exiton> waits for the string match forever. When this
-option is specified, "exiton" timeouts after the specifies the number of
+option is specified, "exiton" timeouts after the specified number of
seconds and novaboot returns non-zero exit code.
=item -i, --interactive