mhc@aicchi.UUCP (Colburn) (02/22/88)
Since there are probably more than one other person who is interested in this, I thought that I would post it to the net. > I found /usr/include/sys/sysinfo.h to be interesting. There is a structure > sysinfo that I want to get some stuff out of. In this file is: > extern struct sysinfo sysinfo; > This is all fine and good, but sysinfo is in /unix. This is not the sort of > thing you find laying around in a library. How does one ld this sort of > thing? > nm -x /unix | grep sysinfo > gives me: > sysinfo |0x00026ea0|extern| | | |.bss > > I am trying to accomplish this on an AT&T UNIXpc. My guess is that there is > a trick with the /lib/shlib.ifile that can be made to work, since that must > be how shared libraries are being done anyway. Please correct me if I'm wrong. > > I want to goof around in the kernal for fun, and this is where I'm stuck > right now. BTW how does one know the format of /dev/kmem? One does not know the format of /dev/kmem. Only the kernel knows. /dev/kmem is the actual kernel memory image of the currently executing kernel. You can find the address of things in /dev/kmem by using the nlist(3c) function. The nlist(3c) function will return the address of a named symbol in /dev/kmem. In the case of functions and predefined data objects, the address returned by nlist(3c) will be same as that printed out by nm(1) (usually anyways :-). By the way, I would not advise writing to /dev/kmem unless you REALLY know what you are doing :-) As an aside, when using the nlist(3) function as described in the 3B1 Manual, you must be careful to '#undef n_name' if you include a.out.h. It appears that AT&T and/or Convergent screwed up when writing the header files for the UNIX PC. In the attached program, the #undef in the program is required. Below is a program which will pull the information located in the sysinfo, syswait and syserr structures (all defined in the /usr/include/sys/sysinfo.h header file) and display it on the screen. One last comment. The attached program must be run as root, or as some other id which has read permission to /dev/kmem. The program itself is pretty simple. I hope that this will help! Please let me know how you make out. ------------------------------- cut here -------------------------------- /* * mnl.c - print out the sysinfo, syswait and syserr structures in /dev/kmem * * Comments: * This program must be run as root or as some other user which has * read access to /dev/kmem. This program was written as an example. * It will probably not pass lint, and I don't really care. * * BTW: the undef of n_name is required to bypass a bug which * Convergent dropped into the a.out.h header file. * * Author: Mark H. Colburn (mark@jhereg.mn.org) */ #include <stdio.h> #include <a.out.h> #undef n_name #include <fcntl.h> #include <sys/sysinfo.h> struct nlist mynl[] = { "sysinfo", 0, 0, 0, 0, 0, "syswait", 0, 0, 0, 0, 0, "syserr", 0, 0, 0, 0, 0, "", 0, 0, 0, 0, 0 }; struct syserr myerr; struct syswait mywait; struct sysinfo mysys; int main() { int fd; if (nlist("/unix", mynl) == -1) { fprintf(stderr, "Unable perform nlist() call\n"); perror(""); exit(1); } if ((fd = open("/dev/kmem", O_RDONLY)) == -1) { fprintf(stderr, "Unable open /dev/kmem\n"); perror(""); exit(1); } printf("n_value = %d\n", mynl[0].n_value); if (mynl[0].n_value != 0) { if (lseek(fd, mynl[0].n_value, 0) != -1 && read(fd, (char *)&mysys, sizeof(mysys)) != -1) { printsys(); } if (lseek(fd, mynl[1].n_value, 0) != -1 && read(fd, (char *)&mywait, sizeof(mywait)) != -1) { printwait(); } if (lseek(fd, mynl[2].n_value, 0) != -1 && read(fd, (char *)&myerr, sizeof(myerr)) != -1) { printerr(); } } else { printf("n_value = 0, lookup failed!\n"); } exit(0); } printsys() { printf("\nsysinfo:\n"); printf("cpu[IDLE] = %d\t", mysys.cpu[CPU_IDLE]); printf("cpu[USER] = %d\n", mysys.cpu[CPU_USER]); printf("cpu[KERNAL] = %d\t", mysys.cpu[CPU_KERNAL]); printf("cpu[WAIT] = %d\n", mysys.cpu[CPU_WAIT]); printf("wait[IO] = %d\t", mysys.wait[W_IO]); printf("wait[SWAP] = %d\t", mysys.wait[W_SWAP]); printf("wait[PIO] = %d\n", mysys.wait[W_PIO]); printf("bread = %d\t", mysys.bread); printf("bwrite = %d\n", mysys.bwrite); printf("lread = %d\t", mysys.lread); printf("lwrite = %d\n", mysys.lwrite); printf("phread = %d\t", mysys.phread); printf("phwrite = %d\n", mysys.phwrite); printf("swapin = %d\t", mysys.swapin); printf("swapout = %d\n", mysys.swapout); printf("bswapin = %d\t", mysys.bswapin); printf("bswapout = %d\n", mysys.bswapout); printf("pswitch = %d\t", mysys.pswitch); printf("syscall = %d\n", mysys.syscall); printf("sysread = %d\t", mysys.sysread); printf("syswrite = %d\n", mysys.syswrite); printf("sysfork = %d\t", mysys.sysfork); printf("sysexec = %d\n", mysys.sysexec); printf("runque = %d\t", mysys.runque); printf("runocc = %d\n", mysys.runocc); printf("swpque = %d\t", mysys.swpque); printf("swpocc = %d\n", mysys.swpocc); printf("iget = %d\t", mysys.iget); printf("namei = %d\t", mysys.namei); printf("dirblk = %d\n", mysys.dirblk); printf("readch = %d\t", mysys.readch); printf("writech = %d\n", mysys.writech); printf("rcvint = %d\t", mysys.rcvint); printf("xmtint = %d\t", mysys.xmtint); printf("mdmint = %d\n", mysys.mdmint); printf("rawch = %d\t", mysys.rawch); printf("canch = %d\t", mysys.canch); printf("outch = %d\n", mysys.outch); printf("msg = %d\t", mysys.msg); printf("sema = %d\n", mysys.sema); printf("pgin = %d\t", mysys.pgin); printf("pgout = %d\n", mysys.pgout); } printwait() { printf("\nsyswait:\n"); printf("iowait = %d\t", mywait.iowait); printf("swap = %d\t", mywait.swap); printf("physio = %d\n", mywait.physio); } printerr() { printf("\nsyserr:\n"); printf("inodeovf = %d\t", myerr.inodeovf); printf("fileovf = %d\t", myerr.fileovf); printf("textovf = %d\t", myerr.textovf); printf("procovf = %d\n", myerr.procovf); } -- Mark H. Colburn mark@jhereg.MN.ORG ihnp4!chinet!jhereg!mark