1 |
/* pupa-mkimage.c - make a bootable image */ |
/* pupa-mkimage.c - make a bootable image */ |
2 |
/* |
/* |
3 |
* PUPA -- Preliminary Universal Programming Architecture for GRUB |
* PUPA -- Preliminary Universal Programming Architecture for GRUB |
4 |
* Copyright (C) 2002 Yoshinori K. Okuji <okuji@enbug.org> |
* Copyright (C) 2002,2003 Yoshinori K. Okuji <okuji@enbug.org> |
5 |
* |
* |
6 |
* PUPA is free software; you can redistribute it and/or modify |
* PUPA is free software; you can redistribute it and/or modify |
7 |
* it under the terms of the GNU General Public License as published by |
* it under the terms of the GNU General Public License as published by |
35 |
#define _GNU_SOURCE 1 |
#define _GNU_SOURCE 1 |
36 |
#include <getopt.h> |
#include <getopt.h> |
37 |
|
|
38 |
|
#include <lzo1x.h> |
39 |
|
|
40 |
|
static void |
41 |
|
compress_kernel (char *kernel_img, size_t kernel_size, |
42 |
|
char **core_img, size_t *core_size) |
43 |
|
{ |
44 |
|
lzo_uint size; |
45 |
|
char *wrkmem; |
46 |
|
|
47 |
|
pupa_util_info ("kernel_img=%p, kernel_size=0x%x", kernel_img, kernel_size); |
48 |
|
if (kernel_size < PUPA_KERNEL_MACHINE_RAW_SIZE) |
49 |
|
pupa_util_error ("the core image is too small"); |
50 |
|
|
51 |
|
if (lzo_init () != LZO_E_OK) |
52 |
|
pupa_util_error ("cannot initialize LZO"); |
53 |
|
|
54 |
|
*core_img = xmalloc (kernel_size + kernel_size / 64 + 16 + 3); |
55 |
|
wrkmem = xmalloc (LZO1X_999_MEM_COMPRESS); |
56 |
|
|
57 |
|
memcpy (*core_img, kernel_img, PUPA_KERNEL_MACHINE_RAW_SIZE); |
58 |
|
|
59 |
|
pupa_util_info ("compressing the core image"); |
60 |
|
if (lzo1x_999_compress (kernel_img + PUPA_KERNEL_MACHINE_RAW_SIZE, |
61 |
|
kernel_size - PUPA_KERNEL_MACHINE_RAW_SIZE, |
62 |
|
*core_img + PUPA_KERNEL_MACHINE_RAW_SIZE, |
63 |
|
&size, wrkmem) |
64 |
|
!= LZO_E_OK) |
65 |
|
pupa_util_error ("cannot compress the kernel image"); |
66 |
|
|
67 |
|
free (wrkmem); |
68 |
|
|
69 |
|
*core_size = (size_t) size + PUPA_KERNEL_MACHINE_RAW_SIZE; |
70 |
|
} |
71 |
|
|
72 |
static void |
static void |
73 |
generate_image (const char *dir, FILE *out, char *mods[]) |
generate_image (const char *dir, FILE *out, char *mods[]) |
74 |
{ |
{ |
75 |
pupa_addr_t module_addr = 0; |
pupa_addr_t module_addr = 0; |
76 |
char *kernel_img, *boot_img; |
char *kernel_img, *boot_img, *core_img; |
77 |
size_t kernel_size, boot_size, total_module_size; |
size_t kernel_size, boot_size, total_module_size, core_size; |
78 |
char *kernel_path, *boot_path; |
char *kernel_path, *boot_path; |
79 |
unsigned num; |
unsigned num; |
80 |
|
size_t offset; |
81 |
struct pupa_util_path_list *path_list, *p, *next; |
struct pupa_util_path_list *path_list, *p, *next; |
82 |
|
|
83 |
path_list = pupa_util_resolve_dependencies (dir, "moddep.lst", mods); |
path_list = pupa_util_resolve_dependencies (dir, "moddep.lst", mods); |
91 |
+ sizeof (struct pupa_module_header)); |
+ sizeof (struct pupa_module_header)); |
92 |
|
|
93 |
pupa_util_info ("the total module size is 0x%x", total_module_size); |
pupa_util_info ("the total module size is 0x%x", total_module_size); |
94 |
|
|
95 |
|
kernel_img = xmalloc (kernel_size + total_module_size); |
96 |
|
pupa_util_load_image (kernel_path, kernel_img); |
97 |
|
offset = kernel_size; |
98 |
|
for (p = path_list; p; p = p->next) |
99 |
|
{ |
100 |
|
struct pupa_module_header *header; |
101 |
|
size_t mod_size; |
102 |
|
|
103 |
|
mod_size = pupa_util_get_image_size (p->name); |
104 |
|
|
105 |
|
header = (struct pupa_module_header *) (kernel_img + offset); |
106 |
|
header->offset = pupa_cpu_to_le32 (sizeof (*header)); |
107 |
|
header->size = pupa_cpu_to_le32 (mod_size + sizeof (*header)); |
108 |
|
|
109 |
|
pupa_util_load_image (p->name, kernel_img + offset + sizeof (*header)); |
110 |
|
|
111 |
|
offset += sizeof (*header) + mod_size; |
112 |
|
} |
113 |
|
|
114 |
|
compress_kernel (kernel_img, kernel_size + total_module_size, |
115 |
|
&core_img, &core_size); |
116 |
|
|
117 |
|
pupa_util_info ("the core size is 0x%x", core_size); |
118 |
|
|
119 |
num = ((kernel_size + total_module_size + PUPA_DISK_SECTOR_SIZE - 1) |
num = ((core_size + PUPA_DISK_SECTOR_SIZE - 1) >> PUPA_DISK_SECTOR_BITS); |
|
>> PUPA_DISK_SECTOR_BITS); |
|
120 |
if (num > 0xffff) |
if (num > 0xffff) |
121 |
pupa_util_error ("the core image is too big"); |
pupa_util_error ("the core image is too big"); |
122 |
|
|
136 |
free (boot_img); |
free (boot_img); |
137 |
free (boot_path); |
free (boot_path); |
138 |
|
|
|
kernel_img = pupa_util_read_image (kernel_path); |
|
139 |
module_addr = (path_list |
module_addr = (path_list |
140 |
? (PUPA_BOOT_MACHINE_KERNEL_ADDR + PUPA_DISK_SECTOR_SIZE |
? (PUPA_BOOT_MACHINE_KERNEL_ADDR + PUPA_DISK_SECTOR_SIZE |
141 |
+ kernel_size) |
+ kernel_size) |
142 |
: 0); |
: 0); |
143 |
|
|
144 |
pupa_util_info ("the first module address is 0x%x", module_addr); |
pupa_util_info ("the first module address is 0x%x", module_addr); |
145 |
*((pupa_uint32_t *) (kernel_img + PUPA_KERNEL_MACHINE_TOTAL_MODULE_SIZE)) |
*((pupa_uint32_t *) (core_img + PUPA_KERNEL_MACHINE_TOTAL_MODULE_SIZE)) |
146 |
= pupa_cpu_to_le32 (total_module_size); |
= pupa_cpu_to_le32 (total_module_size); |
147 |
*((pupa_uint32_t *) (kernel_img + PUPA_KERNEL_MACHINE_KERNEL_IMAGE_SIZE)) |
*((pupa_uint32_t *) (core_img + PUPA_KERNEL_MACHINE_KERNEL_IMAGE_SIZE)) |
148 |
= pupa_cpu_to_le32 (kernel_size); |
= pupa_cpu_to_le32 (kernel_size); |
149 |
|
*((pupa_uint32_t *) (core_img + PUPA_KERNEL_MACHINE_COMPRESSED_SIZE)) |
150 |
|
= pupa_cpu_to_le32 (core_size - PUPA_KERNEL_MACHINE_RAW_SIZE); |
151 |
|
|
152 |
pupa_util_write_image (kernel_img, kernel_size, out); |
pupa_util_write_image (core_img, core_size, out); |
153 |
free (kernel_img); |
free (kernel_img); |
154 |
|
free (core_img); |
155 |
free (kernel_path); |
free (kernel_path); |
156 |
|
|
157 |
while (path_list) |
while (path_list) |
158 |
{ |
{ |
|
struct pupa_module_header header; |
|
|
size_t mod_size; |
|
|
char *mod_img; |
|
|
|
|
159 |
next = path_list->next; |
next = path_list->next; |
|
|
|
|
mod_size = pupa_util_get_image_size (path_list->name); |
|
|
|
|
|
header.offset = pupa_cpu_to_le32 (sizeof (header)); |
|
|
header.size = pupa_cpu_to_le32 (mod_size + sizeof (header)); |
|
|
|
|
|
pupa_util_info ("offset=0x%x, size=0x%x", header.offset, header.size); |
|
|
pupa_util_write_image ((char *) &header, sizeof (header), out); |
|
|
|
|
|
mod_img = pupa_util_read_image (path_list->name); |
|
|
pupa_util_write_image (mod_img, mod_size, out); |
|
|
free (mod_img); |
|
|
|
|
160 |
free ((void *) path_list->name); |
free ((void *) path_list->name); |
161 |
free (path_list); |
free (path_list); |
162 |
path_list = next; |
path_list = next; |