file_android.cc Source File

Back to the index.

file_android.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2018 Anders Gavare. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * 3. The name of the author may not be used to endorse or promote products
13  * derived from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  *
28  * COMMENT: Android boot.img file support
29  */
30 
31 /* Note: Included from file.c. */
32 
33 
35  uint8_t magic[8];
36 
37  uint32_t kernel_size;
38  uint32_t kernel_addr;
39  uint32_t ramdisk_size;
40  uint32_t ramdisk_addr;
41  uint32_t second_size;
42  uint32_t second_addr;
43 
44  uint32_t tags_addr;
45  uint32_t page_size;
46 
47  uint32_t header_version; /* 0: Pre-Android-9 1: Android 9 or higher */
48  uint32_t os_version;
49 
50  uint8_t name[16];
51  uint8_t cmdline[512];
52  uint32_t id[8];
53  uint8_t extra_cmdline[1024];
54 
55  /* Android 9 or higher: */
58  uint32_t header_size;
59 };
60 
61 
62 /*
63  * file_load_android():
64  *
65  * Loads an Android boot.img file into the emulated memory. The entry point
66  * is stored in the specified CPU's registers.
67  *
68  * See https://source.android.com/devices/bootloader/recovery-image and
69  * https://source.android.com/devices/bootloader/boot-image-header for more
70  * details.
71  */
72 static void file_load_android(struct machine *m, struct memory *mem,
73  char *filename, int flags,
74  uint64_t *entrypointp, int arch, int *byte_orderp)
75 {
76  FILE *f;
77  int encoding = ELFDATA2LSB;
78  uint32_t page_size;
79  uint32_t kernel_size, kernel_addr, kernel_pages;
80  uint32_t ramdisk_size, ramdisk_addr, ramdisk_pages;
81  uint32_t second_size, second_addr, second_pages;
83  unsigned char buf[65536];
84 
85  f = fopen(filename, "r");
86  if (f == NULL) {
87  perror(filename);
88  exit(1);
89  }
90 
91  int hlen = fread(&android_header, 1, sizeof(android_header), f);
92  if (hlen != sizeof(android_header)) {
93  fprintf(stderr, "%s: not a complete Android boot.img file\n",
94  filename);
95  exit(1);
96  }
97 
99  debug("Android boot.img format, page size 0x%x\n", page_size);
100 
103  kernel_pages = (kernel_size + (page_size - 1)) / page_size;
104  if (kernel_size > 0) {
105  debug("kernel: 0x%x bytes (%i pages) at addr 0x%08x\n", kernel_size, kernel_pages, kernel_addr);
106 
107  fseek(f, page_size * 1, SEEK_SET);
108 
109  uint32_t len_to_load = kernel_size;
110  uint32_t vaddr = kernel_addr;
111 
112  while (len_to_load != 0) {
113  int len = len_to_load > sizeof(buf) ? sizeof(buf) : len_to_load;
114  int len_read = fread(buf, 1, len, f);
115  if (len != len_read) {
116  fprintf(stderr, "could not read from %s\n", filename);
117  exit(1);
118  }
119 
120  /* printf("fread len=%i vaddr=%x buf[0..]=%02x %02x %02x\n",
121  (int)len, (int)vaddr, buf[0], buf[1], buf[2]); */
122 
123  int len2 = 0;
124  uint64_t vaddr1 = vaddr &
125  ((1 << BITS_PER_MEMBLOCK) - 1);
126  uint64_t vaddr2 = (vaddr +
127  len) & ((1 << BITS_PER_MEMBLOCK) - 1);
128  if (vaddr2 < vaddr1) {
129  len2 = len - vaddr2;
130  m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr,
131  &buf[0], len2, MEM_WRITE, NO_EXCEPTIONS);
132  }
133  m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr + len2,
134  &buf[len2], len-len2, MEM_WRITE, NO_EXCEPTIONS);
135 
136  vaddr += len;
137  len_to_load -= len;
138  }
139  } else {
140  fatal("kernel_size = 0?\n");
141  exit(1);
142  }
143 
146  ramdisk_pages = (ramdisk_size + (page_size - 1)) / page_size;
147  if (ramdisk_size > 0) {
148  debug("ramdisk: 0x%x bytes (%i pages) at addr 0x%08x\n", ramdisk_size, ramdisk_pages, ramdisk_addr);
149 
150  fseek(f, page_size * (1 + kernel_pages), SEEK_SET);
151 
152  uint32_t len_to_load = ramdisk_size;
153  uint32_t vaddr = ramdisk_addr;
154 
155  while (len_to_load != 0) {
156  int len = len_to_load > sizeof(buf) ? sizeof(buf) : len_to_load;
157  int len_read = fread(buf, 1, len, f);
158  if (len != len_read) {
159  fprintf(stderr, "could not read from %s\n", filename);
160  exit(1);
161  }
162 
163  /* printf("fread len=%i vaddr=%x buf[0..]=%02x %02x %02x\n",
164  (int)len, (int)vaddr, buf[0], buf[1], buf[2]); */
165 
166  int len2 = 0;
167  uint64_t vaddr1 = vaddr &
168  ((1 << BITS_PER_MEMBLOCK) - 1);
169  uint64_t vaddr2 = (vaddr +
170  len) & ((1 << BITS_PER_MEMBLOCK) - 1);
171  if (vaddr2 < vaddr1) {
172  len2 = len - vaddr2;
173  m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr,
174  &buf[0], len2, MEM_WRITE, NO_EXCEPTIONS);
175  }
176  m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr + len2,
177  &buf[len2], len-len2, MEM_WRITE, NO_EXCEPTIONS);
178 
179  vaddr += len;
180  len_to_load -= len;
181  }
182  }
183 
186  second_pages = (second_size + (page_size - 1)) / page_size;
187  if (second_size > 0) {
188  debug("second: 0x%x bytes (%i pages) at addr 0x%08x\n", second_size, second_pages, second_addr);
189 
190  fseek(f, page_size * (1 + kernel_pages + ramdisk_pages), SEEK_SET);
191 
192  uint32_t len_to_load = second_size;
193  uint32_t vaddr = second_addr;
194 
195  while (len_to_load != 0) {
196  int len = len_to_load > sizeof(buf) ? sizeof(buf) : len_to_load;
197  int len_read = fread(buf, 1, len, f);
198  if (len != len_read) {
199  fprintf(stderr, "could not read from %s\n", filename);
200  exit(1);
201  }
202 
203  /* printf("fread len=%i vaddr=%x buf[0..]=%02x %02x %02x\n",
204  (int)len, (int)vaddr, buf[0], buf[1], buf[2]); */
205 
206  int len2 = 0;
207  uint64_t vaddr1 = vaddr &
208  ((1 << BITS_PER_MEMBLOCK) - 1);
209  uint64_t vaddr2 = (vaddr +
210  len) & ((1 << BITS_PER_MEMBLOCK) - 1);
211  if (vaddr2 < vaddr1) {
212  len2 = len - vaddr2;
213  m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr,
214  &buf[0], len2, MEM_WRITE, NO_EXCEPTIONS);
215  }
216  m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr + len2,
217  &buf[len2], len-len2, MEM_WRITE, NO_EXCEPTIONS);
218 
219  vaddr += len;
220  len_to_load -= len;
221  }
222  }
223 
224  fclose(f);
225 
226  *entrypointp = (int32_t)kernel_addr;
227 
228  if (encoding == ELFDATA2LSB)
229  *byte_orderp = EMUL_LITTLE_ENDIAN;
230  else
231  *byte_orderp = EMUL_BIG_ENDIAN;
232 
233  n_executables_loaded ++;
234 }
235 
f
void f(int s, int func, int only_name)
Definition: generate_arm_r.c:45
memory
Definition: memory.h:75
android_header::page_size
uint32_t page_size
Definition: file_android.cc:45
debug
#define debug
Definition: dev_adb.cc:57
machine::cpus
struct cpu ** cpus
Definition: machine.h:140
unencode
#define unencode(var, dataptr, typ)
Definition: file.cc:69
EMUL_BIG_ENDIAN
#define EMUL_BIG_ENDIAN
Definition: misc.h:165
android_header::ramdisk_size
uint32_t ramdisk_size
Definition: file_android.cc:39
MEM_WRITE
#define MEM_WRITE
Definition: memory.h:117
android_header
Definition: file_android.cc:34
android_header::ramdisk_addr
uint32_t ramdisk_addr
Definition: file_android.cc:40
fatal
void fatal(const char *fmt,...)
Definition: main.cc:152
android_header::second_size
uint32_t second_size
Definition: file_android.cc:41
android_header::header_size
uint32_t header_size
Definition: file_android.cc:58
machine
Definition: machine.h:97
BITS_PER_MEMBLOCK
#define BITS_PER_MEMBLOCK
Definition: memory.h:92
android_header::recovery_dtbo_offset
uint64_t recovery_dtbo_offset
Definition: file_android.cc:57
android_header::tags_addr
uint32_t tags_addr
Definition: file_android.cc:44
android_header::name
uint8_t name[16]
Definition: file_android.cc:50
android_header::header_version
uint32_t header_version
Definition: file_android.cc:47
EMUL_LITTLE_ENDIAN
#define EMUL_LITTLE_ENDIAN
Definition: misc.h:164
NO_EXCEPTIONS
#define NO_EXCEPTIONS
Definition: memory.h:125
android_header::os_version
uint32_t os_version
Definition: file_android.cc:48
android_header::second_addr
uint32_t second_addr
Definition: file_android.cc:42
android_header::magic
uint8_t magic[8]
Definition: file_android.cc:35
android_header::extra_cmdline
uint8_t extra_cmdline[1024]
Definition: file_android.cc:53
ELFDATA2LSB
#define ELFDATA2LSB
Definition: exec_elf.h:155
android_header::kernel_addr
uint32_t kernel_addr
Definition: file_android.cc:38
android_header::kernel_size
uint32_t kernel_size
Definition: file_android.cc:37
android_header::cmdline
uint8_t cmdline[512]
Definition: file_android.cc:51
cpu::memory_rw
int(* memory_rw)(struct cpu *cpu, struct memory *mem, uint64_t vaddr, unsigned char *data, size_t len, int writeflag, int cache_flags)
Definition: cpu.h:368
android_header::recovery_dtbo_size
uint32_t recovery_dtbo_size
Definition: file_android.cc:56

Generated on Tue Aug 25 2020 19:25:06 for GXemul by doxygen 1.8.18