]> glassweightruler.freedombox.rocks Git - Ventoy.git/blob - IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/core/ventoy_vdisk.c
58cc9750f60dab0477352dea7e2d28d24d050893
[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 ventoy_vdisk_read_real_hdd(lba, count, buffer);
406 ix86->regs.dl = sandev->drive;
407 return 0;
408 }
409
410 /* Workaround for SSTR PE loader error */
411 if (g_fixup_iso9660_secover_start)
412 {
413 lba = ventoy_fixup_iso9660_sector(lba, count);
414 }
415
416 readend = (lba + count) * 2048;
417 if (readend <= g_chain->real_img_size_in_bytes)
418 {
419 ventoy_vdisk_read_real(lba, count, buffer);
420 ix86->regs.dl = sandev->drive;
421 return 0;
422 }
423 else if ((lba * 2048) < g_chain->real_img_size_in_bytes)
424 {
425 /* fix for grub4dos Inconsistent data read from error */
426 memset((void *)(buffer + (count - 1) * 2048), 0, 2048);
427
428 count = (g_chain->real_img_size_in_bytes / 2048) - lba;
429 ventoy_vdisk_read_real(lba, count, buffer);
430 ix86->regs.dl = sandev->drive;
431
432 lba += count;
433 buffer += count * 2048;
434 count = (readend - g_chain->real_img_size_in_bytes) / 2048;
435 }
436
437 VirtSec = g_chain->virt_img_size_in_bytes / 2048;
438 if (lba + count > VirtSec)
439 {
440 count = VirtSec - lba;
441 }
442
443 if (count > sizeof(g_sector_flag))
444 {
445 sector_flag = (ventoy_sector_flag *)malloc(count * sizeof(ventoy_sector_flag));
446 }
447
448 for (curlba = lba, cur_flag = sector_flag, j = 0; j < count; j++, curlba++, cur_flag++)
449 {
450 cur_flag->flag = 0;
451 for (node = g_virt_chunk, i = 0; i < g_virt_chunk_num; i++, node++)
452 {
453 if (curlba >= node->mem_sector_start && curlba < node->mem_sector_end)
454 {
455 memcpy((void *)(buffer + j * 2048),
456 (char *)g_virt_chunk + node->mem_sector_offset + (curlba - node->mem_sector_start) * 2048,
457 2048);
458 cur_flag->flag = 1;
459 break;
460 }
461 else if (curlba >= node->remap_sector_start && curlba < node->remap_sector_end)
462 {
463 cur_flag->remap_lba = node->org_sector_start + curlba - node->remap_sector_start;
464 cur_flag->flag = 2;
465 break;
466 }
467 }
468 }
469
470 for (curlba = lba, cur_flag = sector_flag, j = 0; j < count; j++, curlba++, cur_flag++)
471 {
472 if (cur_flag->flag == 2)
473 {
474 if (lastlba == 0)
475 {
476 lastbuffer = buffer + j * 2048;
477 lastlba = cur_flag->remap_lba;
478 lbacount = 1;
479 }
480 else if (lastlba + lbacount == cur_flag->remap_lba)
481 {
482 lbacount++;
483 }
484 else
485 {
486 ventoy_vdisk_read_real(lastlba, lbacount, lastbuffer);
487 lastbuffer = buffer + j * 2048;
488 lastlba = cur_flag->remap_lba;
489 lbacount = 1;
490 }
491 }
492 }
493
494 if (lbacount > 0)
495 {
496 ventoy_vdisk_read_real(lastlba, lbacount, lastbuffer);
497 }
498
499 if (sector_flag != g_sector_flag)
500 {
501 free(sector_flag);
502 }
503
504 ix86->regs.dl = sandev->drive;
505 return 0;
506 }
507
508 static void ventoy_dump_img_chunk(ventoy_chain_head *chain)
509 {
510 uint32_t i;
511 ventoy_img_chunk *chunk;
512
513 chunk = (ventoy_img_chunk *)((char *)chain + chain->img_chunk_offset);
514
515 printf("##################### ventoy_dump_img_chunk #######################\n");
516
517 for (i = 0; i < chain->img_chunk_num; i++)
518 {
519 printf("%2u: [ %u - %u ] <==> [ %llu - %llu ]\n",
520 i, chunk[i].img_start_sector, chunk[i].img_end_sector,
521 chunk[i].disk_start_sector, chunk[i].disk_end_sector);
522 }
523
524 ventoy_debug_pause();
525 }
526
527 static void ventoy_dump_override_chunk(ventoy_chain_head *chain)
528 {
529 uint32_t i;
530 ventoy_override_chunk *chunk;
531
532 chunk = (ventoy_override_chunk *)((char *)chain + chain->override_chunk_offset);
533
534 printf("##################### ventoy_dump_override_chunk #######################\n");
535
536 for (i = 0; i < g_override_chunk_num; i++)
537 {
538 printf("%2u: [ %llu, %u ]\n", i, chunk[i].img_offset, chunk[i].override_size);
539 }
540
541 ventoy_debug_pause();
542 }
543
544 static void ventoy_dump_virt_chunk(ventoy_chain_head *chain)
545 {
546 uint32_t i;
547 ventoy_virt_chunk *node;
548
549 printf("##################### ventoy_dump_virt_chunk #######################\n");
550 printf("virt_chunk_offset=%u\n", chain->virt_chunk_offset);
551 printf("virt_chunk_num=%u\n", chain->virt_chunk_num);
552
553 node = (ventoy_virt_chunk *)((char *)chain + chain->virt_chunk_offset);
554 for (i = 0; i < chain->virt_chunk_num; i++, node++)
555 {
556 printf("%2u: mem:[ %u, %u, %u ] remap:[ %u, %u, %u ]\n", i,
557 node->mem_sector_start,
558 node->mem_sector_end,
559 node->mem_sector_offset,
560 node->remap_sector_start,
561 node->remap_sector_end,
562 node->org_sector_start);
563 }
564
565 ventoy_debug_pause();
566 }
567
568 static void ventoy_dump_chain(ventoy_chain_head *chain)
569 {
570 uint32_t i = 0;
571 uint8_t chksum = 0;
572 uint8_t *guid;
573 uint8_t *sig;
574 uint8_t *vtoy_reserve;
575
576 guid = chain->os_param.vtoy_disk_guid;
577 sig = chain->os_param.vtoy_disk_signature;
578
579 for (i = 0; i < sizeof(ventoy_os_param); i++)
580 {
581 chksum += *((uint8_t *)(&(chain->os_param)) + i);
582 }
583
584 vtoy_reserve = (uint8_t *)(chain->os_param.vtoy_reserved);
585
586 printf("##################### ventoy_dump_chain #######################\n");
587
588 printf("os_param will be save at %p\n", ventoy_get_runtime_addr());
589
590 printf("os_param->chksum=0x%x (%s)\n", chain->os_param.chksum, chksum ? "FAILED" : "SUCCESS");
591 printf("os_param->vtoy_disk_guid=%02x%02x%02x%02x\n", guid[0], guid[1], guid[2], guid[3]);
592 printf("os_param->vtoy_disk_signature=%02x%02x%02x%02x\n", sig[0], sig[1], sig[2], sig[3]);
593 printf("os_param->vtoy_disk_size=%llu\n", chain->os_param.vtoy_disk_size);
594 printf("os_param->vtoy_disk_part_id=%u\n", chain->os_param.vtoy_disk_part_id);
595 printf("os_param->vtoy_disk_part_type=%u\n", chain->os_param.vtoy_disk_part_type);
596 printf("os_param->vtoy_img_path=<%s>\n", chain->os_param.vtoy_img_path);
597 printf("os_param->vtoy_img_size=<%llu>\n", chain->os_param.vtoy_img_size);
598 printf("os_param->vtoy_reserve[0]=<%u>\n", vtoy_reserve[0]);
599 printf("os_param->vtoy_reserve[1]=<%u>\n", vtoy_reserve[1]);
600 printf("os_param->vtoy_reserve[2]=<%u>\n", vtoy_reserve[2]);
601 printf("os_param->vtoy_reserve[3]=<%u>\n", vtoy_reserve[3]);
602 printf("os_param->vtoy_img_location_addr=<0x%llx>\n", chain->os_param.vtoy_img_location_addr);
603 printf("os_param->vtoy_img_location_len=<%u>\n", chain->os_param.vtoy_img_location_len);
604 ventoy_debug_pause();
605
606 printf("chain->disk_drive=0x%x\n", chain->disk_drive);
607 printf("chain->drive_map=0x%x\n", chain->drive_map);
608 printf("chain->disk_sector_size=%u\n", chain->disk_sector_size);
609 printf("chain->real_img_size_in_bytes=%llu\n", chain->real_img_size_in_bytes);
610 printf("chain->virt_img_size_in_bytes=%llu\n", chain->virt_img_size_in_bytes);
611 printf("chain->boot_catalog=%u\n", chain->boot_catalog);
612 printf("chain->img_chunk_offset=%u\n", chain->img_chunk_offset);
613 printf("chain->img_chunk_num=%u\n", chain->img_chunk_num);
614 printf("chain->override_chunk_offset=%u\n", chain->override_chunk_offset);
615 printf("chain->override_chunk_num=%u\n", chain->override_chunk_num);
616 printf("chain->virt_chunk_offset=%u\n", chain->virt_chunk_offset);
617 printf("chain->virt_chunk_num=%u\n", chain->virt_chunk_num);
618 ventoy_debug_pause();
619
620 ventoy_dump_img_chunk(chain);
621 ventoy_dump_override_chunk(chain);
622 ventoy_dump_virt_chunk(chain);
623 }
624
625 static int ventoy_update_image_location(ventoy_os_param *param)
626 {
627 uint8_t chksum = 0;
628 unsigned int i;
629 unsigned int length;
630 userptr_t address = 0;
631 ventoy_image_location *location = NULL;
632 ventoy_image_disk_region *region = NULL;
633 ventoy_img_chunk *chunk = g_chunk;
634
635 length = sizeof(ventoy_image_location) + (g_img_chunk_num - 1) * sizeof(ventoy_image_disk_region);
636
637 address = umalloc(length + 4096 * 2);
638 if (!address)
639 {
640 return 0;
641 }
642
643 if (address % 4096)
644 {
645 address += 4096 - (address % 4096);
646 }
647
648 param->chksum = 0;
649 param->vtoy_img_location_addr = user_to_phys(address, 0);
650 param->vtoy_img_location_len = length;
651
652 /* update check sum */
653 for (i = 0; i < sizeof(ventoy_os_param); i++)
654 {
655 chksum += *((uint8_t *)param + i);
656 }
657 param->chksum = (chksum == 0) ? 0 : (uint8_t)(0x100 - chksum);
658
659 location = (ventoy_image_location *)(unsigned long)(address);
660 if (NULL == location)
661 {
662 return 0;
663 }
664
665 memcpy(&location->guid, &param->guid, sizeof(ventoy_guid));
666 location->image_sector_size = g_hddmode ? 512 : 2048;
667 location->disk_sector_size = g_chain->disk_sector_size;
668 location->region_count = g_img_chunk_num;
669
670 region = location->regions;
671
672 if (g_hddmode)
673 {
674 for (i = 0; i < g_img_chunk_num; i++)
675 {
676 region->image_sector_count = chunk->disk_end_sector - chunk->disk_start_sector + 1;
677 region->image_start_sector = chunk->img_start_sector * 4;
678 region->disk_start_sector = chunk->disk_start_sector;
679 region++;
680 chunk++;
681 }
682 }
683 else
684 {
685 for (i = 0; i < g_img_chunk_num; i++)
686 {
687 region->image_sector_count = chunk->img_end_sector - chunk->img_start_sector + 1;
688 region->image_start_sector = chunk->img_start_sector;
689 region->disk_start_sector = chunk->disk_start_sector;
690 region++;
691 chunk++;
692 }
693 }
694
695 return 0;
696 }
697
698 int ventoy_boot_vdisk(void *data)
699 {
700 uint8_t chksum = 0;
701 unsigned int i;
702 unsigned int drive;
703 ventoy_img_chunk *cur;
704
705 (void)data;
706
707 ventoy_address.bufsize = offsetof ( typeof ( ventoy_address ), buffer_phys );
708
709 if (strstr(g_cmdline_copy, "debug"))
710 {
711 g_debug = 1;
712 printf("### ventoy chain boot begin... ###\n");
713 printf("cmdline: <%s>\n", g_cmdline_copy);
714 ventoy_debug_pause();
715 }
716
717 if (strstr(g_cmdline_copy, "sector512"))
718 {
719 g_hddmode = 1;
720 }
721
722 if (strstr(g_cmdline_copy, "bios80"))
723 {
724 g_bios_disk80 = 1;
725 }
726
727 g_chain = (ventoy_chain_head *)g_initrd_addr;
728 g_chunk = (ventoy_img_chunk *)((char *)g_chain + g_chain->img_chunk_offset);
729 g_img_chunk_num = g_chain->img_chunk_num;
730 g_disk_sector_size = g_chain->disk_sector_size;
731 g_cur_chunk = g_chunk;
732
733 g_os_param_reserved = (uint8_t *)(g_chain->os_param.vtoy_reserved);
734
735 /* Workaround for Windows & ISO9660 */
736 if (g_os_param_reserved[2] == ventoy_chain_windows && g_os_param_reserved[3] == 0)
737 {
738 g_fixup_iso9660_secover_enable = 1;
739 }
740
741 g_override_chunk = (ventoy_override_chunk *)((char *)g_chain + g_chain->override_chunk_offset);
742 g_override_chunk_num = g_chain->override_chunk_num;
743
744 g_virt_chunk = (ventoy_virt_chunk *)((char *)g_chain + g_chain->virt_chunk_offset);
745 g_virt_chunk_num = g_chain->virt_chunk_num;
746
747 if (g_debug)
748 {
749 for (i = 0; i < sizeof(ventoy_os_param); i++)
750 {
751 chksum += *((uint8_t *)(&(g_chain->os_param)) + i);
752 }
753 printf("os param checksum: 0x%x %s\n", g_chain->os_param.chksum, chksum ? "FAILED" : "SUCCESS");
754 }
755
756 ventoy_update_image_location(&(g_chain->os_param));
757
758 if (g_debug)
759 {
760 ventoy_dump_chain(g_chain);
761 }
762
763 if (g_hddmode)
764 {
765 for (i = 0; i < g_img_chunk_num; i++)
766 {
767 cur = g_chunk + i;
768 cur->img_start_sector *= 4;
769 cur->img_end_sector = cur->img_end_sector * 4 + 3;
770 }
771 }
772
773 drive = ventoy_int13_hook(g_chain);
774
775 if (g_debug)
776 {
777 printf("### ventoy chain boot before boot image ... ###\n");
778 ventoy_debug_pause();
779 }
780
781 ventoy_int13_boot(drive, &(g_chain->os_param), g_cmdline_copy);
782
783 if (g_debug)
784 {
785 printf("!!!!!!!!!! ventoy boot failed !!!!!!!!!!\n");
786 ventoy_debug_pause();
787 }
788
789 return 0;
790 }
791