diff options
Diffstat (limited to 'bootloader')
-rw-r--r-- | bootloader/x1000/boot.c | 91 | ||||
-rw-r--r-- | bootloader/x1000/recovery.c | 1 | ||||
-rw-r--r-- | bootloader/x1000/x1000bootloader.h | 1 |
3 files changed, 93 insertions, 0 deletions
diff --git a/bootloader/x1000/boot.c b/bootloader/x1000/boot.c index ca69e2e057..153c2277aa 100644 --- a/bootloader/x1000/boot.c +++ b/bootloader/x1000/boot.c | |||
@@ -24,8 +24,11 @@ | |||
24 | #include "system.h" | 24 | #include "system.h" |
25 | #include "kernel.h" | 25 | #include "kernel.h" |
26 | #include "power.h" | 26 | #include "power.h" |
27 | #include "file.h" | ||
27 | #include "linuxboot.h" | 28 | #include "linuxboot.h" |
28 | #include "boot-x1000.h" | 29 | #include "boot-x1000.h" |
30 | #include <ctype.h> | ||
31 | #include <sys/types.h> | ||
29 | 32 | ||
30 | void boot_rockbox(void) | 33 | void boot_rockbox(void) |
31 | { | 34 | { |
@@ -53,6 +56,94 @@ void reboot(void) | |||
53 | } | 56 | } |
54 | 57 | ||
55 | /* | 58 | /* |
59 | * boot_linux() is intended for mainline kernels, and as such it | ||
60 | * should not need any major target-specific modifications. | ||
61 | */ | ||
62 | |||
63 | static int read_linux_args(const char* filename) | ||
64 | { | ||
65 | if(check_disk(false) != DISK_PRESENT) | ||
66 | return -1; | ||
67 | |||
68 | int ret; | ||
69 | |||
70 | size_t max_size; | ||
71 | int handle = core_alloc_maximum("args", &max_size, &buflib_ops_locked); | ||
72 | if(handle <= 0) { | ||
73 | splash(5*HZ, "Out of memory"); | ||
74 | return -2; | ||
75 | } | ||
76 | |||
77 | int fd = open(filename, O_RDONLY); | ||
78 | if(fd < 0) { | ||
79 | splash2(5*HZ, "Can't open args file", filename); | ||
80 | ret = -3; | ||
81 | goto err_free; | ||
82 | } | ||
83 | |||
84 | /* this isn't 100% correct but will be good enough */ | ||
85 | off_t fsize = filesize(fd); | ||
86 | if(fsize < 0 || fsize+1 > (off_t)max_size) { | ||
87 | splash(5*HZ, "Arguments too long"); | ||
88 | ret = -4; | ||
89 | goto err_close; | ||
90 | } | ||
91 | |||
92 | char* buf = core_get_data(handle); | ||
93 | core_shrink(handle, buf, fsize+1); | ||
94 | |||
95 | ssize_t rdres = read(fd, buf, fsize); | ||
96 | close(fd); | ||
97 | |||
98 | if(rdres != (ssize_t)fsize) { | ||
99 | splash(5*HZ, "Can't read args file"); | ||
100 | ret = -5; | ||
101 | goto err_free; | ||
102 | } | ||
103 | |||
104 | /* append a null terminator */ | ||
105 | char* end = buf + fsize; | ||
106 | *end = 0; | ||
107 | |||
108 | /* change all newlines, etc, to spaces */ | ||
109 | for(; buf != end; ++buf) | ||
110 | if(isspace(*buf)) | ||
111 | *buf = ' '; | ||
112 | |||
113 | return handle; | ||
114 | |||
115 | err_close: | ||
116 | close(fd); | ||
117 | err_free: | ||
118 | core_free(handle); | ||
119 | return ret; | ||
120 | } | ||
121 | |||
122 | /* | ||
123 | * Provisional linux loading function: kernel is at "/uImage", | ||
124 | * contents of "/linux_cmdline.txt" are used as kernel arguments. | ||
125 | */ | ||
126 | void boot_linux(void) | ||
127 | { | ||
128 | struct uimage_header uh; | ||
129 | size_t img_length; | ||
130 | int handle = load_uimage_file("/uImage", &uh, &img_length); | ||
131 | if(handle < 0) | ||
132 | return; | ||
133 | |||
134 | int args_handle = read_linux_args("/linux_cmdline.txt"); | ||
135 | if(args_handle < 0) { | ||
136 | core_free(handle); | ||
137 | return; | ||
138 | } | ||
139 | |||
140 | x1000_boot_linux(core_get_data(handle), img_length, | ||
141 | (void*)uimage_get_load(&uh), | ||
142 | (void*)uimage_get_ep(&uh), | ||
143 | core_get_data(args_handle)); | ||
144 | } | ||
145 | |||
146 | /* | ||
56 | * WARNING: Original firmware can be finicky. | 147 | * WARNING: Original firmware can be finicky. |
57 | * Be careful when modifying this code. | 148 | * Be careful when modifying this code. |
58 | */ | 149 | */ |
diff --git a/bootloader/x1000/recovery.c b/bootloader/x1000/recovery.c index ffd6151858..de6b3961cd 100644 --- a/bootloader/x1000/recovery.c +++ b/bootloader/x1000/recovery.c | |||
@@ -47,6 +47,7 @@ static const struct menuitem recovery_items[] = { | |||
47 | #ifdef OF_RECOVERY_NAME | 47 | #ifdef OF_RECOVERY_NAME |
48 | {MENUITEM_ACTION, OF_RECOVERY_NAME, &boot_of_recovery}, | 48 | {MENUITEM_ACTION, OF_RECOVERY_NAME, &boot_of_recovery}, |
49 | #endif | 49 | #endif |
50 | {MENUITEM_ACTION, "Linux", &boot_linux}, | ||
50 | {MENUITEM_HEADING, "System", NULL}, | 51 | {MENUITEM_HEADING, "System", NULL}, |
51 | {MENUITEM_ACTION, "USB mode", &usb_mode}, | 52 | {MENUITEM_ACTION, "USB mode", &usb_mode}, |
52 | {MENUITEM_ACTION, "Shutdown", &shutdown}, | 53 | {MENUITEM_ACTION, "Shutdown", &shutdown}, |
diff --git a/bootloader/x1000/x1000bootloader.h b/bootloader/x1000/x1000bootloader.h index 88d4e3585b..587a820eaf 100644 --- a/bootloader/x1000/x1000bootloader.h +++ b/bootloader/x1000/x1000bootloader.h | |||
@@ -141,6 +141,7 @@ void bootloader_restore(void); | |||
141 | void boot_rockbox(void); | 141 | void boot_rockbox(void); |
142 | void boot_of_player(void); | 142 | void boot_of_player(void); |
143 | void boot_of_recovery(void); | 143 | void boot_of_recovery(void); |
144 | void boot_linux(void); | ||
144 | void shutdown(void); | 145 | void shutdown(void); |
145 | void reboot(void); | 146 | void reboot(void); |
146 | 147 | ||