home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume1 / 8706 / 2 < prev    next >
Text File  |  1993-09-01  |  14KB  |  543 lines

  1. Article 78 of comp.sources.misc:
  2. Relay-Version: version B 2.10.3 alpha 5/22/85; site osu-eddie.UUCP
  3. Path: osu-eddie!cbosgd!clyde!rutgers!ames!amdahl!pyramid!uccba!hal!ncoast!allbery
  4. From: mouse@mcgill-vision.UUCP (der Mouse)
  5. Newsgroups: comp.sources.misc
  6. Subject: Silicon disk driver for BSD UNIX
  7. Message-ID: <2677@ncoast.UUCP>
  8. Date: 16 Jun 87 19:54:27 GMT
  9. Date-Received: 21 Jun 87 09:15:43 GMT
  10. Sender: allbery@ncoast.UUCP
  11. Lines: 526
  12. Approved: allbery@ncoast.UUCP
  13. X-Archive: comp.sources.misc/8706/2
  14.  
  15. I've gotten enough requests it's probably worth posting...
  16.                     der Mouse
  17.  
  18.                 (mouse@mcgill-vision.uucp)
  19.  
  20. #! /bin/sh
  21. #
  22. # Shar: Shell Archiver
  23. #
  24. # This archive created Tue Jun 16 15:36:41 1987
  25. # Run this through sh to create:
  26. #    memdisk.doc
  27. #    memdisk.c
  28. #    mdset.c
  29. echo x - memdisk.doc \(5929 characters\)
  30. sed 's/^X//' > memdisk.doc << \SHAR_EOF
  31. Xmemdisk: a silicon disk driver for UNIX.
  32. X     Currently in use on 4.3BSD, mtXinu 4.3+NFS, and Sunix 3.0.
  33. X
  34. XYou should have received:
  35. X
  36. X    - memdisk.doc (this file)
  37. X    - memdisk.c
  38. X    - mdset.c
  39. X
  40. XYou will need to:
  41. X
  42. X    - Look over the configuration section at the top of memdisk.c
  43. X       and change the #defines to match the system you will be
  44. X       using it on.  If none of the possibilities listed quite fit,
  45. X       you will have to guess.  If you have to guess:
  46. X        For lockout(), try splhigh() first and if that doesn't
  47. X         work ("loading vmunix"/"Undefined:"/"_splhigh") then
  48. X         use spl7().
  49. X        For mount.h, try doing "echo ../*/*mount.h" and see if
  50. X         that helps.
  51. X
  52. X    - Put memdisk.c somewhere; I'll assume it's in
  53. X       ../local/memdisk.c (that's where we have it).  If you put it
  54. X       somewhere else, change the filename in the next item to
  55. X       point to wherever you did put it.
  56. X
  57. X    - Put a line
  58. Xlocal/memdisk.c        optional memdisk
  59. X       in ../conf/files.YOURSYSTEMNAME.  For example, our
  60. X       configuration is in ../conf/LARRY and the kernel is built in
  61. X       ../LARRY; the file with the above line is then
  62. X       ../conf/files.LARRY (clear enough?).
  63. X
  64. X    - Put a line
  65. Xpseudo-device    memdisk        1
  66. X       in ../conf/YOURSYSTEMNAME.  The 1 specifies how many silicon
  67. X       disk devices you want to configure in; you may want to
  68. X       increase it.
  69. X
  70. X    - Edit conf.c.  This file is in ../vax for VAX and MicroVAX
  71. X       configurations and seems to be in ../sun (rather than
  72. X       ../machine, which is a link to sun2 or sun3 depending on
  73. X       which sort of Sun you have) for Suns.  You will need to
  74. X       insert the following, somewhere early (before both cdevsw[]
  75. X       and bdevsw[]).
  76. X#include "memdisk.h"
  77. X#if NMEMDISK > 0
  78. Xextern int memdiskopen();
  79. Xextern int memdiskstrategy();
  80. Xextern int memdiskread();
  81. Xextern int memdiskwrite();
  82. Xextern int memdiskioctl();
  83. Xextern int memdiskdump();
  84. Xextern int memdisksize();
  85. X#else
  86. X#define memdiskopen nodev
  87. X#define memdiskstrategy nodev
  88. X#define memdiskread nodev
  89. X#define memdiskwrite nodev
  90. X#define memdiskioctl nodev
  91. X#define memdiskdump nodev
  92. X#define memdisksize nodev
  93. X#endif
  94. X       Now you need to add a device to each of bdevsw[] and
  95. X       cdevsw[].  The bdevsw entry should look like
  96. X    { memdiskopen,    nulldev,    memdiskstrategy,memdiskdump,    /* 10 */
  97. X      memdisksize,    0 },
  98. X       (the 10 should be changed to whatever number you choose to
  99. X       put it at).  The cdevsw entry should look like
  100. X    {
  101. X    memdiskopen,    nulldev,    memdiskread,    memdiskwrite,    /* 34 */
  102. X    memdiskioctl,    nulldev,    nodev,        0,
  103. X    seltrue,    0,
  104. X    },
  105. X       again, with the 34 changed to whatever is appropriate.
  106. X
  107. X    - add a #define to ../h/ioctl.h:
  108. X#define LIOC_MEM_SET    _IOW(l,0,int)            /* start/stop disk */
  109. X
  110. XYou can now re-run config and rebuild your kernel.  If you get
  111. Xcomplaints when trying to rebuild your kernel about "Don't know how to
  112. Xmake ../h/mount.h" (or ../ufs/ufsmount.h, or ../ufs/mount.h), then try
  113. Xtaking the ones it complains about right out of memdisk.c and redoing
  114. Xthe make depend.
  115. X
  116. XIf I haven't forgotten anything (:-), it should run fine.  Test the new
  117. Xkernel.  When you are satisfied that adding the memdisk driver hasn't
  118. Xbroken anything else, you can try it out:
  119. X
  120. X    - Create entries in /dev.  We use /dev/mdisk0 and /dev/rmdisk0
  121. X       (just 0 since we have just one configured in - if we had
  122. X       two, they'd be mdisk0/rmdisk0 and mdisk1/rmdisk1).
  123. X
  124. X    - Compile mdset.c; put the binary wherever you feel
  125. X       appropriate.  As with any disk drive, the /dev entries
  126. X       should be mode xx0, probably mode 600 is best, unless you
  127. X       wouldn't mind entrusting all your users with your root
  128. X       password.  Mdset must be able to open the raw device
  129. X       /dev/rmdisk0 (or rmdisk1, or 2, or...) in order to function.
  130. X
  131. X    - Run mdset to allocate memory to the disk.  When the system is
  132. X       booted, no memory is allocated to the disk.  Mdset takes two
  133. X       arguments.  The first argument must be the disk unit number
  134. X       (the trailing number on the /dev entry), the second must be
  135. X       the number of bytes of memory to allocate to the disk and
  136. X       must be a multiple of 512 (the usual sector size for a
  137. X       disk).  The second argument can have a trailing k or m to
  138. X       indicate kilo- or mega- bytes (eg, 512k indicates a half-meg
  139. X       disk).  If mdset runs and doesn't crash the system, the
  140. X       silicon drive should now have some memory allocated to it.
  141. X       You can now run mkfs (or newfs, if you give it a size) to
  142. X       create a filesystem on the disk, then you can put whatever
  143. X       you want there.  Note that the size argument to mkfs is the
  144. X       number of sectors, ie, the number of bytes divided by 512.
  145. X       If you use the k abbreviation, the number to pass to mkfs
  146. X       will be twice the number before the k; if you use m, the
  147. X       mkfs size will be 2048 times the number before the m.
  148. X
  149. XFor example, suppose we want to allocate a half-meg to /tmp:
  150. X
  151. X# mdset 0 512k
  152. X
  153. XIf the driver can't get the memory, it will produce a message
  154. Xmdset: cannot set size for /dev/rmdisk0: <message>
  155. Xwhere <message> is one of the standard error messages (see intro(2)),
  156. Xmost likely "Not enough core".
  157. X
  158. XNow the disk has memory, but the contents of the memory are basically
  159. Xrandom.  So we make a filesystem:
  160. X
  161. X# /etc/mkfs /dev/rmdisk0 1024
  162. X....mkfs messages....
  163. X
  164. XNow sync the disk just to be safe.  It works just as well to run fsck
  165. Xon it, I find; but if you do neither, I have had it crash mysteriously
  166. Xsometimes (I suspect that some critical filesystem data, like
  167. Xsuperblocks, is still waiting to be written to the disk, because the
  168. Xmkfs used /dev/rmdisk0 instead of /dev/mdisk0).
  169. X
  170. X# sync
  171. X
  172. XNow we can mount it somewhere:
  173. X
  174. X# /etc/mount /dev/mdisk0 /tmp
  175. X
  176. XAnd away we go!  Note that you do not want to put anything on a silicon
  177. Xdrive that is both important and difficult to recreate, because every
  178. Xtime the machine goes down, everything on a silicon drive is lost.
  179. X/tmp is a reasonable thing to put on a silicon drive; a read-only copy
  180. Xof something that gets used heavily could also be a win.
  181. X
  182. X                    der Mouse
  183. X
  184. X                (mouse@mcgill-vision.uucp)
  185. SHAR_EOF
  186. if test 5929 -ne "`wc -c memdisk.doc`"
  187. then
  188. echo shar: error transmitting memdisk.doc \(should have been 5929 characters\)
  189. fi
  190. echo x - memdisk.c \(4858 characters\)
  191. sed 's/^X//' > memdisk.c << \SHAR_EOF
  192. X/*
  193. X * Silicon disk driver.
  194. X *
  195. X * Copyright 1987 by Mike Parker.
  196. X * You may do anything you like with this as long as you don't:
  197. X *    - claim you wrote any part of it that you didn't (ie, you may
  198. X *       of course claim any modifications you've made, but not any
  199. X *       of my code); nor
  200. X *    - change or delete this copyright notice.
  201. X * Note also that I do not take any responsibility for anything this code
  202. X * may do.  I have tried to make it useful but I can't promise anything.
  203. X *
  204. X * If you find any bugs I'd appreciate hearing about them, especially
  205. X * if you also fix them.  Write to mouse@mcgill-vision.uucp.
  206. X */
  207. X
  208. X/* Configuration. */
  209. X
  210. X/* What spl... do we use for total lockout?  (We assume splx() un-locks.) */
  211. X#define lockout() splhigh() /* works on 4.3BSD derivatives for the VAX */
  212. X/* #define lockout() spl7() /* works on Sun UNIX 3.0 */
  213. X
  214. X/* Where is mount.h? */
  215. X#define UFS_UFSMOUNT /* ../ufs/ufsmount.h: works on mtXinu 4.3+NFS */
  216. X/* #define H_MOUNT /* ../h/mount.h: works on 4.3 */
  217. X/* #define UFS_MOUNT /* ../ufs/mount.h: works on Sun UNIX 3.0 */
  218. X
  219. X#include "memdisk.h"
  220. X
  221. X#if NMEMDISK > 0
  222. X
  223. X#include "../h/param.h"
  224. X#include "../h/systm.h"
  225. X#include "../h/ioctl.h"
  226. X#include "../h/buf.h"
  227. X#include "../h/conf.h"
  228. X#include "../h/time.h"
  229. X#include "../h/kernel.h"
  230. X#include "../h/errno.h"
  231. X#ifdef UFS_UFS_MOUNT
  232. X#include "../ufs/ufsmount.h"
  233. X#endif
  234. X#ifdef H_MOUNT
  235. X#include "../h/mount.h"
  236. X#endif
  237. X#ifdef UFS_MOUNT
  238. X#include "../ufs/mount.h"
  239. X#endif
  240. X
  241. Xint max_md_size = (2048+512) * 1024; /* 2.5Mb */
  242. X
  243. Xstatic struct memdiskinfo {
  244. X     int busy;
  245. X     int live;
  246. X     int unit;
  247. X     int nbytes;
  248. X     char *data; } memdiskinfo[NMEMDISK];
  249. Xstatic int didinit = 0;
  250. X
  251. X#define OKUNIT(u) (((u)>=0)&&((u)<NMEMDISK))
  252. X#define LIVEUNIT(u) (OKUNIT(u)&&memdiskinfo[u].live)
  253. X
  254. Xmemdiskopen(dev,flag)
  255. Xdev_t dev;
  256. Xint flag;
  257. X{
  258. X int unit;
  259. X int s;
  260. X
  261. X#ifdef lint
  262. X flag = flag;
  263. X#endif
  264. X unit = minor(dev);
  265. X if (! OKUNIT(unit))
  266. X  { return(ENXIO);
  267. X  }
  268. X s = lockout();
  269. X if (! didinit)
  270. X  { for (unit=0;unit<NMEMDISK;unit++)
  271. X     { register struct memdiskinfo *mdi;
  272. X       mdi = &memdiskinfo[unit];
  273. X       mdi->busy = 0;
  274. X       mdi->live = 0;
  275. X       mdi->unit = unit;
  276. X     }
  277. X    didinit = 1;
  278. X  }
  279. X splx(s);
  280. X return(0);
  281. X}
  282. X
  283. Xmemdiskstrategy(bp)
  284. Xstruct buf *bp;
  285. X{
  286. X int unit;
  287. X register struct memdiskinfo *mdi;
  288. X int off;
  289. X int nblk;
  290. X int s;
  291. X
  292. X unit = minor(bp->b_dev);
  293. X if (! LIVEUNIT(unit))
  294. X  { bp->b_flags |= B_ERROR;
  295. X    iodone(bp);
  296. X    return;
  297. X  }
  298. X mdi = &memdiskinfo[unit];
  299. X s = lockout();
  300. X if (mdi->busy)
  301. X  { splx(s);
  302. X    bp->b_flags |= B_ERROR;
  303. X    iodone(bp);
  304. X    return;
  305. X  }
  306. X off = dbtob(bp->b_blkno);
  307. X if ( (off < 0) ||
  308. X      (off+bp->b_bcount > mdi->nbytes) )
  309. X  { splx(s);
  310. X    bp->b_flags |= B_ERROR;
  311. X    iodone(bp);
  312. X    return;
  313. X  }
  314. X if (bp->b_flags & B_READ)
  315. X  { bcopy(mdi->data+off,bp->b_un.b_addr,bp->b_bcount);
  316. X  }
  317. X else
  318. X  { bcopy(bp->b_un.b_addr,mdi->data+off,bp->b_bcount);
  319. X  }
  320. X splx(s);
  321. X iodone(bp);
  322. X}
  323. X
  324. Xmemdiskread(dev,uio)
  325. Xdev_t dev;
  326. Xstruct uio *uio;
  327. X{
  328. X static struct buf b[NMEMDISK];
  329. X int unit = minor(dev);
  330. X
  331. X if (! LIVEUNIT(unit))
  332. X  { return(ENXIO);
  333. X  }
  334. X return(physio(memdiskstrategy,&b[unit],dev,B_READ,minphys,uio));
  335. X}
  336. X
  337. Xmemdiskwrite(dev,uio)
  338. Xdev_t dev;
  339. Xstruct uio *uio;
  340. X{
  341. X static struct buf b[NMEMDISK];
  342. X int unit = minor(dev);
  343. X
  344. X if (! LIVEUNIT(unit))
  345. X  { return(ENXIO);
  346. X  }
  347. X return(physio(memdiskstrategy,&b[unit],dev,B_WRITE,minphys,uio));
  348. X}
  349. X
  350. Xmemdiskioctl(dev,cmd,data,flag)
  351. Xdev_t dev;
  352. Xint cmd;
  353. Xcaddr_t data;
  354. Xint flag;
  355. X{
  356. X int unit;
  357. X int rv;
  358. X int nb;
  359. X struct memdiskinfo *mdi;
  360. X int s;
  361. X
  362. X unit = minor(dev);
  363. X#ifdef lint
  364. X flag = flag;
  365. X#endif
  366. X if (! OKUNIT(unit))
  367. X  { return(ENXIO);
  368. X  }
  369. X mdi = &memdiskinfo[unit];
  370. X rv = 0;
  371. X switch (cmd)
  372. X  { case LIOC_MEM_SET:
  373. X       nb = * (int *) data;
  374. X       if ( (nb < 0) ||
  375. X        (nb != dbtob(btodb(nb))) ||
  376. X        (nb > max_md_size) )
  377. X    { rv = EINVAL;
  378. X      break;
  379. X    }
  380. X       if (unit_mounted(unit))
  381. X    { rv = EBUSY;
  382. X      break;
  383. X    }
  384. X       s = lockout();
  385. X       if (mdi->busy)
  386. X    { splx(s);
  387. X      return(EALREADY);
  388. X    }
  389. X       mdi->busy = 1;
  390. X       splx(s);
  391. X       if (mdi->live)
  392. X    { wmemfree(mdi->data,mdi->nbytes);
  393. X      mdi->live = 0;
  394. X    }
  395. X       if (nb > 0)
  396. X    { mdi->nbytes = nb;
  397. X      mdi->data = wmemall(memall,nb);
  398. X      if (mdi->data == 0)
  399. X       { rv = ENOMEM;
  400. X       }
  401. X      else
  402. X       { mdi->live = 1;
  403. X       }
  404. X    }
  405. X       mdi->busy = 0;
  406. X       break;
  407. X    default:
  408. X       rv = ENOTTY;
  409. X       break;
  410. X  }
  411. X return(rv);
  412. X}
  413. X
  414. Xmemdiskdump()
  415. X{
  416. X return(ENXIO);
  417. X}
  418. X
  419. Xmemdisksize(dev)
  420. Xdev_t dev;
  421. X{
  422. X int unit = minor(dev);
  423. X
  424. X if (! LIVEUNIT(unit))
  425. X  { return(-1);
  426. X  }
  427. X return(btodb(memdiskinfo[unit].nbytes));
  428. X}
  429. X
  430. Xstatic int unit_mounted(unit)
  431. Xint unit;
  432. X{
  433. X struct mount *mp;
  434. X int s;
  435. X dev_t dev;
  436. X
  437. X s = spl4(); /* as long as ipl > 0, (u)mounts can't happen */
  438. X for (mp= &mounttab[0];mp<&mounttab[NMOUNT];mp++)
  439. X  { if (mp->m_bufp != NULL)
  440. X     { dev = mp->m_dev;
  441. X       if ( (bdevsw[major(dev)].d_strategy == memdiskstrategy) &&
  442. X        (minor(dev) == unit) )
  443. X    { splx(s);
  444. X      return(1);
  445. X    }
  446. X     }
  447. X  }
  448. X splx(s);
  449. X return(0);
  450. X}
  451. X
  452. X#endif
  453. SHAR_EOF
  454. if test 4858 -ne "`wc -c memdisk.c`"
  455. then
  456. echo shar: error transmitting memdisk.c \(should have been 4858 characters\)
  457. fi
  458. echo x - mdset.c \(1367 characters\)
  459. sed 's/^X//' > mdset.c << \SHAR_EOF
  460. X#include <stdio.h>
  461. X#include <sys/file.h>
  462. X#include <sys/ioctl.h>
  463. X
  464. Xchar **argvec;
  465. X
  466. X/* usage: mdset <unit> <size> */
  467. X/* size can have suffix k or m */
  468. X/* assumes /dev/[r]mdisk%d naming scheme */
  469. X
  470. Xint mdfd;
  471. Xchar mdname[64];
  472. X
  473. Xint geti(s)
  474. Xregister char *s;
  475. X{
  476. X register int i;
  477. X
  478. X i = 0;
  479. X for (;*s;s++)
  480. X  { switch (*s)
  481. X     { case '0': case '1': case '2': case '3': case '4':
  482. X       case '5': case '6': case '7': case '8': case '9':
  483. X      i = (i * 10) + (*s - '0');
  484. X      break;
  485. X       case 'm': case 'M':
  486. X      i *= 1024;
  487. X      /* fall through */
  488. X       case 'k': case 'K':
  489. X      i *= 1024;
  490. X      break;
  491. X       default:
  492. X      return(-1);
  493. X     }
  494. X  }
  495. X return(i);
  496. X}
  497. X
  498. Xmain(ac,av)
  499. Xint ac;
  500. Xchar **av;
  501. X{
  502. X int unit;
  503. X int size;
  504. X
  505. X argvec = av;
  506. X if (ac != 3)
  507. X  { fprintf(stderr,"Usage: %s unit size\n",argvec[0]);
  508. X    exit(1);
  509. X  }
  510. X unit = geti(av[1]);
  511. X size = geti(av[2]);
  512. X if (unit < 0)
  513. X  { fprintf(stderr,"%s: bad number `%s'\n",argvec[0],av[1]);
  514. X    exit(1);
  515. X  }
  516. X if (size < 0)
  517. X  { fprintf(stderr,"%s: bad number `%s'\n",argvec[0],av[2]);
  518. X    exit(1);
  519. X  }
  520. X sprintf(mdname,"/dev/rmdisk%d",unit);
  521. X mdfd = open(mdname,O_RDWR,0);
  522. X if (mdfd < 0)
  523. X  { fprintf(stderr,"%s: cannot open %s: ",argvec[0],mdname);
  524. X    perror((char *)0);
  525. X    exit(1);
  526. X  }
  527. X if (ioctl(mdfd,LIOC_MEM_SET,&size) < 0)
  528. X  { fprintf(stderr,"%s: cannot set size for %s: ",argvec[0],mdname);
  529. X    perror((char *)0);
  530. X    exit(1);
  531. X  }
  532. X exit(0);
  533. X}
  534. SHAR_EOF
  535. if test 1367 -ne "`wc -c mdset.c`"
  536. then
  537. echo shar: error transmitting mdset.c \(should have been 1367 characters\)
  538. fi
  539. exit 0
  540. # end of shell archive
  541.  
  542.  
  543.