#!/usr/bin/perl -w # $Id: newkern,v 1.7 2004/04/14 03:43:14 candy Exp candy $ # GENERIC に # デバイスやオプションを足したり引いたりして、 # 新しいカーネルコンフィグファイルを作る。 # -d -D デバイスの追加・削除 # -o -O オプションの追加・削除 # -p -P 仮想デバイスの追加・削除 # -C : card # -F : ipfw # -M : MP use strict; use Getopt::Std; my $version = "0.8091"; use vars qw($opt_c); # cpu use vars qw($opt_C); # enable card use vars qw($opt_d); # add device use vars qw($opt_D); # remove device use vars qw($opt_F); # enable IPFIREWALL use vars qw($opt_U); # enable umass use vars qw($opt_i); # ident use vars qw($opt_v); # verbose use vars qw($opt_v); # verbose use vars qw($opt_o); # add option use vars qw($opt_O); # remove option use vars qw($opt_p); # add pseudo-device use vars qw($opt_P); # remove pseudo-device use vars qw($opt_M); # SMP use vars qw($opt_V); my(%devstd, %devdel, %devadd); my(%pdevdel, %pdevadd); my(%optstd, %optdel, %optadd); my(%cpu); # device : デフォルト削除。 # devadd にあれば消して、置き換える。 # devdel にあれば消す。 # devstd にあれば残す。 my $dev_std = "isa,pci,fdc0,fd0," . "ata0,ata1,ata,atadisk,atapicd," . "atkbdc0,atkbd0,psm0,vga0," . "sc0,npx0,apm0," . "sio0,sio1," . "miibus,fxp,xl," . "uhci,ohci,usb,ukbd,ums," . ""; my $dev_std_add = "atkbd0\tat atkbdc? irq 1 flags 0x0," . ""; # pseudo-device : デフォルト残す。 # pdev_std_add にあれば消して置き換える。 # pdev_std_del にあれば消す。 # my $pdev_std_del = "sl,ppp,tun,gif,faith," . ""; my $pdev_std_add = ""; # options : デフォルト残す。 # opt_std_add にあれば消して置き換える。 # opt_std_del にあれば消す。 my $opt_std_add = "SCSI_DELAY=1000," . "CLK_USE_I8254_CALIBRATION," . "CLK_USE_TSC_CALIBRATION," . "SC_DISABLE_REBOOT," . ""; my $opt_std_del = "MATH_EMULATE," . ""; # # # my $opt_ipfw = "IPFIREWALL," . "IPFIREWALL_VERBOSE," . "IPFIREWALL_FORWARD," . "IPFIREWALL_VERBOSE_LIMIT=100," . "IPFIREWALL_DEFAULT_TO_ACCEPT," . "IPDIVERT," . "DUMMYNET," . "IPV6FIREWALL," . "IPV6FIREWALL_DEFAULT_TO_ACCEPT," . "IPV6FIREWALL_VERBOSE," . "IPV6FIREWALL_VERBOSE_LIMIT=100," . ""; my $opt_SMP = "SMP," . "APIC_IO," . ""; my $ndev_SMP = "apm0"; my $dev_CARD = "apm0\tat nexus? flags 0x20," . "card," . "pcic0\tat isa? irq 0 port 0x3e0 iomem 0xd0000," . "pcic1\tat isa? irq 0 port 0x3e2 iomem 0xd4000 disable," . "ed0\tat isa? disable port 0x280 irq 10 iomem 0xd8000," . "awi," . "wi," . ""; ; my $dev_UMASS = "umass," . "scbus," . "da," . "pass" . ""; sub nz($) { return defined($_[0]) ? $_[0] : ""; } sub getident() { my $h = `hostname -s`; chomp($h); $h =~ tr/a-z/A-Z/; return $h; } sub getcpu() { my $cpu = ""; my $f = "/var/run/dmesg.boot"; if (open(DMSG, $f)) { my(@v, @w); @v = ; close(DMSG); @w = grep(/^CPU:/, @v); if (defined($w[0])) { $cpu = $w[0]; chomp($cpu); $cpu =~ s/.* ([0-9]+)-class CPU.*/I$1/; $cpu .= "_CPU"; } } else { printf("%s: $!\n", $f); } return $cpu; } sub devparse($) { my($dev, @v, $i) = @_; $dev =~ s/,$//; @v = split(/,/, $dev); return @v; } sub devadd($@) { my($ls, @dev, $i, $k, $v) = @_; for ($i = 0; $i < $#dev + 1; $i++) { $k = $dev[$i]; $k =~ s/\s.*//; $v = substr($dev[$i], length($k)); $ls->{$k} = nz($v); } } sub opparse($) { my($op, @v, $i) = @_; $op =~ s/,$//; @v = split(/,/, $op); return @v; } sub opadd($@) { my($ls, @op, $i, @k) = @_; for ($i = 0; $i < $#op + 1; $i++) { @k = split(/=/, $op[$i]); $ls->{$k[0]} = nz($k[1]); } } sub print_opt() { my $k; printf("#device: "); foreach $k (sort keys %devstd) { printf(" %s%s", $k, $devstd{$k}); } printf("\n"); printf("#-d "); foreach $k (sort keys %devadd) { printf("%s%s,", $k, $devadd{$k}); } printf("\n"); printf("#-D "); foreach $k (sort keys %devdel) { printf("%s%s,", $k, $devdel{$k}); } printf("\n"); printf("#-o "); foreach $k (sort keys %optadd) { printf("%s%s%s,", $k, ($optadd{$k} ne "" ? "=" : ""), $optadd{$k}); } printf("\n"); printf("#-O "); foreach $k (sort keys %optdel) { printf("%s%s%s,", $k, ($optdel{$k} ne "" ? "=" : ""), $optdel{$k}); } printf("\n"); printf("#-p "); foreach $k (sort keys %pdevadd) { printf("%s%s,", $k, $pdevadd{$k}); } printf("\n"); printf("#-P "); foreach $k (sort keys %pdevdel) { printf("%s%s,", $k, $pdevdel{$k}); } printf("\n"); } sub setup() { devadd(\%devstd, opparse($dev_std)); devadd(\%devadd, opparse($dev_std_add)); devadd(\%pdevdel, opparse($pdev_std_del)); devadd(\%pdevadd, opparse($pdev_std_add)); opadd(\%optdel, opparse($opt_std_del)); opadd(\%optadd, opparse($opt_std_add)); if ($opt_F) { opadd(\%optadd, opparse($opt_ipfw)); } if ($opt_M) { opadd(\%optadd, opparse($opt_SMP)); devadd(\%devdel, opparse($ndev_SMP)); } if ($opt_C) { devadd(\%devadd, opparse($dev_CARD)); } if ($opt_U) { devadd(\%devadd, opparse($dev_UMASS)); } } sub nain($$$$$$$$) { my($ident, $cpu, $dev_add, $dev_del, $pdev_add, $pdev_del, $opt_add, $opt_del) = @_; my($line, $dev, $nego, $negp); my(%dev, %opt, %pdev); devadd(\%devadd, opparse($dev_add)); devadd(\%devdel, opparse($dev_del)); devadd(\%pdevadd, opparse($pdev_add)); devadd(\%pdevdel, opparse($pdev_del)); opadd(\%optadd, opparse($opt_add)); opadd(\%optdel, opparse($opt_del)); opadd(\%cpu, opparse($cpu)); print_opt(); while ($line = <>) { my @v = split(/\s+/, $line); if (defined($v[0]) && defined($v[1])) { my($op, $id) = ($v[0], $v[1]); if ($op eq "ident") { printf("ident\t\t%s\n", $ident); } elsif ($op eq "cpu") { if (!defined($cpu{$id})) { printf("#"); } print $line; } elsif ($op eq "device" || $op eq "#device") { if (defined($devadd{$id})) { printf("device\t\t%s%s\n", $id, $devadd{$id}); delete($devadd{$id}); } elsif (defined($devdel{$id})) { # delete ($op !~ /^#/) && printf("#"); printf $line; } elsif (defined($devstd{$id})) { printf $line; } else { # delete ($op !~ /^#/) && printf("#"); printf("%s", $line); } } elsif ($op eq "pseudo-device" || $op eq "#pseudo-device") { if (defined($pdevadd{$id})) { printf("pseudo-device\t%s%s\n", $id, $pdevadd{$id}); delete($pdevadd{$id}); } elsif (defined($pdevdel{$id})) { # delete ($op !~ /^#/) && printf("#"); printf("%s", $line); } else { print $line; } } elsif ($op eq "options" || $op eq "#options") { $id =~ s/=.*//; if (defined($optadd{$id})) { if ($optadd{$id} ne "") { printf("options \t%s=%s\n", $id, $optadd{$id}); } else { printf("options \t%s\n", $id); } delete($optadd{$id}); } elsif (defined($optdel{$id})) { # delete ($op !~ /^#/) && printf("#"); printf("%s", $line); } else { print $line; } } else { print $line; } } } { my($id); foreach $id (sort keys %devadd) { printf("device\t\t%s%s\n", $id, $devadd{$id}); } foreach $id (sort keys %pdevadd) { printf("device\t\t%s%s\n", $id, $pdevadd{$id}); } foreach $id (sort keys %optadd) { if ($optadd{$id} ne "") { printf("options \t%s=%s\n", $id, $optadd{$id}); } else { printf("options \t%s\n", $id); } } } } sub main() { my($ex); $ex = 1; my $i; printf("# $0"); for ($i = 0; $i <= $#ARGV; $i++) { printf(" %s", $ARGV[$i]); } printf("\n"); getopts('c:Cd:D:Fi:Mo:O:p:P:UvV'); if ($opt_V) { printf(STDERR << "END"); usage: $0 [option] [file] Generates a new kernel config file from GENERIC. version $version option: -C Enable CARD/WIRELESS. -F Enable IPFIREWALL and IPV6FIREWALL. -M Enable SMP and APIC_IO. Disable amp0. -U Enable umass. -c I386_CPU Specifiy `cpu'. -d device,.. Enable devices. -D device,... Disable devices. -i NAME Specify `ident'. -o OPTION,... Enable OPTIONs. -O OPTION,... Disable OPTIONs. -p pdev,... Enable pseudo-devices. -P pdev,... Disable pseudo-devices. -v verbose -V usage END } else { my($ident, $cpu); $ex = 0; $ident = defined($opt_i) ? $opt_i : getident(); $cpu = defined($opt_c) ? $opt_c : getcpu(); setup(); printf("# Version $version\n"); nain($ident, $cpu, nz($opt_d), nz($opt_D), nz($opt_p), nz($opt_P), nz($opt_o), nz($opt_O)); } return $ex; } exit main();