2008-02-08 15:59:15 +00:00
|
|
|
#! @perl@/bin/perl -w
|
2008-01-30 14:16:38 +00:00
|
|
|
|
|
|
|
use File::Spec;
|
|
|
|
use File::Basename;
|
|
|
|
|
|
|
|
|
2009-08-04 09:50:02 +01:00
|
|
|
my @attrs = ();
|
2008-01-30 14:16:38 +00:00
|
|
|
my @kernelModules = ();
|
|
|
|
my @initrdKernelModules = ();
|
2010-12-09 19:08:33 +00:00
|
|
|
my @modulePackages = ();
|
2008-01-30 14:16:38 +00:00
|
|
|
|
|
|
|
|
2008-02-08 15:59:15 +00:00
|
|
|
sub debug {
|
|
|
|
return unless defined $ENV{"DEBUG"};
|
|
|
|
print STDERR @_;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-01-30 14:16:38 +00:00
|
|
|
# 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.
|
|
|
|
|
2008-01-30 14:50:25 +00:00
|
|
|
my $videoDriver = "vesa";
|
2008-01-30 14:32:02 +00:00
|
|
|
|
2008-01-30 14:16:38 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2008-02-08 15:59:15 +00:00
|
|
|
debug "$path: $vendor $device $class";
|
|
|
|
debug " $module" if defined $module;
|
|
|
|
debug "\n";
|
2008-01-30 14:16:38 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
2008-01-30 14:32:02 +00:00
|
|
|
}
|
|
|
|
|
2010-12-09 19:08:33 +00:00
|
|
|
# broadcom STA driver (wl.ko)
|
|
|
|
# list taken from http://www.broadcom.com/docs/linux_sta/README.txt
|
|
|
|
if ($vendor eq "0x14e4" &&
|
|
|
|
($device eq "0x4311" || $device eq "0x4312" || $device eq "0x4313" ||
|
|
|
|
$device eq "0x4315" || $device eq "0x4327" || $device eq "0x4328" ||
|
|
|
|
$device eq "0x4329" || $device eq "0x432a" || $device eq "0x432b" ||
|
|
|
|
$device eq "0x432c" || $device eq "0x432d" || $device eq "0x4353" ||
|
|
|
|
$device eq "0x4357") )
|
|
|
|
{
|
2010-12-18 17:56:04 +00:00
|
|
|
push @modulePackages, "config.boot.kernelPackages.broadcom_sta";
|
2010-12-09 19:08:33 +00:00
|
|
|
push @kernelModules, "wl";
|
|
|
|
}
|
|
|
|
|
2008-01-30 14:32:02 +00:00
|
|
|
# Can't rely on $module here, since the module may not be loaded
|
|
|
|
# due to missing firmware. Ideally we would check modules.pcimap
|
|
|
|
# here.
|
2009-08-04 09:50:02 +01:00
|
|
|
push @attrs, "networking.enableIntel2200BGFirmware = true;" if
|
2009-01-25 15:48:59 +00:00
|
|
|
$vendor eq "0x8086" &&
|
2008-01-30 14:32:02 +00:00
|
|
|
($device eq "0x1043" || $device eq "0x104f" || $device eq "0x4220" ||
|
|
|
|
$device eq "0x4221" || $device eq "0x4223" || $device eq "0x4224");
|
2008-01-30 14:50:25 +00:00
|
|
|
|
2009-08-04 09:50:02 +01:00
|
|
|
push @attrs, "networking.enableIntel3945ABGFirmware = true;" if
|
2009-01-25 15:48:59 +00:00
|
|
|
$vendor eq "0x8086" &&
|
2008-02-04 10:39:06 +00:00
|
|
|
($device eq "0x4229" || $device eq "0x4230" ||
|
|
|
|
$device eq "0x4222" || $device eq "0x4227");
|
|
|
|
|
2008-01-30 14:50:25 +00:00
|
|
|
# Hm, can we extract the PCI ids supported by X drivers somehow?
|
|
|
|
# cf. http://www.calel.org/pci-devices/xorg-device-list.html
|
2009-06-17 11:41:17 +01:00
|
|
|
$videoDriver = "intel" if $vendor eq "0x8086" &&
|
2008-01-30 14:50:25 +00:00
|
|
|
($device eq "0x1132" ||
|
|
|
|
$device eq "0x2572" ||
|
|
|
|
$device eq "0x2592" ||
|
|
|
|
$device eq "0x2772" ||
|
|
|
|
$device eq "0x2776" ||
|
|
|
|
$device eq "0x2782" ||
|
|
|
|
$device eq "0x2792" ||
|
|
|
|
$device eq "0x2792" ||
|
|
|
|
$device eq "0x27a2" ||
|
|
|
|
$device eq "0x27a6" ||
|
2008-01-30 14:57:13 +00:00
|
|
|
$device eq "0x29a2" ||
|
2008-01-30 14:50:25 +00:00
|
|
|
$device eq "0x3582" ||
|
|
|
|
$device eq "0x7121" ||
|
|
|
|
$device eq "0x7123" ||
|
|
|
|
$device eq "0x7125" ||
|
|
|
|
$device eq "0x7128"
|
|
|
|
);
|
2008-01-30 14:53:06 +00:00
|
|
|
|
|
|
|
# Assume that all NVIDIA cards are supported by the NVIDIA driver.
|
|
|
|
# There may be exceptions (e.g. old cards).
|
|
|
|
$videoDriver = "nvidia" if $vendor eq "0x10de" && $class =~ /^0x03/;
|
2008-01-30 14:16:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2008-02-08 15:59:15 +00:00
|
|
|
debug "$path: $class $subclass $protocol";
|
|
|
|
debug " $module" if defined $module;
|
|
|
|
debug "\n";
|
2008-01-30 14:16:38 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-01-06 20:09:53 +00:00
|
|
|
# Add the modules for all block devices.
|
|
|
|
|
|
|
|
foreach my $path (glob "/sys/class/block/*") {
|
|
|
|
my $module;
|
|
|
|
if (-e "$path/device/driver/module") {
|
|
|
|
$module = basename `readlink -f $path/device/driver/module`;
|
|
|
|
chomp $module;
|
|
|
|
push @initrdKernelModules, $module;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-01-30 14:16:38 +00:00
|
|
|
# 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;
|
|
|
|
}
|
|
|
|
|
2009-01-25 15:48:59 +00:00
|
|
|
sub multiLineList {
|
|
|
|
my $indent = shift;
|
|
|
|
my $res = "";
|
|
|
|
foreach my $s (@_) {
|
2009-08-04 09:50:02 +01:00
|
|
|
$res .= "\n$indent$s";
|
2009-01-25 15:48:59 +00:00
|
|
|
}
|
2009-06-17 11:41:17 +01:00
|
|
|
$res .= "\n$indent";
|
2009-01-25 15:48:59 +00:00
|
|
|
return $res;
|
|
|
|
}
|
|
|
|
|
2008-01-30 14:16:38 +00:00
|
|
|
my $initrdKernelModules = toNixExpr(removeDups @initrdKernelModules);
|
|
|
|
my $kernelModules = toNixExpr(removeDups @kernelModules);
|
2010-12-09 19:08:33 +00:00
|
|
|
my $modulePackages = toNixExpr(removeDups @modulePackages);
|
2009-08-04 09:50:02 +01:00
|
|
|
my $attrs = multiLineList(" ", removeDups @attrs);
|
2008-01-30 14:16:38 +00:00
|
|
|
|
|
|
|
print <<EOF ;
|
2009-06-17 11:41:17 +01:00
|
|
|
# This is a generated file. Do not modify!
|
|
|
|
# Make changes to /etc/nixos/configuration.nix instead.
|
2010-12-18 17:56:04 +00:00
|
|
|
{ config, pkgs, modulesPath, ... }:
|
2010-09-25 10:32:37 +01:00
|
|
|
|
2008-01-30 14:16:38 +00:00
|
|
|
{
|
2010-09-25 10:32:37 +01:00
|
|
|
require = [
|
2010-09-25 10:33:13 +01:00
|
|
|
"\${modulesPath}/profiles/@profile@.nix"
|
2010-09-25 10:32:37 +01:00
|
|
|
"\${modulesPath}/installer/scan/not-detected.nix"
|
|
|
|
];
|
|
|
|
|
2010-12-18 17:56:04 +00:00
|
|
|
boot.initrd.kernelModules = [ $initrdKernelModules ];
|
|
|
|
boot.kernelModules = [ $kernelModules ];
|
|
|
|
boot.extraModulePackages = [ $modulePackages ];
|
2008-01-30 14:16:38 +00:00
|
|
|
|
2009-06-17 11:41:17 +01:00
|
|
|
nix.maxJobs = $cpus;
|
2008-01-30 14:32:02 +00:00
|
|
|
|
2009-06-17 11:41:17 +01:00
|
|
|
services.xserver.videoDriver = "$videoDriver";
|
2009-08-04 09:50:02 +01:00
|
|
|
$attrs
|
2008-01-30 14:16:38 +00:00
|
|
|
}
|
|
|
|
EOF
|