Blame view
init/initramfs.c
13.9 KB
b24413180 License cleanup: ... |
1 |
// SPDX-License-Identifier: GPL-2.0 |
1da177e4c Linux-2.6.12-rc2 |
2 3 4 5 6 7 8 |
#include <linux/init.h> #include <linux/fs.h> #include <linux/slab.h> #include <linux/types.h> #include <linux/fcntl.h> #include <linux/delay.h> #include <linux/string.h> |
df52092f3 fastboot: remove ... |
9 |
#include <linux/dirent.h> |
1da177e4c Linux-2.6.12-rc2 |
10 |
#include <linux/syscalls.h> |
889d51a10 initramfs: add op... |
11 |
#include <linux/utime.h> |
088655148 initramfs: finish... |
12 |
#include <linux/file.h> |
899ee4afe arm64: use generi... |
13 |
#include <linux/memblock.h> |
b2a74d5f9 initramfs: remove... |
14 |
#include <linux/namei.h> |
8fb9f73e5 init: add an init... |
15 |
#include <linux/init_syscalls.h> |
1da177e4c Linux-2.6.12-rc2 |
16 |
|
bf6419e4d initramfs: switch... |
17 18 |
static ssize_t __init xwrite(struct file *file, const char *p, size_t count, loff_t *pos) |
387474399 initramfs: suppor... |
19 20 21 22 23 |
{ ssize_t out = 0; /* sys_write only can write MAX_RW_COUNT aka 2G-4K bytes at most */ while (count) { |
bf6419e4d initramfs: switch... |
24 |
ssize_t rv = kernel_write(file, p, count, pos); |
387474399 initramfs: suppor... |
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
if (rv < 0) { if (rv == -EINTR || rv == -EAGAIN) continue; return out ? out : rv; } else if (rv == 0) break; p += rv; out += rv; count -= rv; } return out; } |
1da177e4c Linux-2.6.12-rc2 |
40 41 42 43 44 45 |
static __initdata char *message; static void __init error(char *x) { if (!message) message = x; } |
1da177e4c Linux-2.6.12-rc2 |
46 |
/* link hash */ |
6a050da45 [PATCH] initramfs... |
47 |
#define N_ALIGN(len) ((((len) + 1) & ~3) + 2) |
1da177e4c Linux-2.6.12-rc2 |
48 49 |
static __initdata struct hash { int ino, minor, major; |
685dd2d5b init/initramfs.c:... |
50 |
umode_t mode; |
1da177e4c Linux-2.6.12-rc2 |
51 |
struct hash *next; |
6a050da45 [PATCH] initramfs... |
52 |
char name[N_ALIGN(PATH_MAX)]; |
1da177e4c Linux-2.6.12-rc2 |
53 54 55 56 57 58 59 60 |
} *head[32]; static inline int hash(int major, int minor, int ino) { unsigned long tmp = ino + minor + (major << 3); tmp += tmp >> 5; return tmp & 31; } |
2139a7fbf [PATCH] initramfs... |
61 |
static char __init *find_link(int major, int minor, int ino, |
685dd2d5b init/initramfs.c:... |
62 |
umode_t mode, char *name) |
1da177e4c Linux-2.6.12-rc2 |
63 64 65 66 67 68 69 70 71 |
{ struct hash **p, *q; for (p = head + hash(major, minor, ino); *p; p = &(*p)->next) { if ((*p)->ino != ino) continue; if ((*p)->minor != minor) continue; if ((*p)->major != major) continue; |
2139a7fbf [PATCH] initramfs... |
72 73 |
if (((*p)->mode ^ mode) & S_IFMT) continue; |
1da177e4c Linux-2.6.12-rc2 |
74 75 |
return (*p)->name; } |
3265e66b1 directly use kmal... |
76 |
q = kmalloc(sizeof(struct hash), GFP_KERNEL); |
1da177e4c Linux-2.6.12-rc2 |
77 78 |
if (!q) panic("can't allocate link hash entry"); |
1da177e4c Linux-2.6.12-rc2 |
79 |
q->major = major; |
2139a7fbf [PATCH] initramfs... |
80 81 82 |
q->minor = minor; q->ino = ino; q->mode = mode; |
6a050da45 [PATCH] initramfs... |
83 |
strcpy(q->name, name); |
1da177e4c Linux-2.6.12-rc2 |
84 85 86 87 88 89 90 91 92 93 94 95 |
q->next = NULL; *p = q; return NULL; } static void __init free_hash(void) { struct hash **p, *q; for (p = head; p < head + 32; p++) { while (*p) { q = *p; *p = q->next; |
3265e66b1 directly use kmal... |
96 |
kfree(q); |
1da177e4c Linux-2.6.12-rc2 |
97 98 99 |
} } } |
e35c4c64f initramfs: use ti... |
100 |
static long __init do_utime(char *filename, time64_t mtime) |
889d51a10 initramfs: add op... |
101 |
{ |
aaed2dd8a utimes: Make utim... |
102 |
struct timespec64 t[2]; |
889d51a10 initramfs: add op... |
103 104 105 106 107 |
t[0].tv_sec = mtime; t[0].tv_nsec = 0; t[1].tv_sec = mtime; t[1].tv_nsec = 0; |
235e57935 init: add an init... |
108 |
return init_utimes(filename, t); |
889d51a10 initramfs: add op... |
109 110 111 112 113 114 |
} static __initdata LIST_HEAD(dir_list); struct dir_entry { struct list_head list; char *name; |
e35c4c64f initramfs: use ti... |
115 |
time64_t mtime; |
889d51a10 initramfs: add op... |
116 |
}; |
e35c4c64f initramfs: use ti... |
117 |
static void __init dir_add(const char *name, time64_t mtime) |
889d51a10 initramfs: add op... |
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
{ struct dir_entry *de = kmalloc(sizeof(struct dir_entry), GFP_KERNEL); if (!de) panic("can't allocate dir_entry buffer"); INIT_LIST_HEAD(&de->list); de->name = kstrdup(name, GFP_KERNEL); de->mtime = mtime; list_add(&de->list, &dir_list); } static void __init dir_utime(void) { struct dir_entry *de, *tmp; list_for_each_entry_safe(de, tmp, &dir_list, list) { list_del(&de->list); do_utime(de->name, de->mtime); kfree(de->name); kfree(de); } } |
e35c4c64f initramfs: use ti... |
138 |
static __initdata time64_t mtime; |
889d51a10 initramfs: add op... |
139 |
|
1da177e4c Linux-2.6.12-rc2 |
140 141 142 |
/* cpio header parsing */ static __initdata unsigned long ino, major, minor, nlink; |
685dd2d5b init/initramfs.c:... |
143 |
static __initdata umode_t mode; |
1da177e4c Linux-2.6.12-rc2 |
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
static __initdata unsigned long body_len, name_len; static __initdata uid_t uid; static __initdata gid_t gid; static __initdata unsigned rdev; static void __init parse_header(char *s) { unsigned long parsed[12]; char buf[9]; int i; buf[8] = '\0'; for (i = 0, s += 6; i < 12; i++, s += 8) { memcpy(buf, s, 8); parsed[i] = simple_strtoul(buf, NULL, 16); } ino = parsed[0]; mode = parsed[1]; uid = parsed[2]; gid = parsed[3]; nlink = parsed[4]; |
e35c4c64f initramfs: use ti... |
165 |
mtime = parsed[5]; /* breaks in y2106 */ |
1da177e4c Linux-2.6.12-rc2 |
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
body_len = parsed[6]; major = parsed[7]; minor = parsed[8]; rdev = new_encode_dev(MKDEV(parsed[9], parsed[10])); name_len = parsed[11]; } /* FSM */ static __initdata enum state { Start, Collect, GotHeader, SkipIt, GotName, CopyFile, GotSymlink, Reset } state, next_state; static __initdata char *victim; |
c34d85aca init/initramfs.c:... |
187 |
static unsigned long byte_count __initdata; |
1da177e4c Linux-2.6.12-rc2 |
188 |
static __initdata loff_t this_header, next_header; |
b0a5ab931 initramfs: missin... |
189 |
static inline void __init eat(unsigned n) |
1da177e4c Linux-2.6.12-rc2 |
190 191 192 |
{ victim += n; this_header += n; |
c34d85aca init/initramfs.c:... |
193 |
byte_count -= n; |
1da177e4c Linux-2.6.12-rc2 |
194 |
} |
1da177e4c Linux-2.6.12-rc2 |
195 |
static __initdata char *collected; |
d97b07c54 initramfs: suppor... |
196 |
static long remains __initdata; |
1da177e4c Linux-2.6.12-rc2 |
197 198 199 200 |
static __initdata char *collect; static void __init read_into(char *buf, unsigned size, enum state next) { |
c34d85aca init/initramfs.c:... |
201 |
if (byte_count >= size) { |
1da177e4c Linux-2.6.12-rc2 |
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
collected = victim; eat(size); state = next; } else { collect = collected = buf; remains = size; next_state = next; state = Collect; } } static __initdata char *header_buf, *symlink_buf, *name_buf; static int __init do_start(void) { read_into(header_buf, 110, GotHeader); return 0; } static int __init do_collect(void) { |
d97b07c54 initramfs: suppor... |
223 |
unsigned long n = remains; |
c34d85aca init/initramfs.c:... |
224 225 |
if (byte_count < n) n = byte_count; |
1da177e4c Linux-2.6.12-rc2 |
226 227 228 229 230 231 232 233 234 235 236 |
memcpy(collect, victim, n); eat(n); collect += n; if ((remains -= n) != 0) return 1; state = next_state; return 0; } static int __init do_header(void) { |
2e591bbc0 [PATCH] Make init... |
237 238 239 240 |
if (memcmp(collected, "070707", 6)==0) { error("incorrect cpio method used: use -H newc option"); return 1; } |
1da177e4c Linux-2.6.12-rc2 |
241 242 243 244 245 246 247 |
if (memcmp(collected, "070701", 6)) { error("no cpio magic"); return 1; } parse_header(collected); next_header = this_header + N_ALIGN(name_len) + body_len; next_header = (next_header + 3) & ~3; |
1da177e4c Linux-2.6.12-rc2 |
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 |
state = SkipIt; if (name_len <= 0 || name_len > PATH_MAX) return 0; if (S_ISLNK(mode)) { if (body_len > PATH_MAX) return 0; collect = collected = symlink_buf; remains = N_ALIGN(name_len) + body_len; next_state = GotSymlink; state = Collect; return 0; } if (S_ISREG(mode) || !body_len) read_into(name_buf, N_ALIGN(name_len), GotName); return 0; } static int __init do_skip(void) { |
c34d85aca init/initramfs.c:... |
267 268 |
if (this_header + byte_count < next_header) { eat(byte_count); |
1da177e4c Linux-2.6.12-rc2 |
269 270 271 272 273 274 275 276 277 278 |
return 1; } else { eat(next_header - this_header); state = next_state; return 0; } } static int __init do_reset(void) { |
c34d85aca init/initramfs.c:... |
279 |
while (byte_count && *victim == '\0') |
1da177e4c Linux-2.6.12-rc2 |
280 |
eat(1); |
c34d85aca init/initramfs.c:... |
281 |
if (byte_count && (this_header & 3)) |
1da177e4c Linux-2.6.12-rc2 |
282 283 284 |
error("broken padding"); return 1; } |
c34d85aca init/initramfs.c:... |
285 |
static void __init clean_path(char *path, umode_t fmode) |
2139a7fbf [PATCH] initramfs... |
286 |
{ |
046aa1265 initramfs: use vf... |
287 |
struct kstat st; |
2139a7fbf [PATCH] initramfs... |
288 |
|
7b81ce7cd init: fix error c... |
289 |
if (!init_stat(path, &st, AT_SYMLINK_NOFOLLOW) && |
716308a53 init: add an init... |
290 |
(st.mode ^ fmode) & S_IFMT) { |
046aa1265 initramfs: use vf... |
291 |
if (S_ISDIR(st.mode)) |
20cce026c init: add an init... |
292 |
init_rmdir(path); |
2139a7fbf [PATCH] initramfs... |
293 |
else |
8fb9f73e5 init: add an init... |
294 |
init_unlink(path); |
2139a7fbf [PATCH] initramfs... |
295 296 |
} } |
7c0950d45 initramfs: clean ... |
297 298 299 300 301 302 |
static int __init maybe_link(void) { if (nlink >= 2) { char *old = find_link(major, minor, ino, mode, collected); if (old) { clean_path(collected, 0); |
812931d69 init: add an init... |
303 |
return (init_link(old, collected) < 0) ? -1 : 1; |
7c0950d45 initramfs: clean ... |
304 305 306 307 |
} } return 0; } |
bf6419e4d initramfs: switch... |
308 309 |
static __initdata struct file *wfile; static __initdata loff_t wfile_pos; |
1da177e4c Linux-2.6.12-rc2 |
310 311 312 313 314 315 316 317 318 |
static int __init do_name(void) { state = SkipIt; next_state = Reset; if (strcmp(collected, "TRAILER!!!") == 0) { free_hash(); return 0; } |
2139a7fbf [PATCH] initramfs... |
319 |
clean_path(collected, mode); |
1da177e4c Linux-2.6.12-rc2 |
320 |
if (S_ISREG(mode)) { |
2139a7fbf [PATCH] initramfs... |
321 322 323 324 325 |
int ml = maybe_link(); if (ml >= 0) { int openflags = O_WRONLY|O_CREAT; if (ml != 1) openflags |= O_TRUNC; |
bf6419e4d initramfs: switch... |
326 327 328 329 330 331 332 333 334 |
wfile = filp_open(collected, openflags, mode); if (IS_ERR(wfile)) return 0; wfile_pos = 0; vfs_fchown(wfile, uid, gid); vfs_fchmod(wfile, mode); if (body_len) vfs_truncate(&wfile->f_path, body_len); |
bf6419e4d initramfs: switch... |
335 |
state = CopyFile; |
1da177e4c Linux-2.6.12-rc2 |
336 337 |
} } else if (S_ISDIR(mode)) { |
83ff98c3e init: add an init... |
338 |
init_mkdir(collected, mode); |
b873498f9 init: add an init... |
339 |
init_chown(collected, uid, gid, 0); |
1097742ef init: add an init... |
340 |
init_chmod(collected, mode); |
889d51a10 initramfs: add op... |
341 |
dir_add(collected, mtime); |
1da177e4c Linux-2.6.12-rc2 |
342 343 344 |
} else if (S_ISBLK(mode) || S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) { if (maybe_link() == 0) { |
5fee64fcd init: add an init... |
345 |
init_mknod(collected, mode, rdev); |
b873498f9 init: add an init... |
346 |
init_chown(collected, uid, gid, 0); |
1097742ef init: add an init... |
347 |
init_chmod(collected, mode); |
889d51a10 initramfs: add op... |
348 |
do_utime(collected, mtime); |
1da177e4c Linux-2.6.12-rc2 |
349 350 351 352 353 354 355 |
} } return 0; } static int __init do_copy(void) { |
c34d85aca init/initramfs.c:... |
356 |
if (byte_count >= body_len) { |
38b082236 initramfs: use vf... |
357 |
struct timespec64 t[2] = { }; |
bf6419e4d initramfs: switch... |
358 |
if (xwrite(wfile, victim, body_len, &wfile_pos) != body_len) |
9687fd910 initramfs: add wr... |
359 |
error("write error"); |
38b082236 initramfs: use vf... |
360 361 362 363 |
t[0].tv_sec = mtime; t[1].tv_sec = mtime; vfs_utimes(&wfile->f_path, t); |
bf6419e4d initramfs: switch... |
364 |
fput(wfile); |
1da177e4c Linux-2.6.12-rc2 |
365 366 367 368 |
eat(body_len); state = SkipIt; return 0; } else { |
bf6419e4d initramfs: switch... |
369 |
if (xwrite(wfile, victim, byte_count, &wfile_pos) != byte_count) |
9687fd910 initramfs: add wr... |
370 |
error("write error"); |
c34d85aca init/initramfs.c:... |
371 372 |
body_len -= byte_count; eat(byte_count); |
1da177e4c Linux-2.6.12-rc2 |
373 374 375 376 377 378 379 |
return 1; } } static int __init do_symlink(void) { collected[N_ALIGN(name_len) + body_len] = '\0'; |
2139a7fbf [PATCH] initramfs... |
380 |
clean_path(collected, 0); |
cd3acb6a7 init: add an init... |
381 |
init_symlink(collected + N_ALIGN(name_len), collected); |
b873498f9 init: add an init... |
382 |
init_chown(collected, uid, gid, AT_SYMLINK_NOFOLLOW); |
889d51a10 initramfs: add op... |
383 |
do_utime(collected, mtime); |
1da177e4c Linux-2.6.12-rc2 |
384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 |
state = SkipIt; next_state = Reset; return 0; } static __initdata int (*actions[])(void) = { [Start] = do_start, [Collect] = do_collect, [GotHeader] = do_header, [SkipIt] = do_skip, [GotName] = do_name, [CopyFile] = do_copy, [GotSymlink] = do_symlink, [Reset] = do_reset, }; |
d97b07c54 initramfs: suppor... |
399 |
static long __init write_buffer(char *buf, unsigned long len) |
1da177e4c Linux-2.6.12-rc2 |
400 |
{ |
c34d85aca init/initramfs.c:... |
401 |
byte_count = len; |
1da177e4c Linux-2.6.12-rc2 |
402 403 404 405 |
victim = buf; while (!actions[state]()) ; |
c34d85aca init/initramfs.c:... |
406 |
return len - byte_count; |
1da177e4c Linux-2.6.12-rc2 |
407 |
} |
d97b07c54 initramfs: suppor... |
408 |
static long __init flush_buffer(void *bufv, unsigned long len) |
1da177e4c Linux-2.6.12-rc2 |
409 |
{ |
30d65dbfe bzip2/lzma: confi... |
410 |
char *buf = (char *) bufv; |
d97b07c54 initramfs: suppor... |
411 412 |
long written; long origLen = len; |
1da177e4c Linux-2.6.12-rc2 |
413 |
if (message) |
30d65dbfe bzip2/lzma: confi... |
414 |
return -1; |
1da177e4c Linux-2.6.12-rc2 |
415 416 417 418 419 420 421 422 423 424 425 |
while ((written = write_buffer(buf, len)) < len && !message) { char c = buf[written]; if (c == '0') { buf += written; len -= written; state = Start; } else if (c == 0) { buf += written; len -= written; state = Reset; } else |
e5eed351f init/initramfs.c:... |
426 |
error("junk within compressed archive"); |
1da177e4c Linux-2.6.12-rc2 |
427 |
} |
30d65dbfe bzip2/lzma: confi... |
428 |
return origLen; |
1da177e4c Linux-2.6.12-rc2 |
429 |
} |
d97b07c54 initramfs: suppor... |
430 |
static unsigned long my_inptr; /* index of next byte to be processed in inbuf */ |
1da177e4c Linux-2.6.12-rc2 |
431 |
|
889c92d21 bzip2/lzma: centr... |
432 |
#include <linux/decompress/generic.h> |
1da177e4c Linux-2.6.12-rc2 |
433 |
|
d97b07c54 initramfs: suppor... |
434 |
static char * __init unpack_to_rootfs(char *buf, unsigned long len) |
1da177e4c Linux-2.6.12-rc2 |
435 |
{ |
d97b07c54 initramfs: suppor... |
436 |
long written; |
889c92d21 bzip2/lzma: centr... |
437 |
decompress_fn decompress; |
23a22d57a bzip2/lzma: compr... |
438 439 |
const char *compress_name; static __initdata char msg_buf[64]; |
889c92d21 bzip2/lzma: centr... |
440 |
|
3265e66b1 directly use kmal... |
441 442 443 |
header_buf = kmalloc(110, GFP_KERNEL); symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL); name_buf = kmalloc(N_ALIGN(PATH_MAX), GFP_KERNEL); |
30d65dbfe bzip2/lzma: confi... |
444 445 |
if (!header_buf || !symlink_buf || !name_buf) |
1da177e4c Linux-2.6.12-rc2 |
446 |
panic("can't allocate buffers"); |
30d65dbfe bzip2/lzma: confi... |
447 |
|
1da177e4c Linux-2.6.12-rc2 |
448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 |
state = Start; this_header = 0; message = NULL; while (!message && len) { loff_t saved_offset = this_header; if (*buf == '0' && !(this_header & 3)) { state = Start; written = write_buffer(buf, len); buf += written; len -= written; continue; } if (!*buf) { buf++; len--; this_header++; continue; } this_header = 0; |
23a22d57a bzip2/lzma: compr... |
467 |
decompress = decompress_method(buf, len, &compress_name); |
6aa7a29aa initramfs: debug ... |
468 469 |
pr_debug("Detected %s compressed data ", compress_name); |
54291362d initramfs: add mi... |
470 |
if (decompress) { |
d97b07c54 initramfs: suppor... |
471 |
int res = decompress(buf, len, NULL, flush_buffer, NULL, |
889c92d21 bzip2/lzma: centr... |
472 |
&my_inptr, error); |
54291362d initramfs: add mi... |
473 474 475 |
if (res) error("decompressor failed"); } else if (compress_name) { |
23a22d57a bzip2/lzma: compr... |
476 477 478 479 480 481 |
if (!message) { snprintf(msg_buf, sizeof msg_buf, "compression method %s not configured", compress_name); message = msg_buf; } |
df37bd156 initramfs: handle... |
482 |
} else |
e5eed351f init/initramfs.c:... |
483 |
error("invalid magic at start of compressed archive"); |
1da177e4c Linux-2.6.12-rc2 |
484 |
if (state != Reset) |
e5eed351f init/initramfs.c:... |
485 |
error("junk at the end of compressed archive"); |
30d65dbfe bzip2/lzma: confi... |
486 487 488 |
this_header = saved_offset + my_inptr; buf += my_inptr; len -= my_inptr; |
1da177e4c Linux-2.6.12-rc2 |
489 |
} |
889d51a10 initramfs: add op... |
490 |
dir_utime(); |
3265e66b1 directly use kmal... |
491 492 493 |
kfree(name_buf); kfree(symlink_buf); kfree(header_buf); |
1da177e4c Linux-2.6.12-rc2 |
494 495 |
return message; } |
0a7b35cb1 [PATCH] Add retai... |
496 497 498 499 500 501 502 503 504 505 |
static int __initdata do_retain_initrd; static int __init retain_initrd_param(char *str) { if (*str) return 0; do_retain_initrd = 1; return 1; } __setup("retain_initrd", retain_initrd_param); |
d8ae8a376 initramfs: move t... |
506 507 508 509 510 511 512 513 |
#ifdef CONFIG_ARCH_HAS_KEEPINITRD static int __init keepinitrd_setup(char *__unused) { do_retain_initrd = 1; return 1; } __setup("keepinitrd", keepinitrd_setup); #endif |
ffe8018c3 initramfs: fix in... |
514 515 |
extern char __initramfs_start[]; extern unsigned long __initramfs_size; |
1da177e4c Linux-2.6.12-rc2 |
516 |
#include <linux/initrd.h> |
9c15e852a [PATCH] kexec: fi... |
517 |
#include <linux/kexec.h> |
0f3d2bd54 [PATCH] free init... |
518 |
|
55d5b7dd6 initramfs: fix cl... |
519 |
void __weak __init free_initrd_mem(unsigned long start, unsigned long end) |
4afd58e14 initramfs: provid... |
520 |
{ |
899ee4afe arm64: use generi... |
521 522 523 524 525 526 |
#ifdef CONFIG_ARCH_KEEP_MEMBLOCK unsigned long aligned_start = ALIGN_DOWN(start, PAGE_SIZE); unsigned long aligned_end = ALIGN(end, PAGE_SIZE); memblock_free(__pa(aligned_start), aligned_end - aligned_start); #endif |
f94f7434c initramfs: poison... |
527 528 |
free_reserved_area((void *)start, (void *)end, POISON_FREE_INITMEM, "initrd"); |
4afd58e14 initramfs: provid... |
529 |
} |
2965faa5e kexec: split kexe... |
530 |
#ifdef CONFIG_KEXEC_CORE |
e99332e7b gcc-10: mark more... |
531 |
static bool __init kexec_free_initrd(void) |
23091e287 initramfs: cleanu... |
532 |
{ |
9c15e852a [PATCH] kexec: fi... |
533 534 535 536 537 538 539 |
unsigned long crashk_start = (unsigned long)__va(crashk_res.start); unsigned long crashk_end = (unsigned long)__va(crashk_res.end); /* * If the initrd region is overlapped with crashkernel reserved region, * free only memory that is not part of crashkernel region. */ |
23091e287 initramfs: cleanu... |
540 541 542 543 544 545 546 547 548 549 550 551 |
if (initrd_start >= crashk_end || initrd_end <= crashk_start) return false; /* * Initialize initrd memory region since the kexec boot does not do. */ memset((void *)initrd_start, 0, initrd_end - initrd_start); if (initrd_start < crashk_start) free_initrd_mem(initrd_start, crashk_start); if (initrd_end > crashk_end) free_initrd_mem(crashk_end, initrd_end); return true; |
0f3d2bd54 [PATCH] free init... |
552 |
} |
23091e287 initramfs: cleanu... |
553 554 555 556 557 558 |
#else static inline bool kexec_free_initrd(void) { return false; } #endif /* CONFIG_KEXEC_CORE */ |
0f3d2bd54 [PATCH] free init... |
559 |
|
a841c673f revert "initramfs... |
560 |
#ifdef CONFIG_BLK_DEV_RAM |
4ada1e810 initramfs: fix po... |
561 |
static void __init populate_initrd_image(char *err) |
7c184ecd2 initramfs: factor... |
562 563 |
{ ssize_t written; |
bf6419e4d initramfs: switch... |
564 565 |
struct file *file; loff_t pos = 0; |
7c184ecd2 initramfs: factor... |
566 567 568 569 570 571 |
unpack_to_rootfs(__initramfs_start, __initramfs_size); printk(KERN_INFO "rootfs image is not initramfs (%s); looks like an initrd ", err); |
bf6419e4d initramfs: switch... |
572 573 |
file = filp_open("/initrd.image", O_WRONLY | O_CREAT, 0700); if (IS_ERR(file)) |
7c184ecd2 initramfs: factor... |
574 |
return; |
bf6419e4d initramfs: switch... |
575 576 |
written = xwrite(file, (char *)initrd_start, initrd_end - initrd_start, &pos); |
7c184ecd2 initramfs: factor... |
577 578 579 580 |
if (written != initrd_end - initrd_start) pr_err("/initrd.image: incomplete write (%zd != %ld) ", written, initrd_end - initrd_start); |
bf6419e4d initramfs: switch... |
581 |
fput(file); |
7c184ecd2 initramfs: factor... |
582 583 |
} #endif /* CONFIG_BLK_DEV_RAM */ |
9a9e0d685 ACPI: Remove ACPI... |
584 |
static int __init populate_rootfs(void) |
1da177e4c Linux-2.6.12-rc2 |
585 |
{ |
17a9be317 initramfs: Always... |
586 |
/* Load the built in initramfs */ |
ffe8018c3 initramfs: fix in... |
587 |
char *err = unpack_to_rootfs(__initramfs_start, __initramfs_size); |
1da177e4c Linux-2.6.12-rc2 |
588 |
if (err) |
499a4584d init: fix possibl... |
589 |
panic("%s", err); /* Failed to decompress INTERNAL initramfs */ |
afef7889c initramfs: cleanu... |
590 591 592 593 594 |
if (!initrd_start || IS_ENABLED(CONFIG_INITRAMFS_FORCE)) goto done; if (IS_ENABLED(CONFIG_BLK_DEV_RAM)) |
a1e6b6c1a initramfs: clean ... |
595 596 |
printk(KERN_INFO "Trying to unpack rootfs image as initramfs... "); |
afef7889c initramfs: cleanu... |
597 598 599 |
else printk(KERN_INFO "Unpacking initramfs... "); |
54c7a8916 initramfs: free i... |
600 |
|
afef7889c initramfs: cleanu... |
601 602 |
err = unpack_to_rootfs((char *)initrd_start, initrd_end - initrd_start); if (err) { |
9ab6b7184 initramfs: remove... |
603 |
#ifdef CONFIG_BLK_DEV_RAM |
7c184ecd2 initramfs: factor... |
604 |
populate_initrd_image(err); |
9ab6b7184 initramfs: remove... |
605 606 607 608 |
#else printk(KERN_EMERG "Initramfs unpacking failed: %s ", err); #endif |
1da177e4c Linux-2.6.12-rc2 |
609 |
} |
23091e287 initramfs: cleanu... |
610 |
|
afef7889c initramfs: cleanu... |
611 |
done: |
23091e287 initramfs: cleanu... |
612 613 614 615 |
/* * If the initrd region is overlapped with crashkernel reserved region, * free only memory that is not part of crashkernel region. */ |
5d59aa8f9 initramfs: don't ... |
616 |
if (!do_retain_initrd && initrd_start && !kexec_free_initrd()) |
23091e287 initramfs: cleanu... |
617 618 619 |
free_initrd_mem(initrd_start, initrd_end); initrd_start = 0; initrd_end = 0; |
17a9be317 initramfs: Always... |
620 |
flush_delayed_fput(); |
8d610dd52 Make sure we popu... |
621 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
622 |
} |
8d610dd52 Make sure we popu... |
623 |
rootfs_initcall(populate_rootfs); |