forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ARM] 4736/1: Export atags to userspace and allow kexec to use custom…
…ised atags Currently, the atags used by kexec are fixed to the ones originally used to boot the kernel. This is less than ideal as changing the commandline, initrd and other options would be a useful feature. This patch exports the atags used for the current kernel to userspace through an "atags" file in procfs. The presence of the file is controlled by its own Kconfig option and cleans up several ifdef blocks into a separate file. The tags for the new kernel are assumed to be at a fixed location before the kernel image itself. The location of the tags used to boot the original kernel is unimportant and no longer saved. Based on a patch from Uli Luckas <[email protected]> Signed-off-by: Richard Purdie <[email protected]> Acked-by: Uli Luckas <[email protected]> Signed-off-by: Russell King <[email protected]>
- Loading branch information
Showing
8 changed files
with
110 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
#include <linux/slab.h> | ||
#include <linux/kexec.h> | ||
#include <linux/proc_fs.h> | ||
#include <asm/setup.h> | ||
#include <asm/types.h> | ||
#include <asm/page.h> | ||
|
||
struct buffer { | ||
size_t size; | ||
char *data; | ||
}; | ||
static struct buffer tags_buffer; | ||
|
||
static int | ||
read_buffer(char* page, char** start, off_t off, int count, | ||
int* eof, void* data) | ||
{ | ||
struct buffer *buffer = (struct buffer *)data; | ||
|
||
if (off >= buffer->size) { | ||
*eof = 1; | ||
return 0; | ||
} | ||
|
||
count = min((int) (buffer->size - off), count); | ||
|
||
memcpy(page, &buffer->data[off], count); | ||
|
||
return count; | ||
} | ||
|
||
|
||
static int | ||
create_proc_entries(void) | ||
{ | ||
struct proc_dir_entry* tags_entry; | ||
|
||
tags_entry = create_proc_read_entry("atags", 0400, &proc_root, read_buffer, &tags_buffer); | ||
if (!tags_entry) | ||
return -ENOMEM; | ||
|
||
return 0; | ||
} | ||
|
||
|
||
static char __initdata atags_copy_buf[KEXEC_BOOT_PARAMS_SIZE]; | ||
static char __initdata *atags_copy; | ||
|
||
void __init save_atags(const struct tag *tags) | ||
{ | ||
atags_copy = atags_copy_buf; | ||
memcpy(atags_copy, tags, KEXEC_BOOT_PARAMS_SIZE); | ||
} | ||
|
||
|
||
static int __init init_atags_procfs(void) | ||
{ | ||
struct tag *tag; | ||
int error; | ||
|
||
if (!atags_copy) { | ||
printk(KERN_WARNING "Exporting ATAGs: No saved tags found\n"); | ||
return -EIO; | ||
} | ||
|
||
for (tag = (struct tag *) atags_copy; tag->hdr.size; tag = tag_next(tag)) | ||
; | ||
|
||
tags_buffer.size = ((char *) tag - atags_copy) + sizeof(tag->hdr); | ||
tags_buffer.data = kmalloc(tags_buffer.size, GFP_KERNEL); | ||
if (tags_buffer.data == NULL) | ||
return -ENOMEM; | ||
memcpy(tags_buffer.data, atags_copy, tags_buffer.size); | ||
|
||
error = create_proc_entries(); | ||
if (error) { | ||
printk(KERN_ERR "Exporting ATAGs: not enough memory\n"); | ||
kfree(tags_buffer.data); | ||
tags_buffer.size = 0; | ||
tags_buffer.data = NULL; | ||
} | ||
|
||
return error; | ||
} | ||
|
||
arch_initcall(init_atags_procfs); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#ifdef CONFIG_ATAGS_PROC | ||
extern void save_atags(struct tag *tags); | ||
#else | ||
static inline void save_atags(struct tag *tags) { } | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters