* Rewrote the hardware scanner in Perl.

svn path=/nixos/trunk/; revision=10405
This commit is contained in:
Eelco Dolstra 2008-01-30 14:16:38 +00:00
parent c1f619a087
commit 7363895f6d
2 changed files with 174 additions and 144 deletions

View File

@ -0,0 +1,174 @@
#! @perl@ -w
use File::Spec;
use File::Basename;
my @kernelModules = ();
my @initrdKernelModules = ();
# Read a file, returning undef if the file cannot be opened.
sub readFile {
my $filename = shift;
my $res;
if (open FILE, "<$filename") {
my $prev = $/;
undef $/;
$res = <FILE>;
$/ = $prev;
close FILE;
chomp $res;
}
return $res;
}
my $cpuinfo = readFile "/proc/cpuinfo";
sub hasCPUFeature {
my $feature = shift;
return $cpuinfo =~ /^flags\s*:.* $feature( |$)/m;
}
# Detect the number of CPU cores.
my $cpus = scalar (grep {/^processor\s*:/} (split '\n', $cpuinfo));
# CPU frequency scaling. Not sure about this test.
push @kernelModules, "acpi-cpufreq" if hasCPUFeature "acpi";
# Virtualization support?
push @kernelModules, "kvm-intel" if hasCPUFeature "vmx";
push @kernelModules, "kvm-amd" if hasCPUFeature "svm";
# Look at the PCI devices and add necessary modules. Note that most
# modules are auto-detected so we don't need to list them here.
# However, some are needed in the initrd to boot the system.
sub pciCheck {
my $path = shift;
my $vendor = readFile "$path/vendor";
my $device = readFile "$path/device";
my $class = readFile "$path/class";
my $module;
if (-e "$path/driver/module") {
$module = basename `readlink -f $path/driver/module`;
chomp $module;
}
print "$path: $vendor $device $class";
print " $module" if defined $module;
print "\n";
if (defined $module) {
# See the bottom of http://pciids.sourceforge.net/pci.ids for
# device classes.
if (# Mass-storage controller. Definitely important.
$class =~ /^0x01/ ||
# Firewire controller. A disk might be attached.
$class =~ /^0x0c00/ ||
# USB controller. Needed if we want to use the
# keyboard when things go wrong in the initrd.
$class =~ /^0x0c03/
)
{
push @initrdKernelModules, $module;
}
}
}
foreach my $path (glob "/sys/bus/pci/devices/*") {
pciCheck $path;
}
# Idem for USB devices.
sub usbCheck {
my $path = shift;
my $class = readFile "$path/bInterfaceClass";
my $subclass = readFile "$path/bInterfaceSubClass";
my $protocol = readFile "$path/bInterfaceProtocol";
my $module;
if (-e "$path/driver/module") {
$module = basename `readlink -f $path/driver/module`;
chomp $module;
}
print "$path: $class $subclass $protocol";
print " $module" if defined $module;
print "\n";
if (defined $module) {
if (# Mass-storage controller. Definitely important.
$class eq "08" ||
# Keyboard. Needed if we want to use the
# keyboard when things go wrong in the initrd.
($class eq "03" && $protocol eq "01")
)
{
push @initrdKernelModules, $module;
}
}
}
foreach my $path (glob "/sys/bus/usb/devices/*") {
if (-e "$path/bInterfaceClass") {
usbCheck $path;
}
}
# Generate the configuration file.
sub removeDups {
my %seen;
my @res = ();
foreach my $s (@_) {
if (!defined $seen{$s}) {
$seen{$s} = "";
push @res, $s;
}
}
return @res;
}
sub toNixExpr {
my $res = "";
foreach my $s (@_) {
$res .= " \"$s\"";
}
return $res;
}
my $initrdKernelModules = toNixExpr(removeDups @initrdKernelModules);
my $kernelModules = toNixExpr(removeDups @kernelModules);
print <<EOF ;
# This is a generated file. Do not modify!
# Make changes to /etc/nixos/configuration.nix instead.
{
boot = {
initrd = {
extraKernelModules = [ $initrdKernelModules ];
};
kernelModules = [ $kernelModules ];
};
nix = {
maxJobs = $cpus;
};
}
EOF

View File

@ -1,144 +0,0 @@
#! @shell@ -e
kernelModules=
initrdKernelModules=
hasCPUFeature() {
local feature="$1"
cat /proc/cpuinfo | grep -q "^flags.* $feature\( \|$\)"
}
needKernelModule() {
kernelModules="$kernelModules \"$1\""
}
needInitrdKernelModule() {
initrdKernelModules="$initrdKernelModules \"$1\""
}
# Detect the number of CPU cores.
cpus="$(cat /proc/cpuinfo | grep '^processor' | wc -l)"
# CPU frequency scaling. Not sure about this test.
if hasCPUFeature "acpi"; then
needKernelModule "acpi-cpufreq"
fi
# Virtualization support?
if hasCPUFeature "vmx"; then
needKernelModule "kvm-intel"
fi
if hasCPUFeature "svm"; then
needKernelModule "kvm-amd"
fi
# Look at the PCI devices and add necessary modules. Note that most
# modules are auto-detected so we don't need to list them here.
# However, some are needed in the initrd to boot the system.
pciCheck() {
local path="$1"
local vendor="$(cat $path/vendor)"
local device="$(cat $path/device)"
local class="$(cat $path/class)"
local module
if test -e "$path/driver/module"; then
module=$(basename $(readlink -f $path/driver/module))
fi
echo "$path: $vendor $device $class $module"
if test -n "$module"; then
# See the bottom of http://pciids.sourceforge.net/pci.ids for
# device classes.
case $class in
0x01*)
# Mass-storage controller. Definitely important.
needInitrdKernelModule $module
;;
0x0c00*)
# Firewire controller. A disk might be attached.
needInitrdKernelModule $module
;;
0x0c03*)
# USB controller. Needed if we want to use the
# keyboard when things go wrong in the initrd.
needInitrdKernelModule $module
;;
esac
fi
}
for path in /sys/bus/pci/devices/*; do
pciCheck "$path"
done
# Idem for USB devices.
usbCheck() {
local path="$1"
local class="$(cat $path/bInterfaceClass)"
local subclass="$(cat $path/bInterfaceSubClass)"
local protocol="$(cat $path/bInterfaceProtocol)"
local module
if test -e "$path/driver/module"; then
module=$(basename $(readlink -f $path/driver/module))
fi
echo "$path: $class $subclass $protocol $module"
if test -n "$module"; then
# See http://www.linux-usb.org/usb.ids for
# classes/subclasses/protocols.
case $class:$subclass:$protocol in
08:*)
# Mass-storage controller. Definitely important.
needInitrdKernelModule $module
;;
03:*:01)
# Keyboard. Needed if we want to use the
# keyboard when things go wrong in the initrd.
needInitrdKernelModule $module
;;
esac
fi
}
for path in /sys/bus/usb/devices/*; do
if test -e "$path/bInterfaceClass"; then
usbCheck "$path"
fi
done
# Remove duplicate modules. !!! preserve order
kernelModules=$(for i in $kernelModules; do echo $i; done | sort | uniq)
initrdKernelModules=$(for i in $initrdKernelModules; do echo $i; done | sort | uniq)
# Generation the configuration file.
cat <<EOF
# This is a generated file. Do not modify!
# Make changes to /etc/nixos/configuration.nix instead.
{
boot = {
initrd = {
extraKernelModules = [ $(echo $initrdKernelModules) ];
};
kernelModules = [ $(echo $kernelModules) ];
};
nix = {
maxJobs = $cpus;
};
}
EOF