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