[4] | 1 | /* This file contains some code to guess where we have to load the
|
---|
| 2 | * RAM image device from, if started from CD. (In this case it's hard
|
---|
| 3 | * to tell where this is without diving into BIOS heuristics.)
|
---|
| 4 | *
|
---|
| 5 | * There is some nasty hard-codery in here (e.g. AT minor device numbers,
|
---|
| 6 | * MINIX cd label) that can be improved on.
|
---|
| 7 | *
|
---|
| 8 | * Changes:
|
---|
| 9 | * Jul 14, 2005 Created (Ben Gras)
|
---|
| 10 | */
|
---|
| 11 |
|
---|
| 12 | #include "fs.h"
|
---|
| 13 | #include "super.h"
|
---|
| 14 |
|
---|
| 15 | #include <minix/com.h>
|
---|
| 16 | #include <string.h>
|
---|
| 17 |
|
---|
| 18 | /*===========================================================================*
|
---|
| 19 | * cdprobe *
|
---|
| 20 | *===========================================================================*/
|
---|
| 21 | PUBLIC int cdprobe(void)
|
---|
| 22 | {
|
---|
| 23 | #define CD_SECTOR 2048
|
---|
| 24 | #define AT_MAJOR 3
|
---|
| 25 | #define AT_MINORS 4
|
---|
| 26 | int i, minors[AT_MINORS] = { 0, 5, 10, 15 }, dev = 0, found = 0;
|
---|
| 27 | char pvd[CD_SECTOR];
|
---|
| 28 | printf("\nLooking for boot CD. This may take a minute.\n"
|
---|
| 29 | "Please ignore any error messages.\n\n");
|
---|
| 30 | for(i = 0; i < AT_MINORS && !found; i++) {
|
---|
| 31 | struct super_block probe_super;
|
---|
| 32 | int r, minor;
|
---|
| 33 |
|
---|
| 34 | dev = (AT_MAJOR << MAJOR) | minors[i];
|
---|
| 35 |
|
---|
| 36 | /* Open device readonly. (This fails if the device
|
---|
| 37 | * is also writable, which a CD isn't.)
|
---|
| 38 | */
|
---|
| 39 | if ((r = dev_open(dev, FS_PROC_NR, RO_BIT)) != OK) {
|
---|
| 40 | continue;
|
---|
| 41 | }
|
---|
| 42 |
|
---|
| 43 | if ((r = dev_io(DEV_READ, dev, FS_PROC_NR, pvd,
|
---|
| 44 | 16*CD_SECTOR, sizeof(pvd), 0)) != sizeof(pvd)) {
|
---|
| 45 | dev_close(dev);
|
---|
| 46 | continue;
|
---|
| 47 | }
|
---|
| 48 | dev_close(dev);
|
---|
| 49 |
|
---|
| 50 | /* Check PVD ID. */
|
---|
| 51 | if (pvd[0] != 1 || pvd[1] != 'C' || pvd[2] != 'D' ||
|
---|
| 52 | pvd[3] != '0' || pvd[4] != '0' || pvd[5] != '1' || pvd[6] != 1 ||
|
---|
| 53 | strncmp(pvd + 40, "MINIX", 5)) {
|
---|
| 54 | continue;
|
---|
| 55 | }
|
---|
| 56 |
|
---|
| 57 | /* 3. Both c0dXp1 and p2 should have a superblock. */
|
---|
| 58 | for(minor = minors[i]+2; minor <= minors[i]+3; minor++) {
|
---|
| 59 | dev = (AT_MAJOR << MAJOR) | minor;
|
---|
| 60 | if ((r = dev_open(dev, FS_PROC_NR, R_BIT)) != OK) {
|
---|
| 61 | break;
|
---|
| 62 | }
|
---|
| 63 | probe_super.s_dev = dev;
|
---|
| 64 | r = read_super(&probe_super);
|
---|
| 65 | dev_close(dev);
|
---|
| 66 | if (r != OK) {
|
---|
| 67 | break;
|
---|
| 68 | }
|
---|
| 69 | }
|
---|
| 70 |
|
---|
| 71 | if (minor > minors[i]+3) {
|
---|
| 72 | /* Success? Then set dev to p1. */
|
---|
| 73 | dev = (AT_MAJOR << MAJOR) | (minors[i]+2);
|
---|
| 74 | found = 1;
|
---|
| 75 | break;
|
---|
| 76 | }
|
---|
| 77 | }
|
---|
| 78 |
|
---|
| 79 | if (!found) return NO_DEV;
|
---|
| 80 |
|
---|
| 81 | return dev;
|
---|
| 82 | }
|
---|
| 83 |
|
---|