7 #include <syslinux/disk.h>
10 void error(const char *msg)
15 int guid_is0(const struct guid *guid)
17 return !*(const uint64_t *)guid && !*((const uint64_t *)guid+1);
28 cnt = read(0, &junk, 1);
29 } while (cnt > 0 || (cnt < 0 && errno == EAGAIN));
34 cnt = read(0, &junk, 1);
35 } while (!cnt || (cnt < 0 && errno == EAGAIN));
38 uint32_t lba2chs(const struct disk_info *di, uint64_t lba)
43 if (lba >= di->cyl * di->head * di->sect) {
49 s = ((uint32_t)lba % di->sect) + 1;
50 t = (uint32_t)lba / di->sect;
57 return h | (s << 8) | ((c & 0x300) << 6) | ((c & 0xFF) << 16);
61 return 0x00FFFFFE; /* 1023/63/254 */
65 * this is somewhat "useful" with partitioned floppy,
66 * maybe stick to 2.88mb ?
68 return 0x004F1201; /* 79/18/1 */
70 return 0x004F2401; /* 79/36/1 */
74 uint32_t get_file_lba(const char *filename)
79 /* Start with clean registers */
80 memset(&inregs, 0, sizeof(com32sys_t));
82 /* Put the filename in the bounce buffer */
83 strlcpy(__com32.cs_bounce, filename, __com32.cs_bounce_size);
85 /* Call comapi_open() which returns a structure pointer in SI
86 * to a structure whose first member happens to be the LBA.
88 inregs.eax.w[0] = 0x0006;
89 inregs.esi.w[0] = OFFS(__com32.cs_bounce);
90 inregs.es = SEG(__com32.cs_bounce);
91 __com32.cs_intcall(0x22, &inregs, &inregs);
93 if ((inregs.eflags.l & EFLAGS_CF) || inregs.esi.w[0] == 0) {
94 return 0; /* Filename not found */
97 /* Since the first member is the LBA, we simply cast */
98 lba = *((uint32_t *) MK_PTR(inregs.ds, inregs.esi.w[0]));
100 /* Clean the registers for the next call */
101 memset(&inregs, 0, sizeof(com32sys_t));
103 /* Put the filename in the bounce buffer */
104 strlcpy(__com32.cs_bounce, filename, __com32.cs_bounce_size);
106 /* Call comapi_close() to free the structure */
107 inregs.eax.w[0] = 0x0008;
108 inregs.esi.w[0] = OFFS(__com32.cs_bounce);
109 inregs.es = SEG(__com32.cs_bounce);
110 __com32.cs_intcall(0x22, &inregs, &inregs);
115 /* drive offset detection */
116 int drvoff_detect(int type, unsigned int *off)
118 if (bpbV40 <= type && type <= bpbVNT) {
120 } else if (type == bpbV70) {
129 * heuristics could certainly be improved
131 int bpb_detect(const uint8_t *sec)
133 int a, b, c, jmp = -1, rev = -1;
135 /* media descriptor check */
136 if ((sec[0x15] & 0xF0) != 0xF0)
139 if (sec[0] == 0xEB) /* jump short */
140 jmp = 2 + *(int8_t *)(sec + 1);
141 else if (sec[0] == 0xE9) /* jump near */
142 jmp = 3 + *(int16_t *)(sec + 1);
144 if (jmp < 0) /* no boot code at all ? */
148 if (jmp < 0x18 || jmp > 0x1F0)
152 if (jmp >= 0x18 && jmp < 0x1E)
154 else if (jmp >= 0x1E && jmp < 0x20)
156 else if (jmp >= 0x20 && jmp < 0x24)
158 else if (jmp >= 0x24 && jmp < 0x46)
161 /* TODO: some better V2 - V3.4 checks ? */
167 a = memcmp(sec + 0x03, "NTFS", 4);
168 b = memcmp(sec + 0x36, "FAT", 3);
169 c = memcmp(sec + 0x52, "FAT", 3); /* ext. DOS 7+ bs */
171 if ((sec[0x26] & 0xFE) == 0x28 && !b) {
173 } else if (sec[0x26] == 0x80 && !a) {
175 } else if ((sec[0x42] & 0xFE) == 0x28 && !c) {
183 /* vim: set ts=8 sts=4 sw=4 noet: */