biso_eltorito.h 6.63 KB
Newer Older
longpanda's avatar
longpanda committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
/******************************************************************************
 * bios_eltorito.h
 *
 * Copyright (c) 2020, longpanda <admin@ventoy.net>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 3 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 *
 */


/*
 * EL TORITO扩展规范相关定义
 * 注意点:
 *   [1] EL TORITO扩展规范里定义的数据都是小字节序的 
 */

#ifndef __BISO_ELTORITO_H__
#define __BISO_ELTORITO_H__

/* 
 * EL TORITO规范里对于Boot Record里面BootCatlog指向的扩展区域做了
 * 结构定义,分成一条条的表项,每一条表项固定32个字节长,1个扇区
 * 可以保存64条表项。BootCatlog可以占用多个扇区。
 * 表项必须按照如下顺序保存:
 *   ID   Entry
 *    0   Validation Entry
 *    1   Initial Entry
 *    2   Section Header
 *    3   Section Entry
 *    4   Section Extension Entry 1
 *    5   Section Extension Entry 2
 *    6   Section Extension Entry 3
 *        ....
 *    N   Section Header
 *    N+1 Section Entry
 *    N+2 Section Extension Entry 1
 *    N+3 Section Extension Entry 2
 *    N+4 Section Extension Entry 3
 *        ....
 */

#define  BISO_ELTORITO_ENTRY_LEN    32

#pragma pack(1)

/* 检验表项, 必须是第一条 */
typedef struct tagBISO_TORITO_VALIDATION_ENTRY
{
    UCHAR ucHeaderID;  /* Must be 01 */

    /* 
     * PlatID: CPU平台架构
     * 0x00: x86
     * 0x01: PowerPC
     * 0x02: Mac
     * 0xEF: EFI System Partition
     */
    UCHAR ucPlatID;

    UINT16 usResv;

    /* ID,一般用来保存CD-ROM的制造商信息 */
    CHAR szID[24];

    /* 
     * 校验补充字段, 注意[1]
     * 这个字段用来保证整个Validation Entry的数据
     * 按照WORD(双字节)累加起来为0(截取之后) 
     */
    UINT16 usCheckSum;

    /* 魔数字,检验使用,值必须为0x55和0xAA */
    UCHAR ucData55;
    UCHAR ucDataAA;
}BISO_TORITO_VALIDATION_ENTRY_S;

/* 默认初始化表项(BIOS里面的 INT 13) */
typedef struct tagBISO_TORITO_INITIAL_ENTRY
{
    /* BOOTID: 0x88:Bootable, 00:Not Bootable */
    UCHAR ucBootId;

    /* 
     * ucBootMedia:
     * Bit0 - Bit3的值:
     *  0: No Emulation
     *  1: 1.2 meg diskette
     *  2: 1.44 meg diskette
     *  3: 2.88 meg diskette
     *  4: Hard Disk(drive 80)
     *  5-F:保留
     * Bit4 - Bit7:保留
     */
    UCHAR ucBootMedia;

    /* 启动段,只对x86构架有效,为0默认使用7C0, 注意[1] */
    UINT16 usLoadSegment;

    /* 是Boot Image里面Partition Table的第5个字节(System Type) */
    UCHAR ucSystemType;

    UCHAR ucResv;

    /* 启动时每次往内存读多长, 注意[1] */
    UINT16 usSectorCount;

    /* 启动文件所在的起始逻辑块编号,例如isolinux.bin文件的位置, 注意[1] */
    UINT32 uiLoadRBA;

    UCHAR aucResv[20];
}BISO_TORITO_INITIAL_ENTRY_S;

/*
 * Section Header, 补充一系列可启动的Entry(比如UEFI启动)
 * 如果默认的Initial/Default Entry不满足BIOS需求
 * BIOS可以继续往下找,根据Section Header里面的ID
 * 以及Section Entry里面的Criteria信息决定是否从
 * 该条Entry启动
 *
 */
typedef struct tagBISO_TORITO_SECHDR_ENTRY
{
    /* ucFlag: 0x90:表示后面还有Header, 0x91:表示最后一个Header */
    UCHAR ucFlag;

    /* 
     * PlatID: CPU平台架构
     * 0x00: x86
     * 0x01: PowerPC
     * 0x02: Mac
     * 0xEF: EFI System Partition
     */
    UCHAR ucPlatID;

    /* 跟在这个头的后面有多少个Section Entry */
    UINT16 usSecEntryNum;

    /* ID信息 */
    CHAR szId[28];
}BISO_TORITO_SECHDR_ENTRY_S;

/* Section Entry */
typedef struct tagBISO_TORITO_SECTION_ENTRY
{
    /* BOOTID: 88:Bootable, 00:Not Bootable */
    UCHAR ucBootId;
    
    /* 
     * ucBootMedia:
     * Bit0 - Bit3的值:
     *  0: No Emulation
     *  1: 1.2 meg diskette
     *  2: 1.44 meg diskette
     *  3: 2.88 meg diskette
     *  4: Hard Disk(drive 80)
     *  5-F:保留
     * Bit4:保留
     * Bit5:Continuation Entry Follows
     * Bit6:Image contains an ATAPI driver
     * Bit7:Image contains SCSI driver
     */
    UCHAR ucFlag;

    /* 启动段,只对x86构架有效,为0默认使用7C0, 注意[1] */
    UINT16 usLoadSegment;

    /* 是Boot Image里面Partition Table的第5个字节(System Type) */
    UCHAR ucSystemType;

    UCHAR ucResv;

    /* 启动时每次往内存读多长, 注意[1] */
    UINT16 usSectorCount;

    /* 启动文件所在的起始逻辑块编号,例如isolinux.bin文件的位置, 注意[1] */
    UINT32 uiLoadRBA;

    /* 
     * 它的值描述了后面的aucCriteria的格式
     * 0: 没有
     * 1: Language and Version Information (IBM)
     * 2-FF - Reserved
     */
    UCHAR ucCriteriaType;

    /* Criteria信息,如果这19个字节不够用,可以使用Section Extension Entry里的 */
    UCHAR aucCriteria[19];
}BISO_TORITO_SECTION_ENTRY_S;

/* 扩展Section Entry */
typedef struct tagBISO_TORITO_SECEXT_ENTRY
{
    /* ucExtId: 必须为44 */
    UCHAR ucExtId;

    /* 
     * ucFlag: 只有Bit5有用
     * Bit5: 1表示后面还有Extension Record  0表示最后一个
     */
    UCHAR ucFlag;

    /* Criteria信息 */
    UCHAR aucCriteria[39];
}BISO_TORITO_SECEXT_ENTRY_S;

#pragma pack()

/*
 * 当前缓冲区指针位置向前1条Entry 
 * 如果已经超过了2048字节,则继续从文件中读
 */
#define BISO_ELTORITO_ENTRY_STEP(pstSection, pstFile, aucBuf, stMBuf) \
{\
    UINT _uiReadLen;\
    pstSection++;\
    if ((UCHAR *)pstSection >= aucBuf + BISO_SECTOR_SIZE)\
    {\
        (VOID)BISO_MBUF_Append(&stMBuf, BISO_SECTOR_SIZE, aucBuf);\
        _uiReadLen = (UINT)BISO_PLAT_ReadFile(pstFile, 1, BISO_SECTOR_SIZE, aucBuf);\
        if (_uiReadLen != BISO_SECTOR_SIZE)\
        {\
            BISO_DIAG("Read Len %u, sector len %u.", _uiReadLen, BISO_SECTOR_SIZE);\
            BISO_MBUF_Free(&stMBuf);\
            return BISO_ERR_READ_FILE;\
        }\
        pstSection = (BISO_TORITO_SECTION_ENTRY_S *)aucBuf;\
    }\
}

ULONG BISO_ELTORITO_ReadBootInfo(IN BISO_FILE_S *pstFile, OUT BISO_PARSER_S *pstParser);
VOID BISO_ELTORITO_Dump(IN CONST BISO_PARSER_S *pstParser);
UINT BISO_ELTORITO_GetBootEntryNum(IN CONST BISO_PARSER_S *pstParser);

#endif /* __BISO_ELTORITO_H__ */