summaryrefslogtreecommitdiff
path: root/bootloader/x1000/boot.c
diff options
context:
space:
mode:
Diffstat (limited to 'bootloader/x1000/boot.c')
-rw-r--r--bootloader/x1000/boot.c91
1 files changed, 91 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
30void boot_rockbox(void) 33void 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
63static 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 */
126void 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 */