]> glassweightruler.freedombox.rocks Git - Ventoy.git/blob - IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/core/ventoy_vdisk.c
074f1afeb17a33262c4c41e5248cc1f8ecb027a1
[Ventoy.git] / IPXE / ipxe_mod_code / ipxe-3fe683e / src / arch / x86 / core / ventoy_vdisk.c
1
2 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
3
4 #include <stdint.h>
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <limits.h>
8 #include <byteswap.h>
9 #include <errno.h>
10 #include <assert.h>
11 #include <ipxe/blockdev.h>
12 #include <ipxe/io.h>
13 #include <ipxe/acpi.h>
14 #include <ipxe/sanboot.h>
15 #include <ipxe/device.h>
16 #include <ipxe/pci.h>
17 #include <ipxe/eltorito.h>
18 #include <ipxe/timer.h>
19 #include <ipxe/umalloc.h>
20 #include <realmode.h>
21 #include <bios.h>
22 #include <biosint.h>
23 #include <bootsector.h>
24 #include <int13.h>
25 #include <ventoy.h>
26
27 int g_debug = 0;
28 int g_hddmode = 0;
29 int g_bios_disk80 = 0;
30 char *g_cmdline_copy;
31 void *g_initrd_addr;
32 size_t g_initrd_len;
33 ventoy_chain_head *g_chain;
34 ventoy_img_chunk *g_chunk;
35 uint32_t g_img_chunk_num;
36 ventoy_img_chunk *g_cur_chunk;
37 uint32_t g_disk_sector_size;
38 uint8_t *g_os_param_reserved;
39
40
41 ventoy_override_chunk *g_override_chunk;
42 uint32_t g_override_chunk_num;
43
44 ventoy_virt_chunk *g_virt_chunk;
45 uint32_t g_virt_chunk_num;
46
47 ventoy_sector_flag g_sector_flag[128];
48
49 #define VENTOY_ISO9660_SECTOR_OVERFLOW 2097152
50
51 int g_fixup_iso9660_secover_enable = 0;
52 int g_fixup_iso9660_secover_start = 0;
53 uint64 g_fixup_iso9660_secover_1st_secs = 0;
54 uint64 g_fixup_iso9660_secover_cur_secs = 0;
55 uint64 g_fixup_iso9660_secover_tot_secs = 0;
56
57 static struct int13_disk_address __bss16 ( ventoy_address );
58 #define ventoy_address __use_data16 ( ventoy_address )
59
60 static uint64_t ventoy_remap_lba_hdd(uint64_t lba, uint32_t *count)
61 {
62 uint32_t i;
63 uint32_t max_sectors;
64 ventoy_img_chunk *cur;
65
66 if ((NULL == g_cur_chunk) || (lba < g_cur_chunk->img_start_sector) ||
67 (lba > g_cur_chunk->img_end_sector))
68 {
69 g_cur_chunk = NULL;
70 for (i = 0; i < g_img_chunk_num; i++)
71 {
72 cur = g_chunk + i;
73 if (lba >= cur->img_start_sector && lba <= cur->img_end_sector)
74 {
75 g_cur_chunk = cur;
76 break;
77 }
78 }
79 }
80
81 if (g_cur_chunk)
82 {
83 max_sectors = g_cur_chunk->img_end_sector - lba + 1;
84 if (*count > max_sectors)
85 {
86 *count = max_sectors;
87 }
88
89 return g_cur_chunk->disk_start_sector + (lba - g_cur_chunk->img_start_sector);
90 }
91 return lba;
92 }
93
94 static uint64_t ventoy_remap_lba(uint64_t lba, uint32_t *count)
95 {
96 uint32_t i;
97 uint32_t max_sectors;
98 ventoy_img_chunk *cur;
99
100 if ((NULL == g_cur_chunk) || ((lba) < g_cur_chunk->img_start_sector) || ((lba) > g_cur_chunk->img_end_sector))
101 {
102 g_cur_chunk = NULL;
103 for (i = 0; i < g_img_chunk_num; i++)
104 {
105 cur = g_chunk + i;
106 if (lba >= cur->img_start_sector && lba <= cur->img_end_sector)
107 {
108 g_cur_chunk = cur;
109 break;
110 }
111 }
112 }
113
114 if (g_cur_chunk)
115 {
116 max_sectors = g_cur_chunk->img_end_sector - lba + 1;
117 if (*count > max_sectors)
118 {
119 *count = max_sectors;
120 }
121
122 if (512 == g_disk_sector_size)
123 {
124 return g_cur_chunk->disk_start_sector + ((lba - g_cur_chunk->img_start_sector) << 2);
125 }
126 return g_cur_chunk->disk_start_sector + (lba - g_cur_chunk->img_start_sector) * 2048 / g_disk_sector_size;
127 }
128 return lba;
129 }
130
131 static int ventoy_vdisk_read_real_hdd(uint64_t lba, unsigned int count, unsigned long buffer)
132 {
133 uint32_t left = 0;
134 uint32_t readcount = 0;
135 uint32_t tmpcount = 0;
136 uint16_t status = 0;
137 uint64_t curlba = 0;
138 uint64_t maplba = 0;
139 unsigned long phyaddr;
140
141 curlba = lba;
142 left = count;
143
144 #if VTOY_DEBUG
145 printf("ventoy_vdisk_read_real_hdd: %llu %u\n", lba, count);
146 #endif
147
148 while (left > 0)
149 {
150 readcount = left;
151 maplba = ventoy_remap_lba_hdd(curlba, &readcount);
152
153 tmpcount = readcount;
154
155 phyaddr = user_to_phys(buffer, 0);
156
157 while (tmpcount > 0)
158 {
159 /* Use INT 13, 42 to read the data from real disk */
160 ventoy_address.lba = maplba;
161 ventoy_address.buffer.segment = (uint16_t)(phyaddr >> 4);
162 ventoy_address.buffer.offset = (uint16_t)(phyaddr & 0x0F);
163
164 if (tmpcount >= 64) /* max sectors per transmit */
165 {
166 ventoy_address.count = 64;
167 tmpcount -= 64;
168 maplba += 64;
169 phyaddr += 32768;
170 }
171 else
172 {
173 ventoy_address.count = tmpcount;
174 tmpcount = 0;
175 }
176
177 __asm__ __volatile__ ( REAL_CODE ( "stc\n\t"
178 "sti\n\t"
179 "int $0x13\n\t"
180 "sti\n\t" /* BIOS bugs */
181 "jc 1f\n\t"
182 "xorw %%ax, %%ax\n\t"
183 "\n1:\n\t" )
184 : "=a" ( status )
185 : "a" ( 0x4200 ), "d" ( VENTOY_BIOS_FAKE_DRIVE ),
186 "S" ( __from_data16 ( &ventoy_address ) ) );
187 }
188
189 curlba += readcount;
190 left -= readcount;
191 buffer += (readcount * 512);
192 }
193
194 return 0;
195 }
196
197 static int ventoy_vdisk_read_real(uint64_t lba, unsigned int count, unsigned long buffer)
198 {
199 uint32_t i = 0;
200 uint32_t left = 0;
201 uint32_t readcount = 0;
202 uint32_t tmpcount = 0;
203 uint16_t status = 0;
204 uint64_t curlba = 0;
205 uint64_t maplba = 0;
206 uint64_t start = 0;
207 uint64_t end = 0;
208 uint64_t override_start = 0;
209 uint64_t override_end = 0;
210 unsigned long phyaddr;
211 unsigned long databuffer = buffer;
212 uint8_t *override_data;
213
214 curlba = lba;
215 left = count;
216
217 while (left > 0)
218 {
219 readcount = left;
220 maplba = ventoy_remap_lba(curlba, &readcount);
221
222 if (g_disk_sector_size == 512)
223 {
224 tmpcount = (readcount << 2);
225 }
226 else
227 {
228 tmpcount = (readcount * 2048) / g_disk_sector_size;
229 }
230
231 phyaddr = user_to_phys(buffer, 0);
232
233 while (tmpcount > 0)
234 {
235 /* Use INT 13, 42 to read the data from real disk */
236 ventoy_address.lba = maplba;
237 ventoy_address.buffer.segment = (uint16_t)(phyaddr >> 4);
238 ventoy_address.buffer.offset = (uint16_t)(phyaddr & 0x0F);
239
240 if (tmpcount >= 64) /* max sectors per transmit */
241 {
242 ventoy_address.count = 64;
243 tmpcount -= 64;
244 maplba += 64;
245 phyaddr += 32768;
246 }
247 else
248 {
249 ventoy_address.count = tmpcount;
250 tmpcount = 0;
251 }
252
253 __asm__ __volatile__ ( REAL_CODE ( "stc\n\t"
254 "sti\n\t"
255 "int $0x13\n\t"
256 "sti\n\t" /* BIOS bugs */
257 "jc 1f\n\t"
258 "xorw %%ax, %%ax\n\t"
259 "\n1:\n\t" )
260 : "=a" ( status )
261 : "a" ( 0x4200 ), "d" ( VENTOY_BIOS_FAKE_DRIVE ),
262 "S" ( __from_data16 ( &ventoy_address ) ) );
263 }
264
265 curlba += readcount;
266 left -= readcount;
267 buffer += (readcount * 2048);
268 }
269
270 start = lba * 2048;
271 if (start > g_chain->real_img_size_in_bytes)
272 {
273 goto end;
274 }
275
276 end = start + count * 2048;
277 for (i = 0; i < g_override_chunk_num; i++)
278 {
279 override_data = g_override_chunk[i].override_data;
280 override_start = g_override_chunk[i].img_offset;
281 override_end = override_start + g_override_chunk[i].override_size;
282
283 if (end <= override_start || start >= override_end)
284 {
285 continue;
286 }
287
288 if (start <= override_start)
289 {
290 if (end <= override_end)
291 {
292 memcpy((char *)databuffer + override_start - start, override_data, end - override_start);
293 }
294 else
295 {
296 memcpy((char *)databuffer + override_start - start, override_data, override_end - override_start);
297 }
298 }
299 else
300 {
301 if (end <= override_end)
302 {
303 memcpy((char *)databuffer, override_data + start - override_start, end - start);
304 }
305 else
306 {
307 memcpy((char *)databuffer, override_data + start - override_start, override_end - start);
308 }
309 }
310
311 if (g_fixup_iso9660_secover_enable && (!g_fixup_iso9660_secover_start) &&
312 g_override_chunk[i].override_size == sizeof(ventoy_iso9660_override))
313 {
314 ventoy_iso9660_override *dirent = (ventoy_iso9660_override *)override_data;
315 if (dirent->first_sector >= VENTOY_ISO9660_SECTOR_OVERFLOW)
316 {
317 g_fixup_iso9660_secover_start = 1;
318 g_fixup_iso9660_secover_cur_secs = 0;
319 }
320 }
321 }
322
323 end:
324
325 return 0;
326 }
327
328 uint64_t ventoy_fixup_iso9660_sector(uint64_t Lba, uint32_t secNum)
329 {
330 uint32_t i = 0;
331
332 if (g_fixup_iso9660_secover_cur_secs > 0)
333 {
334 Lba += VENTOY_ISO9660_SECTOR_OVERFLOW;
335 g_fixup_iso9660_secover_cur_secs += secNum;
336 if (g_fixup_iso9660_secover_cur_secs >= g_fixup_iso9660_secover_tot_secs)
337 {
338 g_fixup_iso9660_secover_start = 0;
339 goto end;
340 }
341 }
342 else
343 {
344 ventoy_iso9660_override *dirent;
345 ventoy_override_chunk *pOverride;
346
347 for (i = 0, pOverride = g_override_chunk; i < g_override_chunk_num; i++, pOverride++)
348 {
349 dirent = (ventoy_iso9660_override *)pOverride->override_data;
350 if (Lba == dirent->first_sector)
351 {
352 g_fixup_iso9660_secover_start = 0;
353 goto end;
354 }
355 }
356
357 if (g_fixup_iso9660_secover_start)
358 {
359 for (i = 0, pOverride = g_override_chunk; i < g_override_chunk_num; i++, pOverride++)
360 {
361 dirent = (ventoy_iso9660_override *)pOverride->override_data;
362 if (Lba + VENTOY_ISO9660_SECTOR_OVERFLOW == dirent->first_sector)
363 {
364 g_fixup_iso9660_secover_tot_secs = (dirent->size + 2047) / 2048;
365 g_fixup_iso9660_secover_cur_secs = secNum;
366 if (g_fixup_iso9660_secover_cur_secs >= g_fixup_iso9660_secover_tot_secs)
367 {
368 g_fixup_iso9660_secover_start = 0;
369 }
370 Lba += VENTOY_ISO9660_SECTOR_OVERFLOW;
371 goto end;
372 }
373 }
374 }
375 }
376
377 end:
378 return Lba;
379 }
380
381 int ventoy_vdisk_read(struct san_device *sandev, uint64_t lba, unsigned int count, unsigned long buffer)
382 {
383 uint32_t i, j;
384 uint64_t curlba;
385 uint64_t lastlba = 0;
386 uint32_t lbacount = 0;
387 unsigned long lastbuffer;
388 uint64_t readend;
389 uint64_t VirtSec;
390 ventoy_virt_chunk *node;
391 ventoy_sector_flag *cur_flag;
392 ventoy_sector_flag *sector_flag = g_sector_flag;
393 struct i386_all_regs *ix86;
394
395 if (INT13_EXTENDED_READ != sandev->int13_command)
396 {
397 DBGC(sandev, "invalid cmd %u\n", sandev->int13_command);
398 return 0;
399 }
400
401 ix86 = (struct i386_all_regs *)sandev->x86_regptr;
402
403 if (g_hddmode)
404 {
405 #if 0
406 /* need to check ?? */
407 lastlba = g_chain->virt_img_size_in_bytes / 512;
408 if (lba < lastlba)
409 {
410 if (lba + count > lastlba)
411 {
412 count = lastlba - lba;
413 }
414 ventoy_vdisk_read_real_hdd(lba, count, buffer);
415 }
416 #endif
417
418 ventoy_vdisk_read_real_hdd(lba, count, buffer);
419 ix86->regs.dl = sandev->drive;
420 return 0;
421 }
422
423 /* Workaround for SSTR PE loader error */
424 if (g_fixup_iso9660_secover_start)
425 {
426 lba = ventoy_fixup_iso9660_sector(lba, count);
427 }
428
429 readend = (lba + count) * 2048;
430 if (readend <= g_chain->real_img_size_in_bytes)
431 {
432 ventoy_vdisk_read_real(lba, count, buffer);
433 ix86->regs.dl = sandev->drive;
434 return 0;
435 }
436 else if ((lba * 2048) < g_chain->real_img_size_in_bytes)
437 {
438 /* fix for grub4dos Inconsistent data read from error */
439 memset((void *)(buffer + (count - 1) * 2048), 0, 2048);
440
441 count = (g_chain->real_img_size_in_bytes / 2048) - lba;
442 ventoy_vdisk_read_real(lba, count, buffer);
443 ix86->regs.dl = sandev->drive;
444
445 lba += count;
446 buffer += count * 2048;
447 count = (readend - g_chain->real_img_size_in_bytes) / 2048;
448 }
449
450 VirtSec = g_chain->virt_img_size_in_bytes / 2048;
451 if (lba >= VirtSec)
452 {
453 /* fix for grub4dos Inconsistent data read from error */
454 memset((void *)(buffer + (count - 1) * 2048), 0, 2048);
455
456 ix86->regs.dl = sandev->drive;
457 return 0;
458 }
459 else if (lba + count > VirtSec)
460 {
461 count = VirtSec - lba;
462 }
463
464 if (count > sizeof(g_sector_flag))
465 {
466 sector_flag = (ventoy_sector_flag *)malloc(count * sizeof(ventoy_sector_flag));
467 }
468
469 for (curlba = lba, cur_flag = sector_flag, j = 0; j < count; j++, curlba++, cur_flag++)
470 {
471 cur_flag->flag = 0;
472 for (node = g_virt_chunk, i = 0; i < g_virt_chunk_num; i++, node++)
473 {
474 if (curlba >= node->mem_sector_start && curlba < node->mem_sector_end)
475 {
476 memcpy((void *)(buffer + j * 2048),
477 (char *)g_virt_chunk + node->mem_sector_offset + (curlba - node->mem_sector_start) * 2048,
478 2048);
479 cur_flag->flag = 1;
480 break;
481 }
482 else if (curlba >= node->remap_sector_start && curlba < node->remap_sector_end)
483 {
484 cur_flag->remap_lba = node->org_sector_start + curlba - node->remap_sector_start;
485 cur_flag->flag = 2;
486 break;
487 }
488 }
489 }
490
491 for (curlba = lba, cur_flag = sector_flag, j = 0; j < count; j++, curlba++, cur_flag++)
492 {
493 if (cur_flag->flag == 2)
494 {
495 if (lastlba == 0)
496 {
497 lastbuffer = buffer + j * 2048;
498 lastlba = cur_flag->remap_lba;
499 lbacount = 1;
500 }
501 else if (lastlba + lbacount == cur_flag->remap_lba)
502 {
503 lbacount++;
504 }
505 else
506 {
507 ventoy_vdisk_read_real(lastlba, lbacount, lastbuffer);
508 lastbuffer = buffer + j * 2048;
509 lastlba = cur_flag->remap_lba;
510 lbacount = 1;
511 }
512 }
513 }
514
515 if (lbacount > 0)
516 {
517 ventoy_vdisk_read_real(lastlba, lbacount, lastbuffer);
518 }
519
520 if (sector_flag != g_sector_flag)
521 {
522 free(sector_flag);
523 }
524
525 ix86->regs.dl = sandev->drive;
526 return 0;
527 }
528
529 static void ventoy_dump_img_chunk(ventoy_chain_head *chain)
530 {
531 uint32_t i;
532 ventoy_img_chunk *chunk;
533
534 chunk = (ventoy_img_chunk *)((char *)chain + chain->img_chunk_offset);
535
536 printf("##################### ventoy_dump_img_chunk #######################\n");
537
538 for (i = 0; i < chain->img_chunk_num; i++)
539 {
540 printf("%2u: [ %u - %u ] <==> [ %llu - %llu ]\n",
541 i, chunk[i].img_start_sector, chunk[i].img_end_sector,
542 chunk[i].disk_start_sector, chunk[i].disk_end_sector);
543 }
544
545 ventoy_debug_pause();
546 }
547
548 static void ventoy_dump_override_chunk(ventoy_chain_head *chain)
549 {
550 uint32_t i;
551 ventoy_override_chunk *chunk;
552
553 chunk = (ventoy_override_chunk *)((char *)chain + chain->override_chunk_offset);
554
555 printf("##################### ventoy_dump_override_chunk #######################\n");
556
557 for (i = 0; i < g_override_chunk_num; i++)
558 {
559 printf("%2u: [ %llu, %u ]\n", i, chunk[i].img_offset, chunk[i].override_size);
560 }
561
562 ventoy_debug_pause();
563 }
564
565 static void ventoy_dump_virt_chunk(ventoy_chain_head *chain)
566 {
567 uint32_t i;
568 ventoy_virt_chunk *node;
569
570 printf("##################### ventoy_dump_virt_chunk #######################\n");
571 printf("virt_chunk_offset=%u\n", chain->virt_chunk_offset);
572 printf("virt_chunk_num=%u\n", chain->virt_chunk_num);
573
574 node = (ventoy_virt_chunk *)((char *)chain + chain->virt_chunk_offset);
575 for (i = 0; i < chain->virt_chunk_num; i++, node++)
576 {
577 printf("%2u: mem:[ %u, %u, %u ] remap:[ %u, %u, %u ]\n", i,
578 node->mem_sector_start,
579 node->mem_sector_end,
580 node->mem_sector_offset,
581 node->remap_sector_start,
582 node->remap_sector_end,
583 node->org_sector_start);
584 }
585
586 ventoy_debug_pause();
587 }
588
589 static void ventoy_dump_chain(ventoy_chain_head *chain)
590 {
591 uint32_t i = 0;
592 uint8_t chksum = 0;
593 uint8_t *guid;
594 uint8_t *sig;
595 uint8_t *vtoy_reserve;
596
597 guid = chain->os_param.vtoy_disk_guid;
598 sig = chain->os_param.vtoy_disk_signature;
599
600 for (i = 0; i < sizeof(ventoy_os_param); i++)
601 {
602 chksum += *((uint8_t *)(&(chain->os_param)) + i);
603 }
604
605 vtoy_reserve = (uint8_t *)(chain->os_param.vtoy_reserved);
606
607 printf("##################### ventoy_dump_chain #######################\n");
608
609 printf("os_param will be save at %p\n", ventoy_get_runtime_addr());
610
611 printf("os_param->chksum=0x%x (%s)\n", chain->os_param.chksum, chksum ? "FAILED" : "SUCCESS");
612 printf("os_param->vtoy_disk_guid=%02x%02x%02x%02x\n", guid[0], guid[1], guid[2], guid[3]);
613 printf("os_param->vtoy_disk_signature=%02x%02x%02x%02x\n", sig[0], sig[1], sig[2], sig[3]);
614 printf("os_param->vtoy_disk_size=%llu\n", chain->os_param.vtoy_disk_size);
615 printf("os_param->vtoy_disk_part_id=%u\n", chain->os_param.vtoy_disk_part_id);
616 printf("os_param->vtoy_disk_part_type=%u\n", chain->os_param.vtoy_disk_part_type);
617 printf("os_param->vtoy_img_path=<%s>\n", chain->os_param.vtoy_img_path);
618 printf("os_param->vtoy_img_size=<%llu>\n", chain->os_param.vtoy_img_size);
619 printf("os_param->vtoy_reserve[0]=<%u>\n", vtoy_reserve[0]);
620 printf("os_param->vtoy_reserve[1]=<%u>\n", vtoy_reserve[1]);
621 printf("os_param->vtoy_reserve[2]=<%u>\n", vtoy_reserve[2]);
622 printf("os_param->vtoy_reserve[3]=<%u>\n", vtoy_reserve[3]);
623 printf("os_param->vtoy_img_location_addr=<0x%llx>\n", chain->os_param.vtoy_img_location_addr);
624 printf("os_param->vtoy_img_location_len=<%u>\n", chain->os_param.vtoy_img_location_len);
625 ventoy_debug_pause();
626
627 printf("chain->disk_drive=0x%x\n", chain->disk_drive);
628 printf("chain->drive_map=0x%x\n", chain->drive_map);
629 printf("chain->disk_sector_size=%u\n", chain->disk_sector_size);
630 printf("chain->real_img_size_in_bytes=%llu\n", chain->real_img_size_in_bytes);
631 printf("chain->virt_img_size_in_bytes=%llu\n", chain->virt_img_size_in_bytes);
632 printf("chain->boot_catalog=%u\n", chain->boot_catalog);
633 printf("chain->img_chunk_offset=%u\n", chain->img_chunk_offset);
634 printf("chain->img_chunk_num=%u\n", chain->img_chunk_num);
635 printf("chain->override_chunk_offset=%u\n", chain->override_chunk_offset);
636 printf("chain->override_chunk_num=%u\n", chain->override_chunk_num);
637 printf("chain->virt_chunk_offset=%u\n", chain->virt_chunk_offset);
638 printf("chain->virt_chunk_num=%u\n", chain->virt_chunk_num);
639 ventoy_debug_pause();
640
641 ventoy_dump_img_chunk(chain);
642 ventoy_dump_override_chunk(chain);
643 ventoy_dump_virt_chunk(chain);
644 }
645
646 static int ventoy_update_image_location(ventoy_os_param *param)
647 {
648 uint8_t chksum = 0;
649 unsigned int i;
650 unsigned int length;
651 userptr_t address = 0;
652 ventoy_image_location *location = NULL;
653 ventoy_image_disk_region *region = NULL;
654 ventoy_img_chunk *chunk = g_chunk;
655
656 length = sizeof(ventoy_image_location) + (g_img_chunk_num - 1) * sizeof(ventoy_image_disk_region);
657
658 address = umalloc(length + 4096 * 2);
659 if (!address)
660 {
661 return 0;
662 }
663
664 if (address % 4096)
665 {
666 address += 4096 - (address % 4096);
667 }
668
669 param->chksum = 0;
670 param->vtoy_img_location_addr = user_to_phys(address, 0);
671 param->vtoy_img_location_len = length;
672
673 /* update check sum */
674 for (i = 0; i < sizeof(ventoy_os_param); i++)
675 {
676 chksum += *((uint8_t *)param + i);
677 }
678 param->chksum = (chksum == 0) ? 0 : (uint8_t)(0x100 - chksum);
679
680 location = (ventoy_image_location *)(unsigned long)(address);
681 if (NULL == location)
682 {
683 return 0;
684 }
685
686 memcpy(&location->guid, &param->guid, sizeof(ventoy_guid));
687 location->image_sector_size = g_hddmode ? 512 : 2048;
688 location->disk_sector_size = g_chain->disk_sector_size;
689 location->region_count = g_img_chunk_num;
690
691 region = location->regions;
692
693 if (g_hddmode)
694 {
695 for (i = 0; i < g_img_chunk_num; i++)
696 {
697 region->image_sector_count = chunk->disk_end_sector - chunk->disk_start_sector + 1;
698 region->image_start_sector = chunk->img_start_sector * 4;
699 region->disk_start_sector = chunk->disk_start_sector;
700 region++;
701 chunk++;
702 }
703 }
704 else
705 {
706 for (i = 0; i < g_img_chunk_num; i++)
707 {
708 region->image_sector_count = chunk->img_end_sector - chunk->img_start_sector + 1;
709 region->image_start_sector = chunk->img_start_sector;
710 region->disk_start_sector = chunk->disk_start_sector;
711 region++;
712 chunk++;
713 }
714 }
715
716 return 0;
717 }
718
719 int ventoy_boot_vdisk(void *data)
720 {
721 uint8_t chksum = 0;
722 unsigned int i;
723 unsigned int drive;
724 ventoy_img_chunk *cur;
725
726 (void)data;
727
728 ventoy_address.bufsize = offsetof ( typeof ( ventoy_address ), buffer_phys );
729
730 if (strstr(g_cmdline_copy, "debug"))
731 {
732 g_debug = 1;
733 printf("### ventoy chain boot begin... ###\n");
734 printf("cmdline: <%s>\n", g_cmdline_copy);
735 ventoy_debug_pause();
736 }
737
738 if (strstr(g_cmdline_copy, "sector512"))
739 {
740 g_hddmode = 1;
741 }
742
743 if (strstr(g_cmdline_copy, "bios80"))
744 {
745 g_bios_disk80 = 1;
746 }
747
748 g_chain = (ventoy_chain_head *)g_initrd_addr;
749 g_chunk = (ventoy_img_chunk *)((char *)g_chain + g_chain->img_chunk_offset);
750 g_img_chunk_num = g_chain->img_chunk_num;
751 g_disk_sector_size = g_chain->disk_sector_size;
752 g_cur_chunk = g_chunk;
753
754 g_os_param_reserved = (uint8_t *)(g_chain->os_param.vtoy_reserved);
755
756 /* Workaround for Windows & ISO9660 */
757 if (g_os_param_reserved[2] == ventoy_chain_windows && g_os_param_reserved[3] == 0)
758 {
759 g_fixup_iso9660_secover_enable = 1;
760 }
761
762 g_override_chunk = (ventoy_override_chunk *)((char *)g_chain + g_chain->override_chunk_offset);
763 g_override_chunk_num = g_chain->override_chunk_num;
764
765 g_virt_chunk = (ventoy_virt_chunk *)((char *)g_chain + g_chain->virt_chunk_offset);
766 g_virt_chunk_num = g_chain->virt_chunk_num;
767
768 if (g_debug)
769 {
770 for (i = 0; i < sizeof(ventoy_os_param); i++)
771 {
772 chksum += *((uint8_t *)(&(g_chain->os_param)) + i);
773 }
774 printf("os param checksum: 0x%x %s\n", g_chain->os_param.chksum, chksum ? "FAILED" : "SUCCESS");
775 }
776
777 ventoy_update_image_location(&(g_chain->os_param));
778
779 if (g_debug)
780 {
781 ventoy_dump_chain(g_chain);
782 }
783
784 if (g_hddmode)
785 {
786 for (i = 0; i < g_img_chunk_num; i++)
787 {
788 cur = g_chunk + i;
789 cur->img_start_sector *= 4;
790 cur->img_end_sector = cur->img_end_sector * 4 + 3;
791 }
792 }
793
794 drive = ventoy_int13_hook(g_chain);
795
796 if (g_debug)
797 {
798 printf("### ventoy chain boot before boot image ... ###\n");
799 ventoy_debug_pause();
800 }
801
802 ventoy_int13_boot(drive, &(g_chain->os_param), g_cmdline_copy);
803
804 if (g_debug)
805 {
806 printf("!!!!!!!!!! ventoy boot failed !!!!!!!!!!\n");
807 ventoy_debug_pause();
808 }
809
810 return 0;
811 }
812