📄 mknbi.pl
字号:
$setupfile = "$libdir/" . ($elfformat ? "first-elf.dos" : "first.dos"); $#ARGV >= 0 or die "Usage: $0 floppyimage\n"; return unless check_file($setupfile, $ARGV[0]); $module->add_header("mknbi-dos-$version", $relocseg, $relocseg + ($elfformat ? 0x300 : 0x200), 0); $setupdesc = { file => $setupfile, segment => $relocseg + 0x200, maxlen => 8192, id => 16 }; die "Ramdisk base should be of the form 0xNNNNNNNN (linear hex address)\n" if (defined($rdbase) and $rdbase !~ /^0x[\da-fA-F]{1,8}$/); $floppydesc = { file => $ARGV[0], segment => (defined($rdbase) ? (hex($rdbase) >> 4) : 0x11000), id => 17, end => 1 }; $module->add_segment($setupdesc); $module->peek_file($floppydesc, \$bootblock, 512) == 512 or die "Error reading boot sector of $ARGV[0]\n"; ($usedsize, $declsize, $firsttracksize, $geom_string, $fstype) = &get_geom($ARGV[0], \$bootblock); $firsttrackdesc = { align => $firsttracksize }; $$floppydesc{'fromoff'} = 512; $$floppydesc{'len'} = $usedsize; $$floppydesc{'len'} += $firsttracksize if $simhd; $$floppydesc{'maxlen'} = $declsize; $geom_string = &mod_geom_string($geom_string) if $simhd; $module->add_segment($floppydesc, $geom_string); $module->dump_segments(); $module->copy_file($setupdesc); if ($simhd) { $$firsttrackdesc{'string'} = &make_mbr($geom_string, $fstype); $module->copy_string($firsttrackdesc); } # write out modified bootblock, not the one in the file $bootdesc = { string => $bootblock }; $module->copy_string($bootdesc); # Restore correct value of len and account for bootblock skipped $$floppydesc{'len'} = $usedsize - 512; $module->copy_file($floppydesc);}sub mknbi_menu ($){ my ($module) = @_; my ($menudesc, $datadesc); $#ARGV >= -1 or die "Usage: mk$format-menu [menudata]\n"; print STDERR "Warning: mk$format-menu requires Etherboot 5.0 or later\n"; return unless check_file("$libdir/menu"); # $progreturns == 1 $module->add_pm_header("mknbi-menu-$version", $relocseg + 0x0, 0x60000, 1); $menudesc = { file => "$libdir/menu", segment => 0x6000, maxlen => 0x10000, id => 16 }; $module->add_segment($menudesc); if ($#ARGV >= 0) { return unless check_file($ARGV[0]); $datadesc = { file => $ARGV[0], segment => 0x7000, maxlen => 0x10000, id => 17, end => 1 }; $module->add_segment($datadesc); } else { $$menudesc{'end'} = 1; } $module->dump_segments(); $module->copy_file($menudesc); $module->copy_file($datadesc) if ($#ARGV >= 0);}sub mknbi_nfl ($){ my ($module) = @_; my ($menudesc, $datadesc); $#ARGV >= -1 or die "Usage: mk$format-nfl [menudata]\n"; print STDERR "Warning: mk$format-nfl requires Etherboot 5.0 or later\n"; return unless check_file("$libdir/nfl"); # $progreturns == 1 $module->add_pm_header("mknbi-nfl-$version", $relocseg + 0x0, 0x60000, 1); $menudesc = { file => "$libdir/nfl", segment => 0x6000, maxlen => 0x10000, id => 16 }; $module->add_segment($menudesc); if ($#ARGV >= 0) { return unless check_file($ARGV[0]); $datadesc = { file => $ARGV[0], segment => 0x7000, maxlen => 0x10000, id => 17, end => 1 }; $module->add_segment($datadesc); } else { $$menudesc{'end'} = 1; } $module->dump_segments(); $module->copy_file($menudesc); $module->copy_file($datadesc) if ($#ARGV >= 0);}## Packing of LUA program:# LUA version as network int32, i.e. 4.0.1.0# progname rounded to int32 boundary# length of program as network int32# program#sub read_lua_prog ($) { my ($progfile) = @_; open(P, $progfile) or die "Shouldn't happen, we already did check_file!\n"; # remove all but last component of filename $progfile =~ s:.*/::; $progfile .= "\x00"; local $/; local $_ = <P>; close(P); my $len = length($progfile); $len = ($len + 3) & ~0x3; return (pack("Na${len}Na*", LUA_VERSION, $progfile, length($_), $_));}sub mkelf_lua ($){ my ($module) = @_; my ($menudesc, $datadesc); $format eq 'elf' or die "Only ELF images are catered for\n"; $#ARGV >= 0 or die "Usage: mkelf-lua luaprog\n"; print STDERR "Warning: mkelf-lua requires Etherboot 5.0 or later\n"; return unless check_file("$libdir/lua", $ARGV[0]); # $progreturns == 1 $module->add_pm_header("mkelf-lua-$version", 0x7c0, 0x60000, 1); $menudesc = { file => "$libdir/lua", segment => 0x6000, maxlen => 0x20000, id => 16 }; $module->add_segment($menudesc); my $progstring = &read_lua_prog($ARGV[0]); my $progdesc = { string => $progstring, segment => 0x8000, maxlen => 0x4000, id => 17, end => 1 }; $module->add_segment($progdesc); $module->dump_segments(); $module->copy_file($menudesc); $module->copy_string($progdesc);}$libdir = '@@LIBDIR@@'; # where config and auxiliary files are stored$version = '@@VERSION@@';$showversion = '';$simhd = 0;$dishd = 0;$squashfd = 1;$relocsegstr = '0x9000';$progreturns = 0;GetOptions('format=s' => \$format, 'target=s' => \$target, 'output=s' => \$output, 'param=s' => \$param, 'append=s' => \$append, 'rootdir=s' => \$rootdir, 'rootmode=s' => \$rootmode, 'ip=s' => \$ip, 'rdbase=s' => \$rdbase, 'harddisk!' => \$simhd, 'disableharddisk!' => \$dishd, 'squash!' => \$squashfd, 'first32:s' => \$first32, 'progreturns!' => \$progreturns, 'relocseg=s' => \$relocsegstr, 'version' => \$showversion);if ($showversion) { print STDERR "$version\n"; exit 0;}if (defined($ENV{LANG}) and $ENV{LANG} =~ /\.UTF-8$/i) { print STDERR <<'EOF';Warning: Perl 5.8 may have a bug that affects handing of strings in Unicodelocales that may cause misbehaviour with binary files. To work around thisproblem, set $LANG to not have a suffix of .UTF-8 before running this program.EOF}$0 =~ /mk([a-z]*)-([a-z]+)$/ and ($format = $1, $target = $2);if (!defined($format)) { print STDERR "No format specified with program name or --format=\n"; exit 1;}if (!defined($target)) { print STDERR "No target specified with program name or --target=\n"; exit 1;}if (defined($output)) { die "$output: $!\n" unless open(STDOUT, ">$output");}binmode(STDOUT);if ($format eq 'nbi') { $first32 = '' if !defined($first32); if ($target ne 'rom' and $target ne 'dos' and $target ne 'fdos') { print STDERR "mkelf-$target is preferred in future instead of mknbi-$target\n"; } $module = Nbi->new($libdir);} elsif ($format eq 'elf') { $first32 = '' if !defined($first32); $module = Elf->new($libdir); die "Output must be file\n" unless (seek(STDOUT, 0, SEEK_SET));} else { die "Format $format not supported\n";}if ($relocsegstr eq '0x9000' or $relocsegstr eq '0x8000') { $relocseg = hex($relocsegstr);} else { print STDERR "relocseg must be 0x9000 or 0x8000 only, setting to 0x9000\n"; $relocseg = 0x9000;}if ($target eq 'rom') { &mknbi_rom($module);} elsif ($target eq 'img') { &mkelf_img($module);} elsif ($target eq 'linux') { &mknbi_linux($module);} elsif ($target eq 'fdos') { if ($simhd and $dishd) { print STDERR "Warning: --harddisk and --disableharddisk are incompatible\n"; } &mknbi_fdos($module);} elsif ($target eq 'dos') { if ($simhd and $dishd) { print STDERR "Warning: --harddisk and --disableharddisk are incompatible\n"; } &mknbi_dos($module);} elsif ($target eq 'menu') { &mknbi_menu($module);} elsif ($target eq 'nfl') { &mknbi_nfl($module);} elsif ($target eq 'lua') { &mkelf_lua($module);} else { print STDERR "Target $target not supported\n"; exit;}$module->finalise_image();close(STDOUT);exit 0;__END__=head1 NAMEmknbi - make network bootable image=head1 SYNOPSISB<mknbi> --versionB<mknbi> --format=I<format> --target=I<target> [--output=I<outputfile>] I<target-specific-arguments>B<mkelf-linux> [--output=I<outputfile>] I<kernelimage> [I<ramdisk>]B<mknbi-linux> [--output=I<outputfile>] I<kernelimage> [I<ramdisk>]B<mknbi-rom> [--output=I<outputfile>] I<.z?rom-file>B<mkelf-img> [--output=I<outputfile>] I<.z?img-file>B<mkelf-menu> [--output=I<outputfile>] [I<dataimage>]B<mknbi-menu> [--output=I<outputfile>] [I<dataimage>]B<mkelf-nfl> [--output=I<outputfile>] [I<dataimage>]B<mknbi-nfl> [--output=I<outputfile>] [I<dataimage>]B<mkelf-lua> [--output=I<outputfile>] I<luabin>B<mknbi-fdos> [--output=I<outputfile>] I<kernel.sys floppyimage>B<mknbi-dos> [--output=I<outputfile>] I<floppyimage>=head1 DESCRIPTIONB<mknbi> is a program that makes network bootable images for variousoperating systems suitable for network loading by Etherboot or Netboot,which are ROM boot loaders. If you are looking to boot using PXE, lookno further, mknbi is not what you want. You probably want something likePXELINUX which is part of the SYSLINUX package.B<mknbi> --version prints the current version. Use this before reportingproblems.B<mknbi> can be invoked with the B<--format> and B<--target> options orlinks can be made to it under format and target specific names. E.g.mkelf-linux is the same as mknbi --format=elf --target=linux.B<--format>=I<format> Specify the format of the output. Currentlyavailable are nbi and elf. ELF format only works with linux and menu.Otherwise the invocation is the same as for mknbi. In discussions below,the mknbi form is used.B<--target>=I<target> Specify the target binary. Currently available arelinux, menu, rom, fdos and dos. B<mknbi> is not needed for bootingFreeBSD.B<--output=>I<outputfile> Specify the output file, can be used withall variants. Stdout is the default.The package must be installed in the destination location before theexecutables can be run, because it looks for library files.Each of the variants will be described separately.=head1 MKELF-LINUXB<mkelf-linux> and B<mknbi-linux> makes a boot image from a Linux kernelimage, either a zImage or a bzImage.=head1 MKELF-LINUX OPTIONSB<--param=>I<string> Replace the default parameter string with thespecified one. This option overrides all the following options so youshould know what you are doing.B<--append>=I<string> Appends the specified string to the existingparameter string. This option operates after the other parameter optionshave been evaluated.B<--rootdir>=I<rootdir> Define name of directory to mount via NFS fromthe boot server.In the absence of this option, the default is to use the directoryC</tftpboot/>I<%s>, with the I<%s> representing the hostname orIP-address of the booting system, depending on whether the hostnameattribute is present in the BOOTP/DHCP reply.If C<rom> is given, and if the BOOTP/DHCP server is able to handle the RFC 1497extensions, the value of the rootpath option is used as the root directory.If the name given to the option starts with C</dev/>, the correspondingdevice is used as the root device, and no NFS directory will be mounted.B<--rootmode>=C<ro|rw> Defines whether the root device will be mountedread-only or read-write respectively. Without this parameter, thedefault is C<rw>.B<--ip=>I<string> Define client and server IP addresses.In the absence of this option no IP addresses are defined, and thekernel will determine the IP addresses by itself, usually by using DHCP,BOOTP or RARP. Note that the kernel's query is I<in addition to> thequery made by the bootrom, and requires the IP: kernel levelautoconfiguration (CONFIG_IP_PNP) feature to be included in the kernel.Important note: In Linux kernels 2.2.x where x >= 18, and 2.4.x where x>= 5, it is B<necessary> to specify one of the enabling options in thenext paragraph to cause the IP autoconfiguration to be activated.Unlike in previous kernels, IP autoconfiguration does not happen bydefault. Also note that IP autoconfiguration and NFSroot are likely togo away in Linux 2.6 and that userspace IP configuration methods usingramdisk and userspace DHCP daemons are preferred now.If one of the following: C<off, none, on, any, dhcp, bootp, rarp, both>,is given, then the option will be passed unmodified to the kernel andcause that autoconfig option to be chosen.If C<rom> is given as the argument to this option, all necessary IPaddresses for NFS root mounting will be inherited from the BOOTP/DHCPanswer the bootrom got from the server.It's also possible to define the addresses during compilation of the bootimage. Then, all addresses must be separated by a colon, and ordered inthe following way:C<--ip=>I<client:server:gateway:netmask:hostname[:dev[:proto]]>Using this option B<mkelf-linux> will automatically convert system namesinto decimal IP addresses for the first three entries in this string.The B<hostname> entry will be used by the kernel to set the host name ofthe booted Linux diskless client. When more than one network interfaceis installed in the diskless client, it is possible to specify the nameof the interface to use for mounting the root directory via NFS bygiving the optional value C<dev>. This entry has to start with thestring C<eth> followed by a number from 0 to 9. However, if only one
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -