1 /*
2  * Copyright (c) 2007 Vreixo Formoso
3  * Copyright (c) 2010 - 2018 Thomas Schmitt
4  *
5  * This file is part of the libisofs project; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License version 2
7  * or later as published by the Free Software Foundation.
8  * See COPYING file for details.
9  */
10 
11 /**
12  * Declare El-Torito related structures.
13  * References:
14  *  "El Torito" Bootable CD-ROM Format Specification Version 1.0 (1995)
15  */
16 
17 #ifndef LIBISO_ELTORITO_H
18 #define LIBISO_ELTORITO_H
19 
20 #include "ecma119.h"
21 #include "node.h"
22 
23 /**
24  * A node that acts as a placeholder for an El-Torito catalog.
25  */
26 struct Iso_Boot
27 {
28     IsoNode node;
29 
30     /* Want to get content of loaded boot catalog.
31        Vreixo took care not to make it an IsoFile at load time.
32        So this is implemented independently of IsoStream.
33      */
34     uint32_t lba;
35     off_t size;
36     char *content;
37 };
38 
39 /* Not more than 32 so that all entries fit into 2048 bytes */
40 #define Libisofs_max_boot_imageS 32
41 
42 struct el_torito_boot_catalog {
43     IsoBoot *node; /* node of the catalog */
44 
45     int num_bootimages;
46     struct el_torito_boot_image *bootimages[Libisofs_max_boot_imageS];
47                                                   /* [0]= default boot image */
48 
49     /* Weight value for image sorting */
50     int sort_weight;
51 };
52 
53 struct el_torito_boot_image {
54     IsoFile *image;
55 
56     /* Overrides .image if >= 0 : array index of appended partition */
57     int appended_idx;
58     uint32_t appended_start; /* In blocks of 2048 bytes */
59     uint32_t appended_size;  /* In blocks of  512 bytes */
60 
61     unsigned int bootable:1; /**< If the entry is bootable. */
62     /**
63      * Whether the boot image seems to contain a boot_info_table
64      */
65     unsigned int seems_boot_info_table:1;
66     unsigned int seems_grub2_boot_info:1;
67     /**
68      * Whether the boot image seems to be capable of isohybrid
69      */
70     unsigned int seems_isohybrid_capable:1;
71     /**
72      * isolinux options
73      * bit 0 -> whether to patch image
74      * bit 1 -> whether to put built-in isolinux 3.72 isohybrid-MBR into image
75      *          System Area (deprecated)
76      *
77      *  bit2-7= Mentioning in isohybrid GPT
78      *          0= do not mention in GPT
79      *          1= mention as EFI partition
80      *          2= Mention as HFS+ partition
81      *  bit8= Mention in isohybrid Apple partition map
82      */
83     unsigned int isolinux_options;
84 
85     unsigned char type; /**< The type of image :
86                               0=no emulation , 1=fd 1.2 MB , 2=fd 1.4 MB
87                               3=fd 3.8 MB , 4=hdd (size in partition table)
88                          */
89     unsigned char partition_type; /**< type of partition for HD-emul images */
90     uint32_t emul_hdd_size; /* 512-bytes LBA after highest partition end from
91                                HD-emul partition table
92                              */
93     uint16_t load_seg; /**< Load segment for the initial boot image. */
94     uint16_t load_size; /**< Number of sectors to load. */
95     int load_size_full; /* 1= override load_size by image size */
96 
97     /* Byte 1 of Validation Entry or Section Header Entry:
98        0= 80x86, 1= PowerPC, 2= Mac, 0xef= EFI */
99     uint8_t platform_id;
100     uint8_t id_string[28];
101     uint8_t selection_crit[20];
102 
103 };
104 
105 /** El-Torito, 2.1 */
106 struct el_torito_validation_entry {
107     uint8_t header_id           BP(1, 1);
108     uint8_t platform_id         BP(2, 2);
109     uint8_t reserved            BP(3, 4);
110     uint8_t id_string           BP(5, 28);
111     uint8_t checksum            BP(29, 30);
112     uint8_t key_byte1           BP(31, 31);
113     uint8_t key_byte2           BP(32, 32);
114 };
115 
116 /** El-Torito, 2.2 */
117 struct el_torito_default_entry {
118     uint8_t boot_indicator      BP(1, 1);
119     uint8_t boot_media_type     BP(2, 2);
120     uint8_t load_seg            BP(3, 4);
121     uint8_t system_type         BP(5, 5);
122     uint8_t unused1             BP(6, 6);
123     uint8_t sec_count           BP(7, 8);
124     uint8_t block               BP(9, 12);
125     uint8_t unused2             BP(13, 32);
126 };
127 
128 /** El-Torito, 2.3 */
129 struct el_torito_section_header {
130     uint8_t header_indicator    BP(1, 1);
131     uint8_t platform_id         BP(2, 2);
132     uint8_t num_entries         BP(3, 4);
133     uint8_t id_string           BP(5, 32);
134 };
135 
136 /** El-Torito, 2.4 */
137 struct el_torito_section_entry {
138     uint8_t boot_indicator      BP(1, 1);
139     uint8_t boot_media_type     BP(2, 2);
140     uint8_t load_seg            BP(3, 4);
141     uint8_t system_type         BP(5, 5);
142     uint8_t unused1             BP(6, 6);
143     uint8_t sec_count           BP(7, 8);
144     uint8_t block               BP(9, 12);
145     uint8_t selec_criteria      BP(13, 13);
146     uint8_t vendor_sc           BP(14, 32);
147 };
148 
149 void el_torito_boot_catalog_free(struct el_torito_boot_catalog *cat);
150 
151 /**
152  * Create a IsoFileSrc for writing the el-torito catalog for the given
153  * target, and add it to target. If the target already has a src for the
154  * catalog, it just returns.
155  */
156 int el_torito_catalog_file_src_create(Ecma119Image *target, IsoFileSrc **src);
157 
158 /**
159  * Create a writer for el-torito information.
160  */
161 int eltorito_writer_create(Ecma119Image *target);
162 
163 /**
164  * Insert boot info table content into buf.
165  *
166  * @return
167  *      1 on success, 0 error (but continue), < 0 error
168  */
169 int make_boot_info_table(uint8_t *buf, uint32_t pvd_lba,
170                          uint32_t boot_lba, uint32_t imgsize);
171 
172 /* Patch the boot images if indicated.
173 */
174 int iso_patch_eltoritos(Ecma119Image *t);
175 
176 
177 /* Parameters for patch_grub2_boot_image()
178    Might later become variables in struct el_torito_boot_image.
179 */
180 #define Libisofs_grub2_elto_patch_poS    (512 * 5 - 12)
181 #define Libisofs_grub2_elto_patch_offsT  5
182 
183 
184 /* Maximum size of a boot image which is marked by
185    el_torito_set_isolinux_options() for patching (boot info table,
186    GRUB2 boot info, maybe others).
187 */
188 #define Libisofs_elto_max_patchablE      (32 * 1024 * 1024)
189 
190 
191 #endif /* LIBISO_ELTORITO_H */
192