rev |
line source |
pascal@20626
|
1 --- linux-3.16.53/drivers/firmware/efi/libstub/efi-stub-helper.c
|
pascal@20626
|
2 +++ linux-3.16.53/drivers/firmware/efi/libstub/efi-stub-helper.c
|
pascal@20626
|
3 @@ -341,6 +341,79 @@
|
pascal@20626
|
4 }
|
pascal@20626
|
5
|
pascal@20626
|
6 /*
|
pascal@20626
|
7 + *
|
pascal@20626
|
8 + */
|
pascal@20626
|
9 +static efi_status_t get_file_size(efi_system_table_t *sys_table_arg,
|
pascal@20626
|
10 + efi_loaded_image_t *image,
|
pascal@20626
|
11 + efi_char16_t *filename_16,
|
pascal@20626
|
12 + struct file_info *file)
|
pascal@20626
|
13 +{
|
pascal@20626
|
14 + efi_status_t status;
|
pascal@20626
|
15 + efi_file_handle_t *fh = NULL;
|
pascal@20626
|
16 +#ifdef CONFIG_X86_64
|
pascal@20626
|
17 + efi_char16_t *p, c;
|
pascal@20626
|
18 +#endif
|
pascal@20626
|
19 +
|
pascal@20626
|
20 + /* Only open the volume once. */
|
pascal@20626
|
21 + if (!fh) {
|
pascal@20626
|
22 + status = efi_open_volume(sys_table_arg, image,
|
pascal@20626
|
23 + (void **)&fh);
|
pascal@20626
|
24 + if (status != EFI_SUCCESS)
|
pascal@20626
|
25 + return status;
|
pascal@20626
|
26 + }
|
pascal@20626
|
27 +#ifdef CONFIG_X86_64
|
pascal@20626
|
28 + for (p = filename_16; *p != '\0'; p++);
|
pascal@20626
|
29 + c = p[-2];
|
pascal@20626
|
30 + file->size = EFI_FILE_SIZE_MUTE;
|
pascal@20626
|
31 + while (1) {
|
pascal@20626
|
32 +#endif
|
pascal@20626
|
33 + status = efi_file_size(sys_table_arg, fh, filename_16,
|
pascal@20626
|
34 + (void **)&file->handle, &file->size);
|
pascal@20626
|
35 +#ifdef CONFIG_X86_64
|
pascal@20626
|
36 + if (status != EFI_SUCCESS && p[-2] != '\0') {
|
pascal@20626
|
37 + p[-2] = '\0';
|
pascal@20626
|
38 + file->size++;
|
pascal@20626
|
39 + continue;
|
pascal@20626
|
40 + }
|
pascal@20626
|
41 + break;
|
pascal@20626
|
42 + }
|
pascal@20626
|
43 + p[-2] = c;
|
pascal@20626
|
44 +#endif
|
pascal@20626
|
45 + return status;
|
pascal@20626
|
46 +}
|
pascal@20626
|
47 +
|
pascal@20626
|
48 +/*
|
pascal@20626
|
49 + *
|
pascal@20626
|
50 + */
|
pascal@20626
|
51 +static efi_status_t read_efi_file(efi_system_table_t *sys_table_arg,
|
pascal@20626
|
52 + struct file_info *file,
|
pascal@20626
|
53 + unsigned long addr,
|
pascal@20626
|
54 + unsigned long size)
|
pascal@20626
|
55 +{
|
pascal@20626
|
56 + efi_status_t status;
|
pascal@20626
|
57 +
|
pascal@20626
|
58 + while (size) {
|
pascal@20626
|
59 + unsigned long chunksize;
|
pascal@20626
|
60 + if (size > __chunk_size)
|
pascal@20626
|
61 + chunksize = __chunk_size;
|
pascal@20626
|
62 + else
|
pascal@20626
|
63 + chunksize = size;
|
pascal@20626
|
64 +
|
pascal@20626
|
65 + status = efi_file_read(file->handle,
|
pascal@20626
|
66 + &chunksize,
|
pascal@20626
|
67 + (void *)addr);
|
pascal@20626
|
68 + if (status != EFI_SUCCESS) {
|
pascal@20626
|
69 + pr_efi_err(sys_table_arg, "Failed to read file\n");
|
pascal@20626
|
70 + break;
|
pascal@20626
|
71 + }
|
pascal@20626
|
72 + addr += chunksize;
|
pascal@20626
|
73 + size -= chunksize;
|
pascal@20626
|
74 + }
|
pascal@20626
|
75 + efi_file_close(file->handle);
|
pascal@20626
|
76 + return status;
|
pascal@20626
|
77 +}
|
pascal@20626
|
78 +
|
pascal@20626
|
79 +/*
|
pascal@20626
|
80 * Check the cmdline for a LILO-style file= arguments.
|
pascal@20626
|
81 *
|
pascal@20626
|
82 * We only support loading a file from the same filesystem as
|
pascal@20626
|
83 @@ -434,18 +507,14 @@
|
pascal@20626
|
84 }
|
pascal@20626
|
85 }
|
pascal@20626
|
86
|
pascal@20626
|
87 +#ifdef CONFIG_X86_64
|
pascal@20626
|
88 + *p++ = '6';
|
pascal@20626
|
89 + *p++ = '4';
|
pascal@20626
|
90 +#endif
|
pascal@20626
|
91 *p = '\0';
|
pascal@20626
|
92
|
pascal@20626
|
93 - /* Only open the volume once. */
|
pascal@20626
|
94 - if (!i) {
|
pascal@20626
|
95 - status = efi_open_volume(sys_table_arg, image,
|
pascal@20626
|
96 - (void **)&fh);
|
pascal@20626
|
97 - if (status != EFI_SUCCESS)
|
pascal@20626
|
98 - goto free_files;
|
pascal@20626
|
99 - }
|
pascal@20626
|
100 -
|
pascal@20626
|
101 - status = efi_file_size(sys_table_arg, fh, filename_16,
|
pascal@20626
|
102 - (void **)&file->handle, &file->size);
|
pascal@20626
|
103 + status = get_file_size(sys_table_arg,image,filename_16,file);
|
pascal@20626
|
104 +
|
pascal@20626
|
105 if (status != EFI_SUCCESS)
|
pascal@20626
|
106 goto close_handles;
|
pascal@20626
|
107
|
pascal@20626
|
108 @@ -476,28 +545,11 @@
|
pascal@20626
|
109
|
pascal@20626
|
110 addr = file_addr;
|
pascal@20626
|
111 for (j = 0; j < nr_files; j++) {
|
pascal@20626
|
112 - unsigned long size;
|
pascal@20626
|
113 -
|
pascal@20626
|
114 - size = files[j].size;
|
pascal@20626
|
115 - while (size) {
|
pascal@20626
|
116 - unsigned long chunksize;
|
pascal@20626
|
117 - if (size > __chunk_size)
|
pascal@20626
|
118 - chunksize = __chunk_size;
|
pascal@20626
|
119 - else
|
pascal@20626
|
120 - chunksize = size;
|
pascal@20626
|
121 -
|
pascal@20626
|
122 - status = efi_file_read(files[j].handle,
|
pascal@20626
|
123 - &chunksize,
|
pascal@20626
|
124 - (void *)addr);
|
pascal@20626
|
125 - if (status != EFI_SUCCESS) {
|
pascal@20626
|
126 - pr_efi_err(sys_table_arg, "Failed to read file\n");
|
pascal@20626
|
127 - goto free_file_total;
|
pascal@20626
|
128 - }
|
pascal@20626
|
129 - addr += chunksize;
|
pascal@20626
|
130 - size -= chunksize;
|
pascal@20626
|
131 - }
|
pascal@20626
|
132 -
|
pascal@20626
|
133 - efi_file_close(files[j].handle);
|
pascal@20626
|
134 + status = read_efi_file(sys_table_arg, &files[j], addr, files[j].size);
|
pascal@20626
|
135 + if (status != EFI_SUCCESS)
|
pascal@20626
|
136 + goto free_file_total;
|
pascal@20626
|
137 + addr += files[j].size + 3;
|
pascal@20626
|
138 + addr &= 0xFFFFFFFCUL;
|
pascal@20626
|
139 }
|
pascal@20626
|
140
|
pascal@20626
|
141 }
|
pascal@20626
|
142 @@ -669,6 +721,30 @@
|
pascal@20626
|
143 }
|
pascal@20626
|
144
|
pascal@20626
|
145 if (!options_chars) {
|
pascal@20626
|
146 + /* No command line options, look for linux.cmdline */
|
pascal@20626
|
147 +#ifdef CONFIG_X86_64
|
pascal@20626
|
148 +#define cmdline_name L"EFI\\BOOT\\linux.cmdline64"
|
pascal@20626
|
149 +#else
|
pascal@20626
|
150 +#define cmdline_name L"EFI\\BOOT\\linux.cmdline"
|
pascal@20626
|
151 +#endif
|
pascal@20626
|
152 + struct file_info file;
|
pascal@20626
|
153 + efi_char16_t filename_16[sizeof(cmdline_name)];
|
pascal@20626
|
154 +
|
pascal@20626
|
155 + memcpy((void *)filename_16, (void *)cmdline_name, sizeof(cmdline_name));
|
pascal@20626
|
156 + if (get_file_size(sys_table_arg, image, filename_16, &file) != EFI_SUCCESS)
|
pascal@20626
|
157 + goto no_cmdline_file;
|
pascal@20626
|
158 +
|
pascal@20626
|
159 + options_bytes = file.size+1;
|
pascal@20626
|
160 + if (efi_low_alloc(sys_table_arg, options_bytes, 0, &cmdline_addr) != EFI_SUCCESS)
|
pascal@20626
|
161 + goto no_cmdline_file;
|
pascal@20626
|
162 +
|
pascal@20626
|
163 + *((u8 *)cmdline_addr + file.size) = '\0';
|
pascal@20626
|
164 + if (read_efi_file(sys_table_arg, &file, cmdline_addr, file.size) == EFI_SUCCESS)
|
pascal@20626
|
165 + goto return_cmdline;
|
pascal@20626
|
166 + }
|
pascal@20626
|
167 + no_cmdline_file:
|
pascal@20626
|
168 +
|
pascal@20626
|
169 + if (!options_chars) {
|
pascal@20626
|
170 /* No command line options, so return empty string*/
|
pascal@20626
|
171 options = &zero;
|
pascal@20626
|
172 }
|
pascal@20626
|
173 @@ -685,6 +761,7 @@
|
pascal@20626
|
174 s1 = efi_utf16_to_utf8(s1, s2, options_chars);
|
pascal@20626
|
175 *s1 = '\0';
|
pascal@20626
|
176
|
pascal@20626
|
177 +return_cmdline:
|
pascal@20626
|
178 *cmd_line_len = options_bytes;
|
pascal@20626
|
179 return (char *)cmdline_addr;
|
pascal@20626
|
180 }
|
pascal@20626
|
181 --- linux-3.16.53/arch/x86/boot/compressed/eboot.c
|
pascal@20626
|
182 +++ linux-3.16.53/arch/x86/boot/compressed/eboot.c
|
pascal@20626
|
183 @@ -50,6 +50,7 @@
|
pascal@20626
|
184
|
pascal@20626
|
185 void efi_char16_printk(efi_system_table_t *, efi_char16_t *);
|
pascal@20626
|
186
|
pascal@20626
|
187 +#define EFI_FILE_SIZE_MUTE 0x4554554d20525245LL
|
pascal@20626
|
188 static efi_status_t
|
pascal@20626
|
189 __file_size32(void *__fh, efi_char16_t *filename_16,
|
pascal@20626
|
190 void **handle, u64 *file_sz)
|
pascal@20626
|
191 @@ -63,9 +64,11 @@
|
pascal@20626
|
192 status = efi_early->call((unsigned long)fh->open, fh, &h, filename_16,
|
pascal@20626
|
193 EFI_FILE_MODE_READ, (u64)0);
|
pascal@20626
|
194 if (status != EFI_SUCCESS) {
|
pascal@20626
|
195 - efi_printk(sys_table, "Failed to open file: ");
|
pascal@20626
|
196 - efi_char16_printk(sys_table, filename_16);
|
pascal@20626
|
197 - efi_printk(sys_table, "\n");
|
pascal@20626
|
198 + if (*file_sz != EFI_FILE_SIZE_MUTE) {
|
pascal@20626
|
199 + efi_printk(sys_table, "Failed to open file: ");
|
pascal@20626
|
200 + efi_char16_printk(sys_table, filename_16);
|
pascal@20626
|
201 + efi_printk(sys_table, "\n");
|
pascal@20626
|
202 + }
|
pascal@20626
|
203 return status;
|
pascal@20626
|
204 }
|
pascal@20626
|
205
|
pascal@20626
|
206 @@ -116,9 +119,11 @@
|
pascal@20626
|
207 status = efi_early->call((unsigned long)fh->open, fh, &h, filename_16,
|
pascal@20626
|
208 EFI_FILE_MODE_READ, (u64)0);
|
pascal@20626
|
209 if (status != EFI_SUCCESS) {
|
pascal@20626
|
210 - efi_printk(sys_table, "Failed to open file: ");
|
pascal@20626
|
211 - efi_char16_printk(sys_table, filename_16);
|
pascal@20626
|
212 - efi_printk(sys_table, "\n");
|
pascal@20626
|
213 + if (*file_sz != EFI_FILE_SIZE_MUTE) {
|
pascal@20626
|
214 + efi_printk(sys_table, "Failed to open file: ");
|
pascal@20626
|
215 + efi_char16_printk(sys_table, filename_16);
|
pascal@20626
|
216 + efi_printk(sys_table, "\n");
|
pascal@20626
|
217 + }
|
pascal@20626
|
218 return status;
|
pascal@20626
|
219 }
|
pascal@20626
|
220
|