2
* s390-tools/zipl/src/boot.c
3
* Functions to handle the boot loader data.
5
* Copyright (C) 2001-2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
7
* Author(s): Carsten Otte <cotte@de.ibm.com>
8
* Peter Oberparleiter <Peter.Oberparleiter@de.ibm.com>
22
/* Include boot data */
23
#include "../boot/data.c"
25
#define STAGE2_MAX_SIZE 4096
28
/* Check sizes of internal objects. Return 0 if everything is correct,
29
* non-zero otherwise. */
33
if (sizeof(boot_data_fba0) !=
34
sizeof(struct boot_fba_stage0)) {
35
error_reason("Size mismatch of stage 0 loader for disks with "
39
if (sizeof(boot_data_eckd0) !=
40
sizeof(struct boot_eckd_stage0)) {
41
error_reason("Size mismatch of stage 0 loader for disks with "
45
if (sizeof(boot_data_eckd1a) !=
46
sizeof(struct boot_eckd_classic_stage1)) {
47
error_reason("Size mismatch of stage 1 loader for disks with "
48
"ECKD classic layout");
51
if (sizeof(boot_data_eckd1b) !=
52
sizeof(struct boot_eckd_compatible_stage1)) {
53
error_reason("Size mismatch of stage 1 loader for disks with "
54
"ECKD compatible layout");
61
/* Create a stage 3 loader in memory.
62
* Upon success, return 0 and set BUFFER to point to the data buffer and set
63
* BYTECOUNT to contain the loader size in bytes. Return non-zero otherwise. */
65
boot_get_stage3(void** buffer, size_t* bytecount, address_t parm_addr,
66
address_t initrd_addr, size_t initrd_len, address_t image_addr,
69
struct boot_stage3_params params;
72
if (image_addr != (image_addr & PSW_ADDRESS_MASK)) {
73
error_reason("Kernel image load address to high (31 bit "
78
data = misc_malloc(sizeof(boot_data_stage3));
81
/* Prepare params section */
82
params.parm_addr = (uint64_t) parm_addr;
83
params.initrd_addr = (uint64_t) initrd_addr;
84
params.initrd_len = (uint64_t) initrd_len;
85
params.load_psw = (uint64_t) (image_addr | PSW_LOAD);
86
params.extra_parm = (uint64_t) extra_parm;
87
/* Initialize buffer */
88
memcpy(data, boot_data_stage3, sizeof(boot_data_stage3));
89
memcpy(data, ¶ms, sizeof(struct boot_stage3_params));
91
*bytecount = sizeof(boot_data_stage3);
96
#define FBA_FLAG_CC 0x0000000040000000LL
99
boot_init_fba_stage0(struct boot_fba_stage0* stage0,
100
disk_blockptr_t* program_table,
101
disk_blockptr_t* stage2_list, blocknum_t stage2_count,
102
struct disk_info* info)
106
/* Initialize stage 0 data */
107
memcpy(stage0, boot_data_fba0, sizeof(struct boot_fba_stage0));
108
/* Fill in blocklist for stage 2 loader */
109
if (stage2_count > 8) {
110
error_reason("Not enough room for FBA stage 2 loader "
111
"(try larger block size)");
114
for (i=0; i < stage2_count; i++) {
115
stage0->locdata[i].blocknr =
116
(uint32_t) stage2_list[i].linear.block;
118
/* Terminate CCW chain */
119
stage0->locread[i - 1].read &= ~FBA_FLAG_CC;
120
/* Store program table pointer in stage 0 loader */
121
bootmap_store_blockptr(&stage0->param1, program_table, info);
127
boot_init_eckd_classic_stage0(struct boot_eckd_stage0* stage0)
129
memcpy(stage0, boot_data_eckd0, sizeof(struct boot_eckd_stage0));
130
/* Fill in size of stage 1 loader */
131
stage0->read.count = sizeof(struct boot_eckd_classic_stage1);
136
boot_init_eckd_compatible_stage0(struct boot_eckd_stage0* stage0)
138
memcpy(stage0, boot_data_eckd0, sizeof(struct boot_eckd_stage0));
139
/* Fill in size of stage 1 loader */
140
stage0->read.count = sizeof(struct boot_eckd_compatible_stage1);
144
#define ECKD_CCW_FLAG_CC 0x40
145
#define ECKD_CCW_FLAG_SLI 0x20
148
boot_init_eckd_classic_stage1(struct boot_eckd_classic_stage1* stage1,
149
disk_blockptr_t* stage2_list, blocknum_t stage2_count,
150
struct disk_info* info)
154
memcpy(stage1, boot_data_eckd1a,
155
sizeof(struct boot_eckd_classic_stage1));
156
/* Fill in blocklist for stage 2 loader */
157
if (stage2_count > 8) {
158
error_reason("Not enough room for ECKD stage 2 loader "
159
"(try larger block size)");
162
for (i=0; i < stage2_count; i++) {
163
stage1->ssrt[i].read.count = stage2_list[i].chs.size;
164
stage1->seek[i].cyl = stage2_list[i].chs.cyl;
165
stage1->seek[i].head = stage2_list[i].chs.head;
166
stage1->seek[i].sec = stage2_list[i].chs.sec;
167
stage1->ssrt[i].read.address_lo = ZIPL_STAGE2_LOAD_ADDRESS +
168
i * stage2_list[i].chs.size;
169
stage1->ssrt[i].read.flags = ECKD_CCW_FLAG_CC |
172
/* Terminate CCW chain */
173
stage1->ssrt[i - 1].read.flags &= ~ECKD_CCW_FLAG_CC;
179
boot_init_eckd_classic_dump_stage1(struct boot_eckd_classic_stage1* stage1,
180
struct disk_info* info)
185
memcpy(stage1, boot_data_eckd1a,
186
sizeof(struct boot_eckd_classic_stage1));
187
blocks = (sizeof(boot_data_eckd2dump) +
188
info->phy_block_size - 1) / info->phy_block_size;
190
error_reason("Not enough room for ECKD stage 2 dump record "
191
"(try larger block size)");
194
/* Fill in block list of stage 2 dump record */
195
for (i=0; i < blocks; i++) {
196
stage1->ssrt[i].read.count = info->phy_block_size;
197
stage1->ssrt[i].read.address_lo = ZIPL_STAGE2_LOAD_ADDRESS +
198
i * info->phy_block_size;
199
stage1->seek[i].cyl =
200
disk_cyl_from_blocknum(i + info->geo.start, info);
201
stage1->seek[i].head =
202
disk_head_from_blocknum(i + info->geo.start, info);
203
stage1->seek[i].sec =
204
disk_sec_from_blocknum(i + info->geo.start, info);
206
/* Terminate CCW chain */
207
stage1->ssrt[i - 1].read.flags &= ~ECKD_CCW_FLAG_CC;
213
boot_init_eckd_compatible_stage1(struct boot_eckd_compatible_stage1* stage1,
214
struct disk_info* info)
219
memcpy(stage1, boot_data_eckd1b,
220
sizeof(struct boot_eckd_compatible_stage1));
221
/* Fill in blocklist for stage 2 loader */
222
blocks = (STAGE2_MAX_SIZE + info->phy_block_size - 1) /
223
info->phy_block_size;
225
error_reason("Not enough room for ECKD stage 2 loader "
226
"(try larger block size)");
229
for (i=0; i < blocks; i++) {
230
stage1->read[i].count = info->phy_block_size;
231
stage1->read[i].address_lo = ZIPL_STAGE2_LOAD_ADDRESS +
232
i * info->phy_block_size;
234
/* Terminate CCW chain */
235
stage1->read[i - 1].flags &= ~ECKD_CCW_FLAG_CC;
241
boot_get_tape_ipl(void** data, size_t* size, address_t parm_addr,
242
address_t initrd_addr, address_t image_addr)
244
struct boot_tape_ipl_params params;
247
if (image_addr != (image_addr & PSW_ADDRESS_MASK)) {
248
error_reason("Kernel image load address to high (31 bit "
252
buffer = misc_malloc(sizeof(boot_data_tape0));
255
/* Prepare params section */
256
params.parm_addr = (uint64_t) parm_addr;
257
params.initrd_addr = (uint64_t) initrd_addr;
258
params.load_psw = (uint64_t) (image_addr | PSW_LOAD);
259
/* Initialize buffer */
260
memcpy(buffer, boot_data_tape0, sizeof(boot_data_tape0));
261
memcpy(VOID_ADD(buffer, BOOT_TAPE_IPL_PARAMS_OFFSET), ¶ms,
262
sizeof(struct boot_tape_ipl_params));
264
*size = sizeof(boot_data_tape0);
270
boot_init_eckd_compatible_dump_stage1(
271
struct boot_eckd_compatible_stage1* stage1,
272
struct disk_info* info)
277
memcpy(stage1, boot_data_eckd1b,
278
sizeof(struct boot_eckd_compatible_stage1));
279
blocks = (sizeof(boot_data_eckd2dump) +
280
info->phy_block_size - 1) / info->phy_block_size;
282
error_reason("Not enough room for ECKD stage 2 dump record "
283
"(try larger block size)");
286
/* Fill in block list of stage 2 dump record */
287
for (i = 0; i < blocks; i++) {
288
stage1->read[i].count = info->phy_block_size;
289
stage1->read[i].address_lo = ZIPL_STAGE2_LOAD_ADDRESS +
290
i * info->phy_block_size;
292
/* Terminate CCW chain */
293
stage1->read[i - 1].flags &= ~ECKD_CCW_FLAG_CC;
298
/* ASCII to EBCDIC conversion table. */
299
unsigned char ascebc[256] =
301
0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F,
302
0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
303
0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26,
304
0x18, 0x19, 0x3F, 0x27, 0x22, 0x1D, 0x1E, 0x1F,
305
0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D,
306
0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
307
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
308
0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
309
0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
310
0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
311
0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6,
312
0xE7, 0xE8, 0xE9, 0xBA, 0xE0, 0xBB, 0xB0, 0x6D,
313
0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
314
0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
315
0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
316
0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07,
317
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
318
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
319
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
320
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
321
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
322
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
323
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
324
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
325
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
326
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
327
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
328
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
329
0x3F, 0x59, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
330
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
331
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
332
0x90, 0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x3F, 0xFF
335
static void ascii_to_ebcdic(unsigned char* from, unsigned char* to)
337
for (;from != to; from++)
338
*from = ascebc[*from];
343
store_stage2_menu(void* data, size_t size, struct job_data* job)
345
struct boot_stage2_params* params;
355
memset(data, 0, size);
356
if (job->id == job_menu) {
358
for (i=0; i < job->data.menu.num; i++)
359
if (job->data.menu.entry[i].pos ==
360
job->data.menu.default_pos)
361
name = job->data.menu.entry[i].name;
362
flag = (job->data.menu.prompt != 0);
363
timeout = job->data.menu.timeout;
366
printf("Preparing boot menu\n");
367
printf(" Interactive prompt......: %s\n",
368
job->data.menu.prompt ? "enabled" : "disabled");
369
if (job->data.menu.timeout == 0)
370
printf(" Menu timeout............: "
373
printf(" Menu timeout............: %d "
374
"seconds\n", job->data.menu.timeout);
375
printf(" Default configuration...: '%s'\n", name);
383
len = sizeof(struct boot_stage2_params);
385
error_reason("Not enough room for menu data");
388
params = (struct boot_stage2_params *) data;
390
params->timeout = timeout;
391
current = (char *) (params + 1);
394
len = snprintf(current, size, "zIPL v%s interactive boot menu\n ",
397
error_reason("Not enough room for menu data");
400
params->banner = (uint16_t) ((unsigned long) current -
401
(unsigned long) data);
404
/* Default config text */
406
len = snprintf(current, size, " 0. default (%s)", name) + 1;
408
len = snprintf(current, size, " 0. default") + 1;
410
error_reason("Not enough room for menu data");
413
params->config[0] = (uint16_t) ((unsigned long) current -
414
(unsigned long) data);
417
/* Skip rest if job is not an actual menu */
418
if (job->id != job_menu) {
419
/* Convert to EBCDIC */
420
ascii_to_ebcdic((unsigned char *) (params + 1),
421
(unsigned char *) current);
427
for (i = 0; i < job->data.menu.num; i++) {
428
len = strlen(job->data.menu.entry[i].name);
433
maxlen += 5; /* '%2d. \0' */
434
if (textlen > size) {
435
/* Menu text won't fit, need to truncate */
436
maxlen = size / job->data.menu.num;
438
error_reason("Not enough room for menu data (try "
439
"shorter config names)");
442
fprintf(stderr, "Warning: Menu text too large, truncating "
443
"names at %d characters!\n", maxlen - 5);
445
for (i = 0; i < job->data.menu.num; i++) {
446
len = snprintf(current, maxlen, "%2d. %s",
447
job->data.menu.entry[i].pos,
448
job->data.menu.entry[i].name) + 1;
451
params->config[job->data.menu.entry[i].pos] = (uint16_t)
452
((unsigned long) current - (unsigned long) data);
455
/* Convert to EBCDIC */
456
ascii_to_ebcdic((unsigned char *) (params + 1),
457
(unsigned char *) current);
464
boot_get_fba_stage2(void** data, size_t* size, struct job_data* job)
469
buffer = misc_malloc(STAGE2_MAX_SIZE);
472
memcpy(buffer, boot_data_fba2, sizeof(boot_data_fba2));
473
rc = store_stage2_menu(VOID_ADD(buffer, sizeof(boot_data_fba2)),
474
STAGE2_MAX_SIZE - sizeof(boot_data_fba2),
481
*size = STAGE2_MAX_SIZE;
487
boot_get_eckd_stage2(void** data, size_t* size, struct job_data* job)
492
buffer = misc_malloc(STAGE2_MAX_SIZE);
495
memcpy(buffer, boot_data_eckd2, sizeof(boot_data_eckd2));
496
rc = store_stage2_menu(VOID_ADD(buffer, sizeof(boot_data_eckd2)),
497
STAGE2_MAX_SIZE - sizeof(boot_data_eckd2),
504
*size = STAGE2_MAX_SIZE;
510
boot_get_tape_dump(void** data, size_t* size, uint64_t mem)
514
buffer = misc_malloc(sizeof(boot_data_tapedump));
517
memcpy(buffer, boot_data_tapedump, sizeof(boot_data_tapedump));
518
/* Write mem size to end of dump record */
519
memcpy(VOID_ADD(buffer, sizeof(boot_data_tapedump) - sizeof(mem)), &mem,
522
*size = sizeof(boot_data_tapedump);
528
boot_get_eckd_dump_stage2(void** data, size_t* size, uint64_t mem)
532
buffer = misc_malloc(sizeof(boot_data_eckd2dump));
535
memcpy(buffer, boot_data_eckd2dump, sizeof(boot_data_eckd2dump));
536
/* Write mem size to end of dump record */
537
memcpy(VOID_ADD(buffer, sizeof(boot_data_eckd2dump) - sizeof(mem)),
540
*size = sizeof(boot_data_eckd2dump);