]> glassweightruler.freedombox.rocks Git - Ventoy.git/blob - wimboot/wimboot-2.7.3/src/vdisk.h
1.1.07 release
[Ventoy.git] / wimboot / wimboot-2.7.3 / src / vdisk.h
1 #ifndef _VDISK_H
2 #define _VDISK_H
3
4 /*
5 * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA.
21 */
22
23 /**
24 * @file
25 *
26 * Virtual disk emulation
27 *
28 */
29
30 #include <stdint.h>
31
32 /** Number of cylinders */
33 #define VDISK_CYLINDERS 1024 /* Maximum possible */
34
35 /** Number of heads */
36 #define VDISK_HEADS 255
37
38 /** Number of sectors per track */
39 #define VDISK_SECTORS_PER_TRACK 63
40
41 /** Sector size (in bytes) */
42 #define VDISK_SECTOR_SIZE 512
43
44 /** Partition start LBA */
45 #define VDISK_PARTITION_LBA 128
46
47 /** Cluster size (in sectors) */
48 #define VDISK_CLUSTER_COUNT 64
49
50 /** Cluster size (in bytes) */
51 #define VDISK_CLUSTER_SIZE ( VDISK_CLUSTER_COUNT * VDISK_SECTOR_SIZE )
52
53 /** Number of clusters */
54 #define VDISK_CLUSTERS 0x03ffc000ULL /* Fill 2TB disk */
55
56 /** Maximum number of virtual files
57 *
58 * The total number of files must be strictly less than the number of
59 * sectors per cluster.
60 */
61 #define VDISK_MAX_FILES ( VDISK_CLUSTER_COUNT - 1 )
62
63 /** Maximum file size (in sectors) */
64 #define VDISK_FILE_COUNT 0x800000UL /* max for 32-bit address space */
65
66 /** Maximum file size (in clusters) */
67 #define VDISK_FILE_CLUSTERS ( VDISK_FILE_COUNT / VDISK_CLUSTER_COUNT )
68
69 /** File starting LBA */
70 #define VDISK_FILE_LBA( idx ) ( ( (idx) + 1 ) * VDISK_FILE_COUNT )
71
72 /** File index from LBA */
73 #define VDISK_FILE_IDX( lba ) ( ( (lba) / VDISK_FILE_COUNT ) - 1 )
74
75 /** File offset (in bytes) from LBA */
76 #define VDISK_FILE_OFFSET( lba ) \
77 ( ( (lba) % VDISK_FILE_COUNT ) * VDISK_SECTOR_SIZE )
78
79 /** File index from directory entry LBA */
80 #define VDISK_FILE_DIRENT_IDX( lba ) ( ( (lba) - 1 ) % VDISK_CLUSTER_COUNT )
81
82 /** Number of sectors allocated for FAT */
83 #define VDISK_SECTORS_PER_FAT \
84 ( ( ( VDISK_CLUSTERS * sizeof ( uint32_t ) + \
85 VDISK_CLUSTER_SIZE - 1 ) / VDISK_CLUSTER_SIZE ) \
86 * VDISK_CLUSTER_COUNT )
87
88 /** Number of reserved sectors */
89 #define VDISK_RESERVED_COUNT VDISK_CLUSTER_COUNT
90
91 /** Starting cluster number for file */
92 #define VDISK_FILE_CLUSTER( idx ) \
93 ( ( ( ( VDISK_FILE_COUNT - VDISK_PARTITION_LBA - \
94 VDISK_RESERVED_COUNT - VDISK_SECTORS_PER_FAT ) / \
95 VDISK_CLUSTER_COUNT ) + 2 ) + \
96 ( (idx) * VDISK_FILE_CLUSTERS ) )
97
98 /** Total number of sectors within partition */
99 #define VDISK_PARTITION_COUNT \
100 ( VDISK_RESERVED_COUNT + VDISK_SECTORS_PER_FAT + \
101 ( VDISK_CLUSTERS * VDISK_CLUSTER_COUNT ) )
102
103 /** Number of sectors */
104 #define VDISK_COUNT ( VDISK_PARTITION_LBA + VDISK_PARTITION_COUNT )
105
106 /** Calculate sector from cluster */
107 #define VDISK_CLUSTER_SECTOR( cluster ) \
108 ( ( ( (cluster) - 2 ) * VDISK_CLUSTER_COUNT ) + \
109 VDISK_RESERVED_COUNT + VDISK_SECTORS_PER_FAT )
110
111 /*****************************************************************************
112 *
113 * Master Boot Record
114 *
115 *****************************************************************************
116 */
117
118 /** Master Boot Record LBA */
119 #define VDISK_MBR_LBA 0x00000000
120
121 /** Master Boot Record sector count */
122 #define VDISK_MBR_COUNT 1
123
124 /** Partition table entry */
125 struct vdisk_partition {
126 /** Bootable flag */
127 uint8_t bootable;
128 /** C/H/S start address */
129 uint8_t chs_start[3];
130 /** System indicator (partition type) */
131 uint8_t type;
132 /** C/H/S end address */
133 uint8_t chs_end[3];
134 /** Linear start address */
135 uint32_t start;
136 /** Linear length */
137 uint32_t length;
138 } __attribute__ (( packed ));
139
140 /** Master Boot Record */
141 struct vdisk_mbr {
142 /** Code area */
143 uint8_t code[440];
144 /** Disk signature */
145 uint32_t signature;
146 /** Padding */
147 uint8_t pad[2];
148 /** Partition table */
149 struct vdisk_partition partitions[4];
150 /** 0x55aa signature */
151 uint16_t magic;
152 } __attribute__ (( packed ));
153
154 /** MBR boot partition indiciator */
155 #define VDISK_MBR_BOOTABLE 0x80
156
157 /** MBR type indicator for FAT32 */
158 #define VDISK_MBR_TYPE_FAT32 0x0c
159
160 /** MBR signature */
161 #define VDISK_MBR_SIGNATURE 0xc0ffeeee
162
163 /** MBR magic */
164 #define VDISK_MBR_MAGIC 0xaa55
165
166 /*****************************************************************************
167 *
168 * Volume Boot Record
169 *
170 *****************************************************************************
171 */
172
173 /** Volume Boot Record LBA */
174 #define VDISK_VBR_LBA VDISK_PARTITION_LBA
175
176 /** Volume Boot Record sector count */
177 #define VDISK_VBR_COUNT 1
178
179 /** Volume Boot Record */
180 struct vdisk_vbr {
181 /** Jump instruction */
182 uint8_t jump[3];
183 /** OEM identifier */
184 char oemid[8];
185 /** Number of bytes per sector */
186 uint16_t bytes_per_sector;
187 /** Number of sectors per cluster */
188 uint8_t sectors_per_cluster;
189 /** Number of reserved sectors */
190 uint16_t reserved_sectors;
191 /** Number of FATs */
192 uint8_t fats;
193 /** Number of root directory entries (FAT12/FAT16 only) */
194 uint16_t root_directory_entries;
195 /** Total number of sectors (0 if more than 65535) */
196 uint16_t sectors_short;
197 /** Media descriptor type */
198 uint8_t media;
199 /** Number of sectors per FAT (FAT12/FAT16 only) */
200 uint16_t sectors_per_fat_short;
201 /** Number of sectors per track */
202 uint16_t sectors_per_track;
203 /** Number of heads */
204 uint16_t heads;
205 /** Number of hidden sectors (i.e. LBA of start of partition) */
206 uint32_t hidden_sectors;
207 /** Total number of sectors */
208 uint32_t sectors;
209
210 /* FAT32-specific fields */
211
212 /** Sectors per FAT */
213 uint32_t sectors_per_fat;
214 /** Flags */
215 uint16_t flags;
216 /** FAT version number */
217 uint16_t version;
218 /** Root directory cluster */
219 uint32_t root;
220 /** FSInfo sector */
221 uint16_t fsinfo;
222 /** Backup boot sector */
223 uint16_t backup;
224 /** Reserved */
225 uint8_t reserved[12];
226 /** Drive number */
227 uint8_t drive;
228 /** Windows NT flags */
229 uint8_t nt_flags;
230 /** Signature */
231 uint8_t signature;
232 /** Volume ID serial */
233 uint32_t serial;
234 /** Label (space-padded) */
235 char label[11];
236 /** System identifier */
237 char system[8];
238 /** Boot code */
239 uint8_t code[420];
240 /** 0x55aa signature */
241 uint16_t magic;
242 } __attribute__ (( packed ));
243
244 /** VBR jump instruction
245 *
246 * bootmgr.exe will actually fail unless this is present. Someone
247 * must read specification documents without bothering to understand
248 * what's really happening.
249 */
250 #define VDISK_VBR_JUMP_WTF_MS 0xe9
251
252 /** VBR OEM ID */
253 #define VDISK_VBR_OEMID "wimboot\0"
254
255 /** VBR media type */
256 #define VDISK_VBR_MEDIA 0xf8
257
258 /** VBR signature */
259 #define VDISK_VBR_SIGNATURE 0x29
260
261 /** VBR serial number */
262 #define VDISK_VBR_SERIAL 0xf00df00d
263
264 /** VBR label */
265 #define VDISK_VBR_LABEL "wimboot "
266
267 /** VBR system identifier */
268 #define VDISK_VBR_SYSTEM "FAT32 "
269
270 /** VBR magic */
271 #define VDISK_VBR_MAGIC 0xaa55
272
273 /*****************************************************************************
274 *
275 * FSInfo
276 *
277 *****************************************************************************
278 */
279
280 /** FSInfo sector */
281 #define VDISK_FSINFO_SECTOR 0x00000001
282
283 /** FSInfo LBA */
284 #define VDISK_FSINFO_LBA ( VDISK_VBR_LBA + VDISK_FSINFO_SECTOR )
285
286 /** FSInfo sector count */
287 #define VDISK_FSINFO_COUNT 1
288
289 /** FSInfo */
290 struct vdisk_fsinfo {
291 /** First signature */
292 uint32_t magic1;
293 /** Reserved */
294 uint8_t reserved_1[480];
295 /** Second signature */
296 uint32_t magic2;
297 /** Free cluster count */
298 uint32_t free_count;
299 /** Next free cluster */
300 uint32_t next_free;
301 /** Reserved */
302 uint8_t reserved_2[12];
303 /** Third signature */
304 uint32_t magic3;
305 } __attribute__ (( packed ));
306
307 /** FSInfo first signature */
308 #define VDISK_FSINFO_MAGIC1 0x41615252
309
310 /** FSInfo second signature */
311 #define VDISK_FSINFO_MAGIC2 0x61417272
312
313 /** FSInfo next free cluster */
314 #define VDISK_FSINFO_NEXT_FREE 0xffffffff /* No free clusters */
315
316 /** FSInfo third signature */
317 #define VDISK_FSINFO_MAGIC3 0xaa550000
318
319 /*****************************************************************************
320 *
321 * Backup Volume Boot Record
322 *
323 *****************************************************************************
324 */
325
326 /** Backup Volume Boot Record sector */
327 #define VDISK_BACKUP_VBR_SECTOR 0x00000006
328
329 /** Backup Volume Boot Record LBA */
330 #define VDISK_BACKUP_VBR_LBA ( VDISK_VBR_LBA + VDISK_BACKUP_VBR_SECTOR )
331
332 /** Backup Volume Boot Record sector count */
333 #define VDISK_BACKUP_VBR_COUNT 1
334
335 /*****************************************************************************
336 *
337 * File Allocation Table
338 *
339 *****************************************************************************
340 */
341
342 /** FAT sector */
343 #define VDISK_FAT_SECTOR VDISK_RESERVED_COUNT
344
345 /** FAT LBA */
346 #define VDISK_FAT_LBA ( VDISK_VBR_LBA + VDISK_FAT_SECTOR )
347
348 /** FAT sector count */
349 #define VDISK_FAT_COUNT VDISK_SECTORS_PER_FAT
350
351 /** FAT end marker */
352 #define VDISK_FAT_END_MARKER 0x0ffffff8
353
354 /*****************************************************************************
355 *
356 * Directory entries
357 *
358 *****************************************************************************
359 */
360
361 /** An 8.3 filename record */
362 struct vdisk_short_filename {
363 /** Filename */
364 union {
365 /** Structured 8.3 base name and extension */
366 struct {
367 /** Base name */
368 char base[8];
369 /** Extension */
370 char ext[3];
371 } __attribute__ (( packed ));
372 /** Raw bytes */
373 uint8_t raw[11];
374 } filename;
375 /** Attributes */
376 uint8_t attr;
377 /** Reserved */
378 uint8_t reserved;
379 /** Creation time in tenths of a second */
380 uint8_t created_deciseconds;
381 /** Creation time (HMS packed) */
382 uint16_t created_time;
383 /** Creation date (YMD packed) */
384 uint16_t created_date;
385 /** Last accessed date (YMD packed) */
386 uint16_t accessed_date;
387 /** High 16 bits of starting cluster number */
388 uint16_t cluster_high;
389 /** Modification time (HMS packed) */
390 uint16_t modified_time;
391 /** Modification date (YMD packed) */
392 uint16_t modified_date;
393 /** Low 16 bits of starting cluster number */
394 uint16_t cluster_low;
395 /** Size */
396 uint32_t size;
397 } __attribute__ (( packed ));
398
399 /** A long filename record */
400 struct vdisk_long_filename {
401 /** Sequence number */
402 uint8_t sequence;
403 /** Name characters */
404 uint16_t name_1[5];
405 /** Attributes */
406 uint8_t attr;
407 /** Type */
408 uint8_t type;
409 /** Checksum of 8.3 name */
410 uint8_t checksum;
411 /** Name characters */
412 uint16_t name_2[6];
413 /** Reserved */
414 uint16_t reserved;
415 /** Name characters */
416 uint16_t name_3[2];
417 } __attribute__ (( packed ));
418
419 /** Directory entry attributes */
420 enum vdisk_directory_entry_attributes {
421 VDISK_READ_ONLY = 0x01,
422 VDISK_HIDDEN = 0x02,
423 VDISK_SYSTEM = 0x04,
424 VDISK_VOLUME_LABEL = 0x08,
425 VDISK_DIRECTORY = 0x10,
426 };
427
428 /** Long filename end-of-sequence marker */
429 #define VDISK_LFN_END 0x40
430
431 /** Long filename attributes */
432 #define VDISK_LFN_ATTR \
433 ( VDISK_READ_ONLY | VDISK_HIDDEN | VDISK_SYSTEM | VDISK_VOLUME_LABEL )
434
435 /** A directory entry */
436 union vdisk_directory_entry {
437 /** Deleted file marker */
438 uint8_t deleted;
439 /** 8.3 filename */
440 struct vdisk_short_filename dos;
441 /** Long filename */
442 struct vdisk_long_filename lfn;
443 } __attribute__ (( packed ));
444
445 /** Magic marker for deleted files */
446 #define VDISK_DIRENT_DELETED 0xe5
447
448 /** Number of directory entries per sector */
449 #define VDISK_DIRENT_PER_SECTOR \
450 ( VDISK_SECTOR_SIZE / \
451 sizeof ( union vdisk_directory_entry ) )
452
453 /** A directory sector */
454 struct vdisk_directory {
455 /** Entries */
456 union vdisk_directory_entry entry[VDISK_DIRENT_PER_SECTOR];
457 } __attribute__ (( packed ));
458
459 /*****************************************************************************
460 *
461 * Root directory
462 *
463 *****************************************************************************
464 */
465
466 /** Root directory cluster */
467 #define VDISK_ROOT_CLUSTER 2
468
469 /** Root directory sector */
470 #define VDISK_ROOT_SECTOR VDISK_CLUSTER_SECTOR ( VDISK_ROOT_CLUSTER )
471
472 /** Root directory LBA */
473 #define VDISK_ROOT_LBA ( VDISK_VBR_LBA + VDISK_ROOT_SECTOR )
474
475 /*****************************************************************************
476 *
477 * Boot directory
478 *
479 *****************************************************************************
480 */
481
482 /** Boot directory cluster */
483 #define VDISK_BOOT_CLUSTER 3
484
485 /** Boot directory sector */
486 #define VDISK_BOOT_SECTOR VDISK_CLUSTER_SECTOR ( VDISK_BOOT_CLUSTER )
487
488 /** Boot directory LBA */
489 #define VDISK_BOOT_LBA ( VDISK_VBR_LBA + VDISK_BOOT_SECTOR )
490
491 /*****************************************************************************
492 *
493 * Sources directory
494 *
495 *****************************************************************************
496 */
497
498 /** Sources directory cluster */
499 #define VDISK_SOURCES_CLUSTER 4
500
501 /** Sources directory sector */
502 #define VDISK_SOURCES_SECTOR VDISK_CLUSTER_SECTOR ( VDISK_SOURCES_CLUSTER )
503
504 /** Sources directory LBA */
505 #define VDISK_SOURCES_LBA ( VDISK_VBR_LBA + VDISK_SOURCES_SECTOR )
506
507 /*****************************************************************************
508 *
509 * Fonts directory
510 *
511 *****************************************************************************
512 */
513
514 /** Fonts directory cluster */
515 #define VDISK_FONTS_CLUSTER 5
516
517 /** Fonts directory sector */
518 #define VDISK_FONTS_SECTOR VDISK_CLUSTER_SECTOR ( VDISK_FONTS_CLUSTER )
519
520 /** Fonts directory LBA */
521 #define VDISK_FONTS_LBA ( VDISK_VBR_LBA + VDISK_FONTS_SECTOR )
522
523 /*****************************************************************************
524 *
525 * Resources directory
526 *
527 *****************************************************************************
528 */
529
530 /** Resources directory cluster */
531 #define VDISK_RESOURCES_CLUSTER 6
532
533 /** Resources directory sector */
534 #define VDISK_RESOURCES_SECTOR VDISK_CLUSTER_SECTOR ( VDISK_RESOURCES_CLUSTER )
535
536 /** Resources directory LBA */
537 #define VDISK_RESOURCES_LBA ( VDISK_VBR_LBA + VDISK_RESOURCES_SECTOR )
538
539 /*****************************************************************************
540 *
541 * EFI directory
542 *
543 *****************************************************************************
544 */
545
546 /** EFI directory cluster */
547 #define VDISK_EFI_CLUSTER 7
548
549 /** EFI directory sector */
550 #define VDISK_EFI_SECTOR VDISK_CLUSTER_SECTOR ( VDISK_EFI_CLUSTER )
551
552 /** EFI directory LBA */
553 #define VDISK_EFI_LBA ( VDISK_VBR_LBA + VDISK_EFI_SECTOR )
554
555 /*****************************************************************************
556 *
557 * Microsoft directory
558 *
559 *****************************************************************************
560 */
561
562 /** Microsoft directory cluster */
563 #define VDISK_MICROSOFT_CLUSTER 8
564
565 /** Microsoft directory sector */
566 #define VDISK_MICROSOFT_SECTOR VDISK_CLUSTER_SECTOR ( VDISK_MICROSOFT_CLUSTER )
567
568 /** Microsoft directory LBA */
569 #define VDISK_MICROSOFT_LBA ( VDISK_VBR_LBA + VDISK_MICROSOFT_SECTOR )
570
571 /*****************************************************************************
572 *
573 * Files
574 *
575 *****************************************************************************
576 */
577
578 /** Maximum virtual filename length (excluding NUL) */
579 #define VDISK_NAME_LEN 31
580
581 /** A virtual file */
582 struct vdisk_file {
583 /** Filename */
584 char name[ VDISK_NAME_LEN + 1 /* NUL */ ];
585 /** Opaque token */
586 void *opaque;
587 /** Length (excluding any zero-padding) */
588 size_t len;
589 /** Length (including any zero-padding) */
590 size_t xlen;
591 /** Read data
592 *
593 * @v file Virtual file
594 * @v data Data buffer
595 * @v offset Starting offset
596 * @v len Length
597 */
598 void ( * read ) ( struct vdisk_file *file, void *data, size_t offset,
599 size_t len );
600 /** Patch data (optional)
601 *
602 * @v file Virtual file
603 * @v data Data buffer
604 * @v offset Starting offset
605 * @v len Length
606 */
607 void ( * patch ) ( struct vdisk_file *file, void *data, size_t offset,
608 size_t len );
609 };
610
611 extern struct vdisk_file vdisk_files[VDISK_MAX_FILES];
612
613 extern void vdisk_read ( uint64_t lba, unsigned int count, void *data );
614 extern struct vdisk_file *
615 vdisk_add_file ( const char *name, void *opaque, size_t len,
616 void ( * read ) ( struct vdisk_file *file, void *data,
617 size_t offset, size_t len ) );
618 extern void
619 vdisk_patch_file ( struct vdisk_file *file,
620 void ( * patch ) ( struct vdisk_file *file, void *data,
621 size_t offset, size_t len ) );
622
623 #endif /* _VDISK_H */