Subject: Re: root device
To: Simon Burge <simonb@wasabisystems.com>
From: Nathan J. Williams <nathanw@wasabisystems.com>
List: tech-kern
Date: 02/10/2003 17:24:46
--=rail-gun-EuroFed-Fortezza-bullion-threat-Project-Monarch-UNSCOM-Pine
Simon Burge <simonb@wasabisystems.com> writes:
> Emmanuel Dreyfus wrote:
>
> > > i think that having a program that could dump out the device tree
> > > under netbsd would be *damn cool*!
> >
> > Hey, look at what Darwin's ioreg outputs on my NetBSD/macppc machine:
> >
> > +-o mainbus0@ <class unknownClass>
> > +-o cpu0@ <class unknownClass>
> >
> > [ ... ]
>
> It'd be nice to have a _native_ NetBSD program to show this too. I'm
> sorta sure that's what Andrew meant :-)
Here's something I've had kicking around for a while. It's quite
simple; embellish as necessary to get actual tree-like
output. Locators only exist for devices configured explicitly; we
don't store "found" locators anywhere besides the message buffer.
% ./printdev
mainbus0
cpu0 at mainbus0
pci0 at mainbus0
pchb0 at pci0
agp0 at pchb0
ppb0 at pci0
pci1 at ppb0
vga1 at pci1
wsdisplay0 at vga1 kbdmux 0x1
pcib0 at pci0
pciide0 at pci0
wd0 at pciide0
atapibus0 at pciide0
cd0 at atapibus0
cd1 at atapibus0
amdpm0 at pci0
tlp0 at pci0
acphy0 at tlp0
ppb1 at pci0
pci2 at ppb1
cmpci0 at pci2
audio0 at cmpci0
opl0 at cmpci0
midi0 at opl0
mpu0 at cmpci0
midi1 at mpu0
ohci0 at pci2
usb0 at ohci0
uhub0 at usb0
ohci1 at pci2
usb1 at ohci1
uhub1 at usb1
ehci0 at pci2
usb2 at ehci0
uhub2 at usb2
tlp1 at pci2
bmtphy0 at tlp1
isa0 at pcib0
com0 at isa0 port 0x3f8 irq 0x4
com1 at isa0 port 0x2f8 irq 0x3
pckbc0 at isa0
pckbd0 at pckbc0
wskbd0 at pckbd0 mux 0x1
pms0 at pckbc0
wsmouse0 at pms0
lpt0 at isa0 port 0x378 irq 0x7
pcppi0 at isa0
midi2 at pcppi0
spkr0 at pcppi0
sysbeep0 at pcppi0
npx0 at isa0 port 0xf0 irq 0xd
fdc0 at isa0 port 0x3f0 irq 0x6 drq 0x2
fd0 at fdc0
- Nathan
--=rail-gun-EuroFed-Fortezza-bullion-threat-Project-Monarch-UNSCOM-Pine
Content-Type: application/x-sh
Content-Disposition: attachment; filename=printdev.shar
Content-Description: printdev
# This is a shell archive. Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file". Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
# Makefile
# printdev.c
#
echo x - Makefile
sed 's/^X//' >Makefile << 'END-of-Makefile'
XPROG= printdev
XSRCS= printdev.c
XDPADD= ${LIBKVM}
XLDADD= -lkvm
XBINGRP= kmem
XBINMODE= 2555
XWARNS= 2
XMAN=
X
X.include <bsd.prog.mk>
END-of-Makefile
echo x - printdev.c
sed 's/^X//' >printdev.c << 'END-of-printdev.c'
X
X#include <err.h>
X#include <fcntl.h>
X#include <kvm.h>
X#include <nlist.h>
X#include <stdio.h>
X#include <stdlib.h>
X#include <limits.h>
X#include <unistd.h>
X
X#include <sys/device.h>
X
Xstatic void usage(void);
Xssize_t kvm_readstr(kvm_t *kd, u_long addr, char *buf, size_t maxlen);
Xssize_t kvm_eread(kvm_t *kd, u_long addr, void *buf, size_t maxlen);
X
X#define FORMAT(n) ((n) > -10 && (n) < 10 ? "%d" : "0x%x")
X
X
Xstruct nlist pcnl[] = {
X#define PCNL_ALLDEVS 0
X { "_alldevs" },
X {NULL}
X};
X
Xint main(int argc, char *argv[])
X{
X extern char *optarg;
X extern int optind;
X int ch, ret;
X char *nlistf, *memf, *swapf;
X kvm_t* kd;
X char errbuf[LINE_MAX], locname[LINE_MAX];
X u_long devaddr;
X
X struct devicelist alldevs;
X struct device dev, dev2;
X struct cfdata cfda;
X char **lnsaddr, *lnaddr;
X int *lsaddr, loc;
X
X nlistf = NULL;
X memf = NULL;
X swapf = NULL;
X
X while((ch = getopt(argc, argv, "N:M:W:")) != -1)
X switch (ch) {
X case 'M':
X memf = optarg;
X break;
X case 'N':
X nlistf = optarg;
X break;
X case 'W':
X swapf = optarg;
X break;
X case '?':
X default:
X usage();
X }
X
X argc += optind;
X argv -= optind;
X
X kd = kvm_openfiles(nlistf, memf, swapf, O_RDONLY, errbuf);
X if (kd == 0) {
X errx(1, "%s", errbuf);
X }
X
X ret = kvm_nlist(kd, pcnl);
X if (ret < 0) {
X errx(2, "%s", kvm_geterr(kd));
X }
X
X kvm_eread(kd, pcnl[PCNL_ALLDEVS].n_value, &alldevs, sizeof(alldevs));
X
X devaddr = (u_long) TAILQ_FIRST(&alldevs);
X while (devaddr) {
X kvm_eread(kd, devaddr, &dev, sizeof(dev));
X printf("%s ", dev.dv_xname);
X if (dev.dv_parent) {
X kvm_eread(kd, (u_long)dev.dv_parent, &dev2, sizeof(dev));
X printf("at %s ", dev2.dv_xname);
X }
X if (dev.dv_cfdata) {
X kvm_eread(kd, (u_long)dev.dv_cfdata, &cfda, sizeof(cfda));
X lnsaddr = (char **)cfda.cf_locnames;
X lsaddr = cfda.cf_loc;
X kvm_eread(kd, (u_long)lnsaddr, &lnaddr, sizeof(lnaddr));
X while (lnaddr) {
X kvm_readstr(kd, (u_long)lnaddr, locname,
X sizeof(locname));
X kvm_eread(kd, (u_long)lsaddr, &loc, sizeof(loc));
X if (loc != -1 && loc != 0)
X printf("%s %#x ", locname, loc);
X
X lnsaddr++;
X lsaddr++;
X kvm_eread(kd, (u_long)lnsaddr, &lnaddr,
X sizeof(lnaddr));
X }
X }
X printf("\n");
X devaddr = (u_long)TAILQ_NEXT(&dev, dv_list);
X }
X
X kvm_close(kd);
X
X return 0;
X}
X
Xssize_t kvm_eread(kvm_t *kd, u_long addr, void *buf, size_t maxlen)
X{
X ssize_t ret;
X ret = kvm_read(kd, addr, buf, maxlen);
X if (ret == -1) {
X errx(3, "%s", kvm_geterr(kd));
X }
X return ret;
X}
X
Xssize_t kvm_readstr(kvm_t *kd, u_long addr, char *buf, size_t maxlen)
X{
X int count, done;
X
X count = 0;
X done = 0;
X
X while (!done && count < maxlen) {
X kvm_eread(kd, addr + count, &buf[count], 1);
X if (buf[count] == '\0')
X done = 1;
X count++;
X }
X
X return count;
X}
X
Xstatic void usage(void)
X{
X fprintf(stderr, "usage: printdev [-N kernel] [-M core] [-W swap]\n");
X exit(1);
X}
END-of-printdev.c
exit
--=rail-gun-EuroFed-Fortezza-bullion-threat-Project-Monarch-UNSCOM-Pine--