summaryrefslogtreecommitdiffstats
path: root/usr.sbin/sysinstall
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2006-03-08 18:02:32 +0000
committersam <sam@FreeBSD.org>2006-03-08 18:02:32 +0000
commitfa1fbfedc2f06342ca8bbae5b057d8bd2c14cc59 (patch)
tree87198eeaccc5a4734146e5e9aa6881c4854232fe /usr.sbin/sysinstall
parentb19c8d2fcc1540312b520fc757d445026667a6ac (diff)
downloadFreeBSD-src-fa1fbfedc2f06342ca8bbae5b057d8bd2c14cc59.zip
FreeBSD-src-fa1fbfedc2f06342ca8bbae5b057d8bd2c14cc59.tar.gz
Revamp base system packaging of kernels to enable up/smp selection
at runtime and to support distributing additional kernels: o remove kernel from the base tarball o add new kernel tarballs o build + package both SMP and GENERIC kernels when an <arch>/conf/SMP config file is present o add sysinstall support for multiple kernels o update sysinstall to probe for the number of cpus on a system and auto-select smp/up kernel accordingly o add a post-kernels install hook to fixup /boot/kernel o add -ldevinfo to boot crunch for sysinstall's cpu probing logic Notes: 1. On HEAD this code is not currently used because GENERIC kernels include SMP. This work is mainly intended for RELENG_6 where the GENERIC kernel is UP. If HEAD changes to match then just enable WITH_SMP in sysinstall/Makefile. 2. The cpu probing support is done with acpi and MPTable; this means some systems will require work for auto-detection to work. 3. The handling of /boot/kernel may need to be revisited; for now we rename one kernel at the last moment (SMP if installed, otherwise GENERIC). There are other, possibly better, approaches. Lots of help from ru, emaste, scottl, and jhb.
Diffstat (limited to 'usr.sbin/sysinstall')
-rw-r--r--usr.sbin/sysinstall/Makefile30
-rw-r--r--usr.sbin/sysinstall/acpi.c356
-rw-r--r--usr.sbin/sysinstall/acpidump.h177
-rw-r--r--usr.sbin/sysinstall/biosmptable.c274
-rw-r--r--usr.sbin/sysinstall/dist.c112
-rw-r--r--usr.sbin/sysinstall/dist.h8
-rw-r--r--usr.sbin/sysinstall/install.c36
-rw-r--r--usr.sbin/sysinstall/menus.c48
-rw-r--r--usr.sbin/sysinstall/sysinstall.h13
9 files changed, 1041 insertions, 13 deletions
diff --git a/usr.sbin/sysinstall/Makefile b/usr.sbin/sysinstall/Makefile
index 751d10c..c735c26 100644
--- a/usr.sbin/sysinstall/Makefile
+++ b/usr.sbin/sysinstall/Makefile
@@ -23,6 +23,36 @@ CFLAGS+= -I${.CURDIR}/../../gnu/lib/libdialog -I.
DPADD= ${LIBDIALOG} ${LIBNCURSES} ${LIBUTIL} ${LIBDISK} ${LIBFTPIO}
LDADD= -ldialog -lncurses -lutil -ldisk -lftpio
+#
+# When distributions have both UP and SMP kernels sysinstall
+# will probe for the number of cpus on the target machine and
+# automatically select which is appropriate. This can be overridden
+# through the menus or both kernels can be installed (with the
+# most "appropriate" one setup as /boot/kernel). For now this
+# is done for i386 and amd64; for other systems support must be
+# added to identify the cpu count if acpi and MPTable probing
+# is insufficient.
+#
+# The unmber of cpus probed is passed through the environment in
+# VAR_NCPUS ("ncpus") to scripts.
+#
+# Note that WITH_SMP is a compile time option that enables the
+# builtin menus for the SMP kernel configuration. If this kernel
+# is not built (see release/Makefile) then this should not be
+# enabled as sysinstall may try to select an SMP kernel config
+# where none is available. This option should not be needed--we
+# should probe for an SMP kernel in the distribution but doing
+# that is painful because of media changes and the structure of
+# sysinstall so for now it's a priori.
+#
+.if ${MACHINE_ARCH} == "i386" || ${MACHINE_ARCH} == "amd64"
+SRCS+= acpi.c biosmptable.c
+# NB: HEAD has SMP in GENERIC so only one kernel
+#CFLAGS+=-DWITH_SMP
+DPADD+= ${LIBDEVINFO}
+LDADD+= -ldevinfo
+.endif
+
CLEANFILES= makedevs.c rtermcap
CLEANFILES+= keymap.tmp keymap.h countries.tmp countries.h
diff --git a/usr.sbin/sysinstall/acpi.c b/usr.sbin/sysinstall/acpi.c
new file mode 100644
index 0000000..4a375a1
--- /dev/null
+++ b/usr.sbin/sysinstall/acpi.c
@@ -0,0 +1,356 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/endian.h>
+#include <sys/mman.h>
+#include <sys/queue.h>
+#include <sys/stat.h>
+#include <sys/sysctl.h>
+#include <sys/wait.h>
+#include <assert.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <paths.h>
+#include <devinfo.h>
+
+#include "acpidump.h"
+#include "sysinstall.h"
+
+static void acpi_handle_apic(struct ACPIsdt *sdp);
+static struct ACPIsdt *acpi_map_sdt(vm_offset_t pa);
+static void acpi_handle_rsdt(struct ACPIsdt *rsdp);
+static struct acpi_user_mapping *acpi_user_find_mapping(vm_offset_t, size_t);
+static void * acpi_map_physical(vm_offset_t, size_t);
+
+/* Size of an address. 32-bit for ACPI 1.0, 64-bit for ACPI 2.0 and up. */
+static int addr_size;
+
+static int ncpu;
+
+static void
+acpi_handle_apic(struct ACPIsdt *sdp)
+{
+ struct MADTbody *madtp;
+ struct MADT_APIC *mp;
+ struct MADT_local_apic *apic;
+ struct MADT_local_sapic *sapic;
+
+ madtp = (struct MADTbody *) sdp->body;
+ mp = (struct MADT_APIC *)madtp->body;
+ while (((uintptr_t)mp) - ((uintptr_t)sdp) < sdp->len) {
+ switch (mp->type) {
+ case ACPI_MADT_APIC_TYPE_LOCAL_APIC:
+ apic = &mp->body.local_apic;
+ msgDebug("MADT: Found CPU APIC ID %d %s\n",
+ apic->cpu_id,
+ apic->flags & ACPI_MADT_APIC_LOCAL_FLAG_ENABLED ?
+ "enabled" : "disabled");
+ if (apic->flags & ACPI_MADT_APIC_LOCAL_FLAG_ENABLED)
+ ncpu++;
+ break;
+ case ACPI_MADT_APIC_TYPE_LOCAL_SAPIC:
+ sapic = &mp->body.local_sapic;
+ msgDebug("MADT: Found CPU SAPIC ID %d %s\n",
+ sapic->cpu_id,
+ sapic->flags & ACPI_MADT_APIC_LOCAL_FLAG_ENABLED ?
+ "enabled" : "disabled");
+ /* XXX is enable flag the same? */
+ if (sapic->flags & ACPI_MADT_APIC_LOCAL_FLAG_ENABLED)
+ ncpu++;
+ break;
+ default:
+ break;
+ }
+ mp = (struct MADT_APIC *) ((char *)mp + mp->len);
+ }
+}
+
+static int
+acpi_checksum(void *p, size_t length)
+{
+ u_int8_t *bp;
+ u_int8_t sum;
+
+ bp = p;
+ sum = 0;
+ while (length--)
+ sum += *bp++;
+
+ return (sum);
+}
+
+static struct ACPIsdt *
+acpi_map_sdt(vm_offset_t pa)
+{
+ struct ACPIsdt *sp;
+
+ sp = acpi_map_physical(pa, sizeof(struct ACPIsdt));
+ if (sp != NULL)
+ sp = acpi_map_physical(pa, sp->len);
+ return (sp);
+}
+
+static void
+acpi_handle_rsdt(struct ACPIsdt *rsdp)
+{
+ struct ACPIsdt *sdp;
+ vm_offset_t addr;
+ int entries, i;
+
+ entries = (rsdp->len - SIZEOF_SDT_HDR) / addr_size;
+ for (i = 0; i < entries; i++) {
+ switch (addr_size) {
+ case 4:
+ addr = le32dec((char*)rsdp->body + i * addr_size);
+ break;
+ case 8:
+ addr = le64dec((char*)rsdp->body + i * addr_size);
+ break;
+ default:
+ assert((addr = 0));
+ }
+
+ sdp = (struct ACPIsdt *)acpi_map_sdt(addr);
+ if (sdp == NULL) {
+ msgDebug("%s: unable to map sdt\n", __func__);
+ continue;
+ }
+ if (acpi_checksum(sdp, sdp->len)) {
+#if 0
+ msgDebug("RSDT entry %d (sig %.4s) has bad checksum\n",
+ i, sdp->signature);
+#endif
+ continue;
+ }
+ if (!memcmp(sdp->signature, "APIC", 4))
+ acpi_handle_apic(sdp);
+ }
+}
+
+static char machdep_acpi_root[] = "machdep.acpi_root";
+static int acpi_mem_fd = -1;
+
+struct acpi_user_mapping {
+ LIST_ENTRY(acpi_user_mapping) link;
+ vm_offset_t pa;
+ caddr_t va;
+ size_t size;
+};
+
+LIST_HEAD(acpi_user_mapping_list, acpi_user_mapping) maplist;
+
+static int
+acpi_user_init(void)
+{
+
+ if (acpi_mem_fd == -1) {
+ acpi_mem_fd = open(_PATH_MEM, O_RDONLY);
+ if (acpi_mem_fd == -1) {
+ msgDebug("%s: error opening %s: %s\n", __func__,
+ _PATH_MEM, strerror(errno));
+ return 0;
+ }
+ LIST_INIT(&maplist);
+ }
+ return 1;
+}
+
+static struct acpi_user_mapping *
+acpi_user_find_mapping(vm_offset_t pa, size_t size)
+{
+ struct acpi_user_mapping *map;
+
+ /* First search for an existing mapping */
+ for (map = LIST_FIRST(&maplist); map; map = LIST_NEXT(map, link)) {
+ if (map->pa <= pa && map->size >= pa + size - map->pa)
+ return (map);
+ }
+
+ /* Then create a new one */
+ size = round_page(pa + size) - trunc_page(pa);
+ pa = trunc_page(pa);
+ map = malloc(sizeof(struct acpi_user_mapping));
+ if (!map) {
+ msgDebug("%s: out of memory: %s\n", __func__, strerror(errno));
+ return (map);
+ }
+ map->pa = pa;
+ map->va = mmap(0, size, PROT_READ, MAP_SHARED, acpi_mem_fd, pa);
+ map->size = size;
+ if ((intptr_t) map->va == -1) {
+ msgDebug("%s: can't mmap address %lu size %lu: %s\n", __func__,
+ (unsigned long) pa, (unsigned long) size, strerror(errno));
+ free(map);
+ return (NULL);
+ }
+ LIST_INSERT_HEAD(&maplist, map, link);
+
+ return (map);
+}
+
+static void *
+acpi_map_physical(vm_offset_t pa, size_t size)
+{
+ struct acpi_user_mapping *map;
+
+ map = acpi_user_find_mapping(pa, size);
+ return (map == NULL ? NULL : map->va + (pa - map->pa));
+}
+
+static struct ACPIrsdp *
+acpi_get_rsdp(u_long addr)
+{
+ struct ACPIrsdp rsdp;
+ size_t len;
+
+ /* Read in the table signature and check it. */
+ pread(acpi_mem_fd, &rsdp, 8, addr);
+ if (memcmp(rsdp.signature, "RSD PTR ", 8))
+ return (NULL);
+
+ /* Read the entire table. */
+ pread(acpi_mem_fd, &rsdp, sizeof(rsdp), addr);
+
+ /* Run the checksum only over the version 1 header. */
+ if (acpi_checksum(&rsdp, 20))
+ return (NULL);
+
+ /* If the revision is 0, assume a version 1 length. */
+ if (rsdp.revision == 0)
+ len = 20;
+ else
+ len = rsdp.length;
+
+ /* XXX Should handle ACPI 2.0 RSDP extended checksum here. */
+
+ return (acpi_map_physical(addr, len));
+}
+
+static const char *
+devstate(devinfo_state_t state)
+{
+ switch (state) {
+ case DIS_NOTPRESENT:
+ return "not-present";
+ case DIS_ALIVE:
+ return "alive";
+ case DIS_ATTACHED:
+ return "attached";
+ case DIS_BUSY:
+ return "busy";
+ default:
+ return "unknown-state";
+ }
+}
+
+static int
+acpi0_check(struct devinfo_dev *dd, void *arg)
+{
+ printf("%s: %s %s\n", __func__, dd->dd_name, devstate(dd->dd_state));
+ /* NB: device must be present AND attached */
+ if (strcmp(dd->dd_name, "acpi0") == 0)
+ return (dd->dd_state == DIS_ATTACHED ||
+ dd->dd_state == DIS_BUSY);
+ return devinfo_foreach_device_child(dd, acpi0_check, arg);
+}
+
+static int
+acpi0_present(void)
+{
+ struct devinfo_dev *root;
+ int found;
+
+ found = 0;
+ devinfo_init();
+ root = devinfo_handle_to_device(DEVINFO_ROOT_DEVICE);
+ if (root != NULL)
+ found = devinfo_foreach_device_child(root, acpi0_check, NULL);
+ devinfo_free();
+ return found;
+}
+
+int
+acpi_detect(void)
+{
+ struct ACPIrsdp *rp;
+ struct ACPIsdt *rsdp;
+ u_long addr;
+ size_t len;
+
+ if (!acpi0_present()) {
+ msgDebug("%s: no acpi0 device located\n", __func__);
+ return -1;
+ }
+
+ if (!acpi_user_init())
+ return -1;
+
+ /* Attempt to use sysctl to find RSD PTR record. */
+ len = sizeof(addr);
+ if (sysctlbyname(machdep_acpi_root, &addr, &len, NULL, 0) != 0) {
+ msgDebug("%s: cannot find ACPI information\n", __func__);
+ return -1;
+ }
+ rp = acpi_get_rsdp(addr);
+ if (rp == NULL) {
+ msgDebug("%s: cannot find ACPI information: "
+ "sysctl %s does not point to RSDP\n", __func__,
+ machdep_acpi_root);
+ return -1;
+ }
+ if (rp->revision < 2) {
+ rsdp = (struct ACPIsdt *)acpi_map_sdt(rp->rsdt_addr);
+ if (rsdp == NULL)
+ return -1;
+ if (memcmp(rsdp->signature, "RSDT", 4) != 0 ||
+ acpi_checksum(rsdp, rsdp->len) != 0) {
+ msgDebug("%s: RSDT is corrupted\n", __func__);
+ return -1;
+ }
+ addr_size = sizeof(uint32_t);
+ } else {
+ rsdp = (struct ACPIsdt *)acpi_map_sdt(rp->xsdt_addr);
+ if (rsdp == NULL)
+ return -1;
+ if (memcmp(rsdp->signature, "XSDT", 4) != 0 ||
+ acpi_checksum(rsdp, rsdp->len) != 0) {
+ msgDebug("%s: XSDT is corrupted\n", __func__);
+ return -1;
+ }
+ addr_size = sizeof(uint64_t);
+ }
+ ncpu = 0;
+ acpi_handle_rsdt(rsdp);
+ return (ncpu == 0 ? 1 : ncpu);
+}
diff --git a/usr.sbin/sysinstall/acpidump.h b/usr.sbin/sysinstall/acpidump.h
new file mode 100644
index 0000000..9c2b5b6
--- /dev/null
+++ b/usr.sbin/sysinstall/acpidump.h
@@ -0,0 +1,177 @@
+/*-
+ * Copyright (c) 1999 Doug Rabson
+ * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _ACPIDUMP_H_
+#define _ACPIDUMP_H_
+
+/* Root System Description Pointer */
+struct ACPIrsdp {
+ u_char signature[8];
+ u_char sum;
+ u_char oem[6];
+ u_char revision;
+ u_int32_t rsdt_addr;
+ u_int32_t length;
+ u_int64_t xsdt_addr;
+ u_char xsum;
+ u_char _reserved_[3];
+} __packed;
+
+/* System Description Table */
+struct ACPIsdt {
+ u_char signature[4];
+ u_int32_t len;
+ u_char rev;
+ u_char check;
+ u_char oemid[6];
+ u_char oemtblid[8];
+ u_int32_t oemrev;
+ u_char creator[4];
+ u_int32_t crerev;
+#define SIZEOF_SDT_HDR 36 /* struct size except body */
+ u_int32_t body[1];/* This member should be casted */
+} __packed;
+
+struct MADT_local_apic {
+ u_char cpu_id;
+ u_char apic_id;
+ u_int32_t flags;
+#define ACPI_MADT_APIC_LOCAL_FLAG_ENABLED 1
+} __packed;
+
+struct MADT_io_apic {
+ u_char apic_id;
+ u_char reserved;
+ u_int32_t apic_addr;
+ u_int32_t int_base;
+} __packed;
+
+struct MADT_int_override {
+ u_char bus;
+ u_char source;
+ u_int32_t intr;
+ u_int16_t mps_flags;
+#define MPS_INT_FLAG_POLARITY_MASK 0x3
+#define MPS_INT_FLAG_POLARITY_CONFORM 0x0
+#define MPS_INT_FLAG_POLARITY_HIGH 0x1
+#define MPS_INT_FLAG_POLARITY_LOW 0x3
+#define MPS_INT_FLAG_TRIGGER_MASK 0xc
+#define MPS_INT_FLAG_TRIGGER_CONFORM 0x0
+#define MPS_INT_FLAG_TRIGGER_EDGE 0x4
+#define MPS_INT_FLAG_TRIGGER_LEVEL 0xc
+} __packed;
+
+struct MADT_nmi {
+ u_int16_t mps_flags;
+ u_int32_t intr;
+} __packed;
+
+struct MADT_local_nmi {
+ u_char cpu_id;
+ u_int16_t mps_flags;
+ u_char lintpin;
+} __packed;
+
+struct MADT_local_apic_override {
+ u_char reserved[2];
+ u_int64_t apic_addr;
+} __packed;
+
+struct MADT_io_sapic {
+ u_char apic_id;
+ u_char reserved;
+ u_int32_t int_base;
+ u_int64_t apic_addr;
+} __packed;
+
+struct MADT_local_sapic {
+ u_char cpu_id;
+ u_char apic_id;
+ u_char apic_eid;
+ u_char reserved[3];
+ u_int32_t flags;
+} __packed;
+
+struct MADT_int_src {
+ u_int16_t mps_flags;
+ u_char type;
+#define ACPI_MADT_APIC_INT_SOURCE_PMI 1
+#define ACPI_MADT_APIC_INT_SOURCE_INIT 2
+#define ACPI_MADT_APIC_INT_SOURCE_CPEI 3 /* Corrected Platform Error */
+ u_char cpu_id;
+ u_char cpu_eid;
+ u_char sapic_vector;
+ u_int32_t intr;
+ u_char reserved[4];
+} __packed;
+
+struct MADT_APIC {
+ u_char type;
+#define ACPI_MADT_APIC_TYPE_LOCAL_APIC 0
+#define ACPI_MADT_APIC_TYPE_IO_APIC 1
+#define ACPI_MADT_APIC_TYPE_INT_OVERRIDE 2
+#define ACPI_MADT_APIC_TYPE_NMI 3
+#define ACPI_MADT_APIC_TYPE_LOCAL_NMI 4
+#define ACPI_MADT_APIC_TYPE_LOCAL_OVERRIDE 5
+#define ACPI_MADT_APIC_TYPE_IO_SAPIC 6
+#define ACPI_MADT_APIC_TYPE_LOCAL_SAPIC 7
+#define ACPI_MADT_APIC_TYPE_INT_SRC 8
+ u_char len;
+ union {
+ struct MADT_local_apic local_apic;
+ struct MADT_io_apic io_apic;
+ struct MADT_int_override int_override;
+ struct MADT_nmi nmi;
+ struct MADT_local_nmi local_nmi;
+ struct MADT_local_apic_override local_apic_override;
+ struct MADT_io_sapic io_sapic;
+ struct MADT_local_sapic local_sapic;
+ struct MADT_int_src int_src;
+ } body;
+} __packed;
+
+struct MADTbody {
+ u_int32_t lapic_addr;
+ u_int32_t flags;
+#define ACPI_APIC_FLAG_PCAT_COMPAT 1 /* System has dual-8259 setup. */
+ u_char body[1];
+} __packed;
+
+/*
+ * Addresses to scan on ia32 for the RSD PTR. According to section 5.2.2
+ * of the ACPI spec, we only consider two regions for the base address:
+ * 1. EBDA (1 KB area addressed to by 16 bit pointer at 0x40E)
+ * 2. High memory (0xE0000 - 0xFFFFF)
+ */
+#define RSDP_EBDA_PTR 0x40E
+#define RSDP_EBDA_SIZE 0x400
+#define RSDP_HI_START 0xE0000
+#define RSDP_HI_SIZE 0x20000
+
+#endif /* !_ACPIDUMP_H_ */
diff --git a/usr.sbin/sysinstall/biosmptable.c b/usr.sbin/sysinstall/biosmptable.c
new file mode 100644
index 0000000..d6ee944
--- /dev/null
+++ b/usr.sbin/sysinstall/biosmptable.c
@@ -0,0 +1,274 @@
+/*-
+ * Copyright (c) 2005 Sandvine Incorporated. All righs reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Author: Ed Maste <emaste@phaedrus.sandvine.ca>
+ */
+
+/*
+ * This module detects Intel Multiprocessor spec info (mptable) and returns
+ * the number of cpu's identified.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <machine/mptable.h>
+
+#include <fcntl.h>
+#include <inttypes.h>
+#include <paths.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "sysinstall.h"
+
+#define MPFPS_SIG "_MP_"
+#define MPCTH_SIG "PCMP"
+
+#define PTOV(pa) ((off_t)(pa))
+
+static mpfps_t biosmptable_find_mpfps(void);
+static mpfps_t biosmptable_search_mpfps(off_t base, int length);
+static mpcth_t biosmptable_check_mpcth(off_t addr);
+
+static int memopen(void);
+static void memclose(void);
+
+int
+biosmptable_detect(void)
+{
+ mpfps_t mpfps;
+ mpcth_t mpcth;
+ char *entry_type_p;
+ proc_entry_ptr proc;
+ int ncpu, i;
+
+ if (!memopen())
+ return -1; /* XXX 0? */
+ /* locate and validate the mpfps */
+ mpfps = biosmptable_find_mpfps();
+ mpcth = NULL;
+ if (mpfps == NULL) {
+ ncpu = 0;
+ } else if (mpfps->config_type != 0) {
+ /*
+ * If thie config_type is nonzero then this is a default configuration
+ * from Chapter 5 in the MP spec. Report 2 cpus and 1 I/O APIC.
+ */
+ ncpu = 2;
+ } else {
+ ncpu = 0;
+ mpcth = biosmptable_check_mpcth(PTOV(mpfps->pap));
+ if (mpcth != NULL) {
+ entry_type_p = (char *)(mpcth + 1);
+ for (i = 0; i < mpcth->entry_count; i++) {
+ switch (*entry_type_p) {
+ case 0:
+ entry_type_p += sizeof(struct PROCENTRY);
+ proc = (proc_entry_ptr) entry_type_p;
+ msgDebug("MPTable: Found CPU APIC ID %d %s\n",
+ proc->apic_id,
+ proc->cpu_flags & PROCENTRY_FLAG_EN ?
+ "enabled" : "disabled");
+ if (proc->cpu_flags & PROCENTRY_FLAG_EN)
+ ncpu++;
+ break;
+ case 1:
+ entry_type_p += sizeof(struct BUSENTRY);
+ break;
+ case 2:
+ entry_type_p += sizeof(struct IOAPICENTRY);
+ break;
+ case 3:
+ case 4:
+ entry_type_p += sizeof(struct INTENTRY);
+ break;
+ default:
+ msgDebug("%s: unknown mptable entry type (%d)\n",
+ __func__, *entry_type_p);
+ goto done; /* XXX error return? */
+ }
+ }
+ done:
+ ;
+ }
+ }
+ memclose();
+ if (mpcth != NULL)
+ free(mpcth);
+ if (mpfps != NULL)
+ free(mpfps);
+
+ return ncpu;
+}
+
+static int pfd = -1;
+
+static int
+memopen(void)
+{
+ if (pfd < 0) {
+ pfd = open(_PATH_MEM, O_RDONLY);
+ if (pfd < 0)
+ warn("%s: cannot open", _PATH_MEM);
+ }
+ return pfd >= 0;
+}
+
+static void
+memclose(void)
+{
+ if (pfd >= 0) {
+ close(pfd);
+ pfd = -1;
+ }
+}
+
+static int
+memread(off_t addr, void* entry, size_t size)
+{
+ if ((size_t)pread(pfd, entry, size, addr) != size) {
+ warn("pread (%lu @ 0x%lx)", size, addr);
+ return 0;
+ }
+ return 1;
+}
+
+
+/*
+ * Find the MP Floating Pointer Structure. See the MP spec section 4.1.
+ */
+static mpfps_t
+biosmptable_find_mpfps(void)
+{
+ mpfps_t mpfps;
+ uint16_t addr;
+
+ /* EBDA is the 1 KB addressed by the 16 bit pointer at 0x40E. */
+ if (!memread(PTOV(0x40E), &addr, sizeof(addr)))
+ return (NULL);
+ mpfps = biosmptable_search_mpfps(PTOV(addr << 4), 0x400);
+ if (mpfps != NULL)
+ return (mpfps);
+
+ /* Check the BIOS. */
+ mpfps = biosmptable_search_mpfps(PTOV(0xf0000), 0x10000);
+ if (mpfps != NULL)
+ return (mpfps);
+
+ return (NULL);
+}
+
+static mpfps_t
+biosmptable_search_mpfps(off_t base, int length)
+{
+ mpfps_t mpfps;
+ u_int8_t *cp, sum;
+ int ofs, idx;
+
+ mpfps = malloc(sizeof(*mpfps));
+ if (mpfps == NULL) {
+ msgDebug("%s: unable to malloc space for "
+ "MP Floating Pointer Structure\n", __func__);
+ return (NULL);
+ }
+ /* search on 16-byte boundaries */
+ for (ofs = 0; ofs < length; ofs += 16) {
+ if (!memread(base + ofs, mpfps, sizeof(*mpfps)))
+ break;
+
+ /* compare signature, validate checksum */
+ if (!strncmp(mpfps->signature, MPFPS_SIG, strlen(MPFPS_SIG))) {
+ cp = (u_int8_t *)mpfps;
+ sum = 0;
+ /* mpfps is 16 bytes, or one "paragraph" */
+ if (mpfps->length != 1) {
+ msgDebug("%s: bad mpfps length (%d)\n",
+ __func__, mpfps->length);
+ continue;
+ }
+ for (idx = 0; idx < mpfps->length * 16; idx++)
+ sum += *(cp + idx);
+ if (sum != 0) {
+ msgDebug("%s: bad mpfps checksum (%d)\n", __func__, sum);
+ continue;
+ }
+ return (mpfps);
+ }
+ }
+ free(mpfps);
+ return (NULL);
+}
+
+static mpcth_t
+biosmptable_check_mpcth(off_t addr)
+{
+ mpcth_t mpcth;
+ u_int8_t *cp, sum;
+ int idx, table_length;
+
+ /* mpcth must be in the first 1MB */
+ if ((u_int32_t)addr >= 1024 * 1024) {
+ msgDebug("%s: bad mpcth address (0x%lx)\n", __func__, addr);
+ return (NULL);
+ }
+
+ mpcth = malloc(sizeof(*mpcth));
+ if (mpcth == NULL) {
+ msgDebug("%s: unable to malloc space for "
+ "MP Configuration Table Header\n", __func__);
+ return (NULL);
+ }
+ if (!memread(addr, mpcth, sizeof(*mpcth)))
+ goto bad;
+ /* Compare signature and validate checksum. */
+ if (strncmp(mpcth->signature, MPCTH_SIG, strlen(MPCTH_SIG)) != 0) {
+ msgDebug("%s: bad mpcth signature\n", __func__);
+ goto bad;
+ }
+ table_length = mpcth->base_table_length;
+ mpcth = realloc(mpcth, table_length);
+ if (mpcth == NULL) {
+ msgDebug("%s: unable to realloc space for mpcth (len %u)\n",
+ __func__, table_length);
+ return (NULL);
+ }
+ if (!memread(addr, mpcth, table_length))
+ goto bad;
+ cp = (u_int8_t *)mpcth;
+ sum = 0;
+ for (idx = 0; idx < mpcth->base_table_length; idx++)
+ sum += *(cp + idx);
+ if (sum != 0) {
+ msgDebug("%s: bad mpcth checksum (%d)\n", __func__, sum);
+ goto bad;
+ }
+
+ return mpcth;
+bad:
+ free(mpcth);
+ return (NULL);
+}
diff --git a/usr.sbin/sysinstall/dist.c b/usr.sbin/sysinstall/dist.c
index ab3914c..be74bd3 100644
--- a/usr.sbin/sysinstall/dist.c
+++ b/usr.sbin/sysinstall/dist.c
@@ -45,6 +45,7 @@
unsigned int Dists;
unsigned int SrcDists;
unsigned int XOrgDists;
+unsigned int KernelDists;
enum _disttype { DT_TARBALL, DT_SUBDIST, DT_PACKAGE };
@@ -59,6 +60,7 @@ typedef struct _dist {
} my_data;
} Distribution;
+static Distribution KernelDistTable[];
static Distribution SrcDistTable[];
static Distribution XOrgDistTable[];
@@ -75,6 +77,7 @@ static Distribution XOrgDistTable[];
/* The top-level distribution categories */
static Distribution DistTable[] = {
DTE_TARBALL("base", &Dists, BASE, "/"),
+ DTE_SUBDIST("kernels", &Dists, KERNEL, KernelDistTable),
DTE_TARBALL("doc", &Dists, DOC, "/"),
DTE_TARBALL("games", &Dists, GAMES, "/"),
DTE_TARBALL("manpages", &Dists, MANPAGES, "/"),
@@ -92,6 +95,15 @@ static Distribution DistTable[] = {
DTE_END,
};
+/* The kernel distributions */
+static Distribution KernelDistTable[] = {
+ DTE_TARBALL("GENERIC", &KernelDists, KERNEL_GENERIC, "/boot"),
+#ifdef WITH_SMP
+ DTE_TARBALL("SMP", &KernelDists, KERNEL_SMP, "/boot"),
+#endif
+ DTE_END,
+};
+
/* The /usr/src distribution */
static Distribution SrcDistTable[] = {
DTE_TARBALL("sbase", &SrcDists, SRC_BASE, "/usr/src"),
@@ -149,9 +161,11 @@ distVerifyFlags(void)
Dists |= DIST_SRC;
if (XOrgDists)
Dists |= DIST_XORG;
+ if (KernelDists)
+ Dists |= DIST_KERNEL;
if (isDebug()) {
- msgDebug("Dist Masks: Dists: %0x, Srcs: %0x\n", Dists,
- SrcDists);
+ msgDebug("Dist Masks: Dists: %0x, Srcs: %0x Kernels: %0x\n", Dists,
+ SrcDists, KernelDists);
msgDebug("XServer: %0x\n", XOrgDists);
}
}
@@ -162,6 +176,7 @@ distReset(dialogMenuItem *self)
Dists = 0;
SrcDists = 0;
XOrgDists = 0;
+ KernelDists = 0;
return DITEM_SUCCESS | DITEM_REDRAW;
}
@@ -181,6 +196,9 @@ distConfig(dialogMenuItem *self)
if ((cp = variable_get(VAR_DIST_X11)) != NULL)
XOrgDists = atoi(cp);
+ if ((cp = variable_get(VAR_DIST_KERNEL)) != NULL)
+ KernelDists = atoi(cp);
+
distVerifyFlags();
return DITEM_SUCCESS | DITEM_REDRAW;
}
@@ -193,6 +211,17 @@ distSetX(void)
return distSetXOrg(NULL);
}
+static int
+selectKernel(void)
+{
+#ifdef WITH_SMP
+ /* select default kernel based on deduced cpu count */
+ return NCpus > 1 ? DIST_KERNEL_SMP : DIST_KERNEL_GENERIC;
+#else
+ return DIST_KERNEL_GENERIC;
+#endif
+}
+
int
distSetDeveloper(dialogMenuItem *self)
{
@@ -201,6 +230,7 @@ distSetDeveloper(dialogMenuItem *self)
distReset(NULL);
Dists = _DIST_DEVELOPER;
SrcDists = DIST_SRC_ALL;
+ KernelDists = selectKernel();
i = distMaybeSetPorts(self);
distVerifyFlags();
return i;
@@ -225,6 +255,7 @@ distSetKernDeveloper(dialogMenuItem *self)
distReset(NULL);
Dists = _DIST_DEVELOPER;
SrcDists = DIST_SRC_SYS;
+ KernelDists = selectKernel();
i = distMaybeSetPorts(self);
distVerifyFlags();
return i;
@@ -248,6 +279,7 @@ distSetUser(dialogMenuItem *self)
distReset(NULL);
Dists = _DIST_USER;
+ KernelDists = selectKernel();
i = distMaybeSetPorts(self);
distVerifyFlags();
return i;
@@ -268,7 +300,8 @@ int
distSetMinimum(dialogMenuItem *self)
{
distReset(NULL);
- Dists = DIST_BASE;
+ Dists = DIST_BASE | DIST_KERNEL;
+ KernelDists = selectKernel();
distVerifyFlags();
return DITEM_SUCCESS | DITEM_REDRAW;
}
@@ -281,6 +314,7 @@ distSetEverything(dialogMenuItem *self)
Dists = DIST_ALL;
SrcDists = DIST_SRC_ALL;
XOrgDists = DIST_XORG_ALL;
+ KernelDists = DIST_KERNEL_ALL;
i = distMaybeSetPorts(self);
distVerifyFlags();
return i | DITEM_REDRAW;
@@ -434,6 +468,20 @@ distSetXOrg(dialogMenuItem *self)
return i | DITEM_RESTORE;
}
+int
+distSetKernel(dialogMenuItem *self)
+{
+ int i;
+
+ dialog_clear_norefresh();
+ if (!dmenuOpenSimple(&MenuKernelDistributions, FALSE))
+ i = DITEM_FAILURE;
+ else
+ i = DITEM_SUCCESS;
+ distVerifyFlags();
+ return i | DITEM_RESTORE;
+}
+
static Boolean got_intr = FALSE;
/* timeout handler */
@@ -455,13 +503,31 @@ check_for_interrupt(void)
}
/*
+ * translate distribution filename to lower case
+ * as doTARBALL does in release/Makefile
+ */
+static void
+translateDist(char trdist[PATH_MAX], const char *dist)
+{
+ int j;
+
+ /*
+ * translate distribution filename to lower case
+ * as doTARBALL does in release/Makefile
+ */
+ for (j = 0; j < PATH_MAX-1 && dist[j] != '\0'; j++)
+ trdist[j] = tolower(dist[j]);
+ trdist[j] = '\0';
+}
+
+/*
* Try to get distribution as multiple pieces, locating and parsing an
* info file which tells us how many we need for this distribution.
*/
static Boolean
distExtractTarball(char *path, char *dist, char *my_dir, int is_base)
{
- char *buf = NULL, fname[PATH_MAX];
+ char *buf = NULL, trdist[PATH_MAX], fname[PATH_MAX];
struct timeval start, stop;
int j, status, total, intr;
int cpid, zpid, fd2, chunk, numchunks;
@@ -469,14 +535,23 @@ distExtractTarball(char *path, char *dist, char *my_dir, int is_base)
const char *tmp;
FILE *fp;
+ translateDist(trdist, dist);
+ if (isDebug())
+ msgDebug("%s: path \"%s\" dist \"%s\" trdist \"%s\" "
+ "my_dir \"%s\" %sis_base\n",
+ __func__, path, dist, trdist, my_dir, is_base ? "" : "!");
+
status = TRUE;
numchunks = 0;
- snprintf(fname, sizeof (fname), "%s/%s.inf", path, dist);
+ snprintf(fname, sizeof (fname), "%s/%s.inf", path, trdist);
getinfo:
fp = DEVICE_GET(mediaDevice, fname, TRUE);
intr = check_for_interrupt();
if (fp == (FILE *)IO_ERROR || intr || !mediaDevice) {
+ if (isDebug())
+ msgDebug("%s: fname %s fp: %p, intr: %d mediaDevice: %p\n",
+ __func__, fname, fp, intr, mediaDevice);
/* Hard error, can't continue */
if (!msgYesNo("Unable to open %s: %s.\nReinitialize media?",
fname, !intr ? "I/O error." : "User interrupt.")) {
@@ -488,8 +563,10 @@ getinfo:
return (FALSE);
} else if (fp == NULL) {
/* No attributes file, so try as a single file. */
- snprintf(fname, sizeof(fname), "%s/%s.%s", path, dist,
+ snprintf(fname, sizeof(fname), "%s/%s.%s", path, trdist,
USE_GZIP ? "tgz" : "tbz");
+ if (isDebug())
+ msgDebug("%s: fp is NULL (1) fname: %s\n", __func__, fname);
/*
* Passing TRUE as 3rd parm to get routine makes this a "probing"
* get, for which errors are not considered too significant.
@@ -498,6 +575,9 @@ getinfo:
fp = DEVICE_GET(mediaDevice, fname, TRUE);
intr = check_for_interrupt();
if (fp == (FILE *)IO_ERROR || intr || !mediaDevice) {
+ if (isDebug())
+ msgDebug("%s: fname %s fp: %p, intr: %d mediaDevice: %p\n",
+ __func__, fname, fp, intr, mediaDevice);
/* Hard error, can't continue */
msgConfirm("Unable to open %s: %s", fname,
!intr ? "I/O error" : "User interrupt");
@@ -513,8 +593,11 @@ getinfo:
status = mediaExtractDist(dir, dist, fp);
fclose(fp);
return (status);
- } else
+ } else {
+ if (isDebug())
+ msgDebug("%s: fp is NULL (2) fname %s\n", __func__, fname);
return (FALSE);
+ }
}
if (isDebug())
@@ -523,6 +606,8 @@ getinfo:
dist_attr = properties_read(fileno(fp));
intr = check_for_interrupt();
if (intr || !dist_attr) {
+ if (isDebug())
+ msgDebug("%s: intr %d dist_attr %p\n", __func__, intr, dist_attr);
msgConfirm("Cannot parse information file for the %s distribution: %s\n"
"Please verify that your media is valid and try again.",
dist, !intr ? "I/O error" : "User interrupt");
@@ -532,8 +617,11 @@ getinfo:
numchunks = strtol(tmp, 0, 0);
}
fclose(fp);
- if (!numchunks)
+ if (!numchunks) {
+ if (isDebug())
+ msgDebug("%s: numchunks is zero\n", __func__);
return (TRUE);
+ }
if (isDebug())
msgDebug("Attempting to extract distribution from %u chunks.\n",
@@ -562,7 +650,7 @@ getinfo:
tmp = index(tmp, ' ');
chunksize = strtol(tmp, 0, 0);
}
- snprintf(fname, sizeof(fname), "%s/%s.%c%c", path, dist, (chunk / 26) + 'a',
+ snprintf(fname, sizeof(fname), "%s/%s.%c%c", path, trdist, (chunk / 26) + 'a',
(chunk % 26) + 'a');
if (isDebug())
msgDebug("trying for piece %d of %d: %s\n", chunk + 1, numchunks,
@@ -767,7 +855,7 @@ printSelected(char *buf, int selected, Distribution *me, int *col)
int
distExtractAll(dialogMenuItem *self)
{
- int old_dists, retries = 0, status = DITEM_SUCCESS;
+ int old_dists, old_kernel, retries = 0, status = DITEM_SUCCESS;
char buf[512];
WINDOW *w;
@@ -781,6 +869,7 @@ distExtractAll(dialogMenuItem *self)
return DITEM_FAILURE;
old_dists = Dists;
+ old_kernel = KernelDists;
distVerifyFlags();
dialog_clear_norefresh();
@@ -795,6 +884,9 @@ distExtractAll(dialogMenuItem *self)
/* Only do base fixup if base dist was successfully extracted */
if ((old_dists & DIST_BASE) && !(Dists & DIST_BASE))
status |= installFixupBase(self);
+ /* Only do base fixup if base dist was successfully extracted */
+ if ((old_dists & DIST_KERNEL) && !(Dists & DIST_KERNEL))
+ status |= installFixupKernel(self, old_kernel);
/* Clear any local dist flags now */
Dists &= ~DIST_LOCAL;
diff --git a/usr.sbin/sysinstall/dist.h b/usr.sbin/sysinstall/dist.h
index 3d052b9..b2af31e 100644
--- a/usr.sbin/sysinstall/dist.h
+++ b/usr.sbin/sysinstall/dist.h
@@ -19,6 +19,7 @@
#ifdef __amd64__
#define DIST_LIB32 0x01000
#endif
+#define DIST_KERNEL 0x02000
#define DIST_ALL 0xFFFFF
/* Subtypes for SRC distribution */
@@ -70,6 +71,11 @@
#define DIST_XORG_ALL \
(DIST_XORG_MISC_ALL | DIST_XORG_SERVER_ALL | DIST_XORG_FONTS_ALL)
+/* Subtypes for KERNEL distribution */
+#define DIST_KERNEL_GENERIC 0x00001
+#define DIST_KERNEL_SMP 0x00002
+#define DIST_KERNEL_ALL 0xFFFFF
+
/* Canned distribution sets */
#define _DIST_XORG_FONTS_BASE \
@@ -77,7 +83,7 @@
DIST_XORG_FONTS_TT)
#define _DIST_USER \
- ( DIST_BASE | DIST_DOC | DIST_MANPAGES | DIST_DICT )
+ ( DIST_BASE | DIST_KERNEL | DIST_DOC | DIST_MANPAGES | DIST_DICT )
#define _DIST_DEVELOPER \
( _DIST_USER | DIST_PROFLIBS | DIST_INFO | DIST_SRC )
diff --git a/usr.sbin/sysinstall/install.c b/usr.sbin/sysinstall/install.c
index 39cfb3f..801cda9 100644
--- a/usr.sbin/sysinstall/install.c
+++ b/usr.sbin/sysinstall/install.c
@@ -61,6 +61,7 @@
*/
int _interactiveHack;
int FixItMode = 0;
+int NCpus;
static void create_termcap(void);
static void fixit_common(void);
@@ -892,6 +893,30 @@ installFixupBase(dialogMenuItem *self)
return DITEM_SUCCESS | DITEM_RESTORE;
}
+int
+installFixupKernel(dialogMenuItem *self, int dists)
+{
+
+ /* All of this is done only as init, just to be safe */
+ if (RunningAsInit) {
+ /*
+ * Install something as /boot/kernel. Prefer SMP
+ * over generic--this should handle the case where
+ * both SMP and GENERIC are installed (otherwise we
+ * select the one kernel that was installed).
+ *
+ * NB: we assume any existing kernel has been saved
+ * already and the /boot/kernel we remove is empty.
+ */
+ vsystem("rm -rf /boot/kernel");
+ if (dists & DIST_KERNEL_SMP)
+ vsystem("mv /boot/SMP /boot/kernel");
+ else
+ vsystem("mv /boot/GENERIC /boot/kernel");
+ }
+ return DITEM_SUCCESS | DITEM_RESTORE;
+}
+
#define QUEUE_YES 1
#define QUEUE_NO 0
static int
@@ -1173,7 +1198,7 @@ getRelname(void)
int
installVarDefaults(dialogMenuItem *self)
{
- char *cp;
+ char *cp, ncpus[10];
/* Set default startup options */
variable_set2(VAR_RELNAME, getRelname(), 0);
@@ -1205,6 +1230,15 @@ installVarDefaults(dialogMenuItem *self)
variable_set2(SYSTEM_STATE, "init", 0);
variable_set2(VAR_NEWFS_ARGS, "-b 16384 -f 2048", 0);
variable_set2(VAR_CONSTERM, "NO", 0);
+#if defined(i386) || defined(amd64)
+ NCpus = acpi_detect();
+ if (NCpus == -1)
+ NCpus = biosmptable_detect();
+#endif
+ if (NCpus <= 0)
+ NCpus = 1;
+ snprintf(ncpus, sizeof(ncpus), "%u", NCpus);
+ variable_set2(VAR_NCPUS, ncpus, 0);
return DITEM_SUCCESS;
}
diff --git a/usr.sbin/sysinstall/menus.c b/usr.sbin/sysinstall/menus.c
index 767909f..6147313 100644
--- a/usr.sbin/sysinstall/menus.c
+++ b/usr.sbin/sysinstall/menus.c
@@ -57,6 +57,22 @@ clearSrc(dialogMenuItem *self)
}
static int
+setKernel(dialogMenuItem *self)
+{
+ Dists |= DIST_KERNEL;
+ KernelDists = DIST_KERNEL_ALL;
+ return DITEM_SUCCESS | DITEM_REDRAW;
+}
+
+static int
+clearKernel(dialogMenuItem *self)
+{
+ Dists &= ~DIST_KERNEL;
+ KernelDists = 0;
+ return DITEM_SUCCESS | DITEM_REDRAW;
+}
+
+static int
setX11Misc(dialogMenuItem *self)
{
XOrgDists |= DIST_XORG_MISC_ALL;
@@ -160,7 +176,8 @@ checkDistEverything(dialogMenuItem *self)
{
return Dists == DIST_ALL &&
_IS_SET(SrcDists, DIST_SRC_ALL) &&
- _IS_SET(XOrgDists, DIST_XORG_ALL);
+ _IS_SET(XOrgDists, DIST_XORG_ALL) &&
+ _IS_SET(KernelDists, DIST_KERNEL_ALL);
}
static int
@@ -181,6 +198,12 @@ x11FlagCheck(dialogMenuItem *item)
}
static int
+kernelFlagCheck(dialogMenuItem *item)
+{
+ return KernelDists;
+}
+
+static int
checkTrue(dialogMenuItem *item)
{
return TRUE;
@@ -965,6 +988,8 @@ DMenu MenuSubDistributions = {
NULL, distReset, NULL, NULL, ' ', ' ', ' ' },
{ " base", "Binary base distribution (required)",
dmenuFlagCheck, dmenuSetFlag, NULL, &Dists, '[', 'X', ']', DIST_BASE },
+ { " kernels", "Binary kernel distributions (required)",
+ kernelFlagCheck,distSetKernel },
{ " dict", "Spelling checker dictionary files",
dmenuFlagCheck, dmenuSetFlag, NULL, &Dists, '[', 'X', ']', DIST_DICT },
{ " doc", "Miscellaneous FreeBSD online docs",
@@ -994,6 +1019,27 @@ DMenu MenuSubDistributions = {
{ NULL } },
};
+DMenu MenuKernelDistributions = {
+ DMENU_CHECKLIST_TYPE | DMENU_SELECTION_RETURNS,
+ "Select the operating system kernels you wish to install.",
+ "Please check off those kernels you wish to install.\n",
+ NULL,
+ NULL,
+ { { "X Exit", "Exit this menu (returning to previous)",
+ checkTrue, dmenuExit, NULL, NULL, '<', '<', '<' },
+ { "All", "Select all of the below",
+ NULL, setKernel, NULL, NULL, ' ', ' ', ' ' },
+ { "Reset", "Reset all of the below",
+ NULL, clearKernel, NULL, NULL, ' ', ' ', ' ' },
+ { " GENERIC", "GENERIC kernel configuration",
+ dmenuFlagCheck, dmenuSetFlag, NULL, &KernelDists, '[', 'X', ']', DIST_KERNEL_GENERIC },
+#ifdef WITH_SMP
+ { " SMP", "GENERIC symmetric multiprocessor kernel configuration",
+ dmenuFlagCheck, dmenuSetFlag, NULL, &KernelDists, '[', 'X', ']', DIST_KERNEL_SMP },
+#endif
+ { NULL } },
+};
+
DMenu MenuSrcDistributions = {
DMENU_CHECKLIST_TYPE | DMENU_SELECTION_RETURNS,
"Select the sub-components of src you wish to install.",
diff --git a/usr.sbin/sysinstall/sysinstall.h b/usr.sbin/sysinstall/sysinstall.h
index 9940392..6e4d096 100644
--- a/usr.sbin/sysinstall/sysinstall.h
+++ b/usr.sbin/sysinstall/sysinstall.h
@@ -107,6 +107,7 @@
#define VAR_DIST_MAIN "distMain"
#define VAR_DIST_SRC "distSRC"
#define VAR_DIST_X11 "distX11"
+#define VAR_DIST_KERNEL "distKernel"
#define VAR_DEDICATE_DISK "dedicateDisk"
#define VAR_DOMAINNAME "domainname"
#define VAR_EDITOR "editor"
@@ -147,6 +148,7 @@
#define VAR_MOUSED_PORT "moused_port"
#define VAR_MOUSED_TYPE "moused_type"
#define VAR_NAMESERVER "nameserver"
+#define VAR_NCPUS "ncpus"
#define VAR_NETINTERACTIVE "netInteractive"
#define VAR_NETMASK "netmask"
#define VAR_NETWORK_DEVICE "netDev"
@@ -421,6 +423,7 @@ extern Device *mediaDevice; /* Where we're getting our distribution from */
extern unsigned int Dists; /* Which distributions we want */
extern unsigned int SrcDists; /* Which src distributions we want */
extern unsigned int XOrgDists; /* Which X.Org dists we want */
+extern unsigned int KernelDists; /* Which kernel dists we want */
extern int BootMgr; /* Which boot manager to use */
extern int StatusLine; /* Where to print our status messages */
extern DMenu MenuCountry; /* Country menu */
@@ -470,6 +473,7 @@ extern DMenu MenuDistributions; /* Distribution menu */
extern DMenu MenuDiskDevices; /* Disk type devices */
extern DMenu MenuSubDistributions; /* Custom distribution menu */
extern DMenu MenuSrcDistributions; /* Source distribution menu */
+extern DMenu MenuKernelDistributions;/* Kernel distribution menu */
extern DMenu MenuXOrg; /* X.Org main menu */
extern DMenu MenuXOrgSelect; /* X.Org distribution selection menu */
extern DMenu MenuXOrgSelectCore; /* X.Org core distribution menu */
@@ -482,6 +486,7 @@ extern DMenu MenuFixit; /* Fixit floppy/CDROM/shell menu */
extern DMenu MenuXOrgConfig; /* Select X.Org configuration tool */
extern int FixItMode; /* FixItMode starts shell onc urrent device (ie Serial port) */
extern const char * StartName; /* Which name we were started as */
+extern int NCpus; /* # cpus on machine */
/* Important chunks. */
extern Chunk *HomeChunk;
@@ -500,6 +505,9 @@ extern void display_helpline(WINDOW *w, int y, int width);
/*** Prototypes ***/
+/* acpi.c */
+extern int acpi_detect(void);
+
/* anonFTP.c */
extern int configAnonFTP(dialogMenuItem *self);
@@ -606,6 +614,7 @@ extern int distSetMinimum(dialogMenuItem *self);
extern int distSetEverything(dialogMenuItem *self);
extern int distSetSrc(dialogMenuItem *self);
extern int distSetXOrg(dialogMenuItem *self);
+extern int distSetKernel(dialogMenuItem *self);
extern int distExtractAll(dialogMenuItem *self);
/* dmenu.c */
@@ -683,6 +692,7 @@ extern int installFixitHoloShell(dialogMenuItem *self);
extern int installFixitCDROM(dialogMenuItem *self);
extern int installFixitFloppy(dialogMenuItem *self);
extern int installFixupBase(dialogMenuItem *self);
+extern int installFixupKernel(dialogMenuItem *self, int dists);
extern int installUpgrade(dialogMenuItem *self);
extern int installFilesystems(dialogMenuItem *self);
extern int installVarDefaults(dialogMenuItem *self);
@@ -785,6 +795,9 @@ extern int mousedTest(dialogMenuItem *self);
extern int mousedDisable(dialogMenuItem *self);
extern int setMouseFlags(dialogMenuItem *self);
+/* mptable.c */
+extern int biosmptable_detect(void);
+
/* msg.c */
extern Boolean isDebug(void);
extern void msgInfo(char *fmt, ...) __printf0like(1, 2);
OpenPOWER on IntegriCloud