diff options
-rw-r--r-- | release/Makefile | 39 | ||||
-rw-r--r-- | release/amd64/boot_crunch.conf | 2 | ||||
-rw-r--r-- | release/i386/boot_crunch.conf | 2 | ||||
-rw-r--r-- | release/ia64/boot_crunch.conf | 2 | ||||
-rw-r--r-- | release/pc98/boot_crunch.conf | 2 | ||||
-rw-r--r-- | usr.sbin/sade/Makefile | 30 | ||||
-rw-r--r-- | usr.sbin/sade/install.c | 36 | ||||
-rw-r--r-- | usr.sbin/sade/menus.c | 48 | ||||
-rw-r--r-- | usr.sbin/sade/sade.h | 13 | ||||
-rw-r--r-- | usr.sbin/sysinstall/Makefile | 30 | ||||
-rw-r--r-- | usr.sbin/sysinstall/acpi.c | 356 | ||||
-rw-r--r-- | usr.sbin/sysinstall/acpidump.h | 177 | ||||
-rw-r--r-- | usr.sbin/sysinstall/biosmptable.c | 274 | ||||
-rw-r--r-- | usr.sbin/sysinstall/dist.c | 112 | ||||
-rw-r--r-- | usr.sbin/sysinstall/dist.h | 8 | ||||
-rw-r--r-- | usr.sbin/sysinstall/install.c | 36 | ||||
-rw-r--r-- | usr.sbin/sysinstall/menus.c | 48 | ||||
-rw-r--r-- | usr.sbin/sysinstall/sysinstall.h | 13 |
18 files changed, 1199 insertions, 29 deletions
diff --git a/release/Makefile b/release/Makefile index 1b9b506..56de4fe 100644 --- a/release/Makefile +++ b/release/Makefile @@ -173,6 +173,16 @@ ARCH_DISTS?= lib32 .endif DISTRIBUTIONS?= ${BASE_DISTS} ${OTHER_DISTS} +# +# Build and package both GENERIC and SMP kernels if the target +# has both configuration files. Otherwise only GENERIC is done. +# +.if !exists(${.CURDIR}/../sys/${TARGET}/conf/SMP) +KERNELS?= GENERIC +.else +KERNELS?= GENERIC SMP +.endif + # mountpoint for filesystems. MNT= /mnt @@ -567,7 +577,6 @@ release.1: mkdir ${RD}/floppies .endif mkdir ${RD}/trees - mkdir ${RD}/kernels for i in ${DISTRIBUTIONS}; do \ mkdir ${RD}/trees/$$i && \ mtree -deU -f ${MTREEFILES}/BSD.root.dist \ @@ -579,6 +588,10 @@ release.1: mtree -deU -f ${MTREEFILES}/BSD.var.dist \ -p ${RD}/trees/$$i/var > /dev/null ; \ done + mkdir ${RD}/kernels + for i in ${KERNELS}; do \ + mkdir ${RD}/kernels/$${i}; \ + done touch ${.TARGET} # Install the system into the various distributions. @@ -592,15 +605,10 @@ release.2: release.3: .for kernel in ${KERNELS} cd ${.CURDIR}/..; \ - ${CROSSMAKE} ${KERNEL_FLAGS} -DNO_MODULES \ - KERNCONF=${kernel} INSTKERNNAME=${kernel} kernel \ - DESTDIR=${RD}/trees/base -.endfor - # Install a standard boot kernel+modules. - cd ${.CURDIR}/..; \ ${CROSSMAKE} ${KERNEL_FLAGS} \ - kernel \ - DESTDIR=${RD}/trees/base + KERNCONF=${kernel} kernel \ + DESTDIR=${RD}/kernels KODIR=/${kernel} +.endfor touch ${.TARGET} # Make and install the three crunched binaries which live on the floppies. @@ -658,6 +666,15 @@ release.6: echo "$${i} distribution is finished."; \ fi ; \ done + @for i in ${KERNELS} ; \ + do \ + if [ -d ${RD}/kernels/$${i} ] ; then \ + cd ${.CURDIR} && $(MAKE) doTARBALL \ + SD=${RD}/kernels \ + TN=$$i TD=kernels ARG="$$i" && \ + echo "$${i} distribution is finished."; \ + fi ; \ + done .if !defined(NOPORTS) # XXX: Inline stripped version of doTARBALL @rm -rf ${RD}/dists/ports/ports* @@ -789,7 +806,7 @@ SMALLMFSROOTFLOPPYSET= ${RD}/floppyset/mfsroot-small/mfsroot.gz # Build boot and install floppies. floppies.1: - @gzip -9nc ${RD}/trees/base/boot/kernel/kernel > ${RD}/kernels/kernel.gz + @gzip -9nc ${RD}/kernels/GENERIC/kernel > ${RD}/kernels/kernel.gz @echo "Making the kernel boot floppies..." @cd ${.CURDIR} && ${MAKE} makeFloppySet FLOPPYBASE=kern \ FLOPPYDESC="Kernel" SPLITFILE=${RD}/kernels/kernel.gz @@ -919,6 +936,8 @@ cdrom.1: find . -depth -print | cpio -dumpl ${CD_LIVEFS} ) ; \ fi \ done + @echo "Copy GENERIC kernel to boot area" + @cp -Rp ${RD}/kernels/GENERIC/ ${CD_LIVEFS}/boot/kernel @rm -f ${CD_LIVEFS}/.profile @cp ${.CURDIR}/fixit.profile ${CD_LIVEFS}/.profile @ln -sf /rescue ${CD_LIVEFS}/stand diff --git a/release/amd64/boot_crunch.conf b/release/amd64/boot_crunch.conf index ce31af3..e478b25 100644 --- a/release/amd64/boot_crunch.conf +++ b/release/amd64/boot_crunch.conf @@ -41,4 +41,4 @@ progs sysinstall progs usbdevs libs -ll -ledit -lutil -lmd -lcrypt -lftpio -lz -lnetgraph -libs -ldialog -lncurses -ldisk -lcam -lsbuf -lufs +libs -ldialog -lncurses -ldisk -lcam -lsbuf -lufs -ldevinfo diff --git a/release/i386/boot_crunch.conf b/release/i386/boot_crunch.conf index ce31af3..e478b25 100644 --- a/release/i386/boot_crunch.conf +++ b/release/i386/boot_crunch.conf @@ -41,4 +41,4 @@ progs sysinstall progs usbdevs libs -ll -ledit -lutil -lmd -lcrypt -lftpio -lz -lnetgraph -libs -ldialog -lncurses -ldisk -lcam -lsbuf -lufs +libs -ldialog -lncurses -ldisk -lcam -lsbuf -lufs -ldevinfo diff --git a/release/ia64/boot_crunch.conf b/release/ia64/boot_crunch.conf index a052ab9..b6b52aa 100644 --- a/release/ia64/boot_crunch.conf +++ b/release/ia64/boot_crunch.conf @@ -43,4 +43,4 @@ progs sysinstall progs usbdevs libs -ll -ledit -lutil -lmd -lcrypt -lftpio -lz -lnetgraph -libs -ldialog -lncurses -ldisk -lcam -lkiconv -lsbuf -lufs +libs -ldialog -lncurses -ldisk -lcam -lkiconv -lsbuf -lufs -ldevinfo diff --git a/release/pc98/boot_crunch.conf b/release/pc98/boot_crunch.conf index b630c88..78061dd 100644 --- a/release/pc98/boot_crunch.conf +++ b/release/pc98/boot_crunch.conf @@ -40,4 +40,4 @@ progs ppp progs sysinstall libs -ll -ledit -lutil -lmd -lcrypt -lftpio -lz -lnetgraph -libs -ldialog -lncurses -ldisk -lcam -lsbuf -lufs +libs -ldialog -lncurses -ldisk -lcam -lsbuf -lufs -ldevinfo diff --git a/usr.sbin/sade/Makefile b/usr.sbin/sade/Makefile index 751d10c..c735c26 100644 --- a/usr.sbin/sade/Makefile +++ b/usr.sbin/sade/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/sade/install.c b/usr.sbin/sade/install.c index 39cfb3f..801cda9 100644 --- a/usr.sbin/sade/install.c +++ b/usr.sbin/sade/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/sade/menus.c b/usr.sbin/sade/menus.c index 767909f..6147313 100644 --- a/usr.sbin/sade/menus.c +++ b/usr.sbin/sade/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/sade/sade.h b/usr.sbin/sade/sade.h index 9940392..6e4d096 100644 --- a/usr.sbin/sade/sade.h +++ b/usr.sbin/sade/sade.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); 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); |