CROSS_COMPILE ?= arm-linux-
CC = $(CROSS_COMPILE)gcc
AS = $(CROSS_COMPILE)as
-CFLAGS += -Wall -ggdb
-LDFLAGS += -static -ggdb -lpthread -lrt
+CFLAGS += -Wall -ggdb -DLOADER
+LDFLAGS += -ggdb -lpthread -lrt
ifndef DEBUG
CFLAGS += -O2 -fno-strict-aliasing
LDFLAGS += -s -O2
endif
+ifdef DBG
+CFLAGS += -DDBG=$(DBG)
+endif
ifeq "$(ARCH)" "ia32"
ARCH = ia32
vpath %.c = ../common/
-TARGET = ginge_sloader
-OBJ += loader.o loader_$(ARCH).o patches.o emu.o host_fb.o host_pnd.o
+TARGET_S = ginge_sloader
+TARGET_D = ginge_dyn
+
+OBJ += emu.o host_fb.o host_pnd.o cmn.o
+OBJ_S += $(OBJ) loader.o loader_$(ARCH).o patches.o
+OBJ_D += $(OBJ) dl.o
+
+all: $(TARGET_S) $(TARGET_D)
-$(TARGET): LDFLAGS += -Wl,-T script_$(ARCH).lds
+$(TARGET_S): LDFLAGS += -Wl,-T script_$(ARCH).lds
+$(TARGET_D): LDFLAGS += -ldl
-$(TARGET): $(OBJ)
- $(CC) -o $@ $^ $(LDFLAGS)
+$(TARGET_S): $(OBJ_S)
+ $(CC) -o $@ $^ -static $(LDFLAGS)
+
+$(TARGET_D): $(OBJ_D)
+ $(CC) -o $@ $^ -shared $(LDFLAGS)
clean:
- $(RM) $(TARGET) $(OBJ)
+ $(RM) $(TARGET_S) $(TARGET_D) $(OBJ_S) $(OBJ_D)
+
+# basic deps
+dl.o patches.o: override.c
+*.o: header.h
+
--- /dev/null
+// vim:shiftwidth=2:expandtab
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <dlfcn.h>
+#include "header.h"
+
+#define DL
+#include "override.c"
+
+__attribute__((constructor))
+static void ginge_init(void)
+{
+ unsigned int lowest_segment = (unsigned int)-1;
+ unsigned int start, end;
+ int i, ret;
+ FILE *f;
+
+ for (i = 0; i < ARRAY_SIZE(real_funcs_np); i++) {
+ *real_funcs_np[i].func_ptr = dlsym(RTLD_NEXT, real_funcs_np[i].name);
+ if (*real_funcs_np[i].func_ptr == NULL) {
+ fprintf(stderr, "dlsym %s: %s\n", real_funcs_np[i].name, dlerror());
+ exit(1);
+ }
+ // dbg("%p %s\n", *real_funcs_np[i].func_ptr, real_funcs_np[i].name);
+ }
+
+ f = fopen("/proc/self/maps", "r");
+ if (f == NULL) {
+ perror("open /proc/self/maps");
+ exit(1);
+ }
+
+ ret = fscanf(f, "%x-%x %*s %*s %*s %*s %*s\n", &start, &end);
+ if (ret != 2) {
+ perror("parse maps");
+ exit(1);
+ }
+ lowest_segment = start;
+
+ // assume first entry lists program's text section.
+ // unprotect it in case we need some patching.
+ ret = mprotect((void *)start, end - start, PROT_READ|PROT_WRITE|PROT_EXEC);
+ if (ret != 0)
+ perror("warning: mprotect");
+
+ while (1) {
+ ret = fscanf(f, "%x-%*s %*s %*s %*s %*s %*s\n", &start);
+ if (ret <= 0)
+ break;
+
+ if (start < lowest_segment)
+ lowest_segment = start;
+ }
+
+#if 0
+ rewind(f);
+ char buff[256];
+ while (fgets(buff, sizeof(buff), f))
+ fputs(buff, stdout);
+#endif
+ fclose(f);
+
+ emu_init((void *)lowest_segment);
+}
+
#include <errno.h>
#include <time.h>
#include <sys/resource.h>
+#include <sys/ioctl.h>
+#include <linux/soundcard.h>
+#include <linux/fb.h>
#include "header.h"
+#include "../common/host_fb.h"
+#include "../common/cmn.h"
#include "sys_cacheflush.h"
+#include "realfuncs.h"
-//#define LOG_IO
-//#define LOG_IO_UNK
+#if (dbg & 2)
+#define LOG_IO_UNK
+#endif
+#if (dbg & 4)
+#define LOG_IO
+#endif
//#define LOG_SEGV
#ifdef LOG_IO
u32 *regs = (u32 *)&context->uc_mcontext.arm_r0;
u32 *pc = (u32 *)regs[15];
struct op_context *op_ctx;
- int lp_size;
+ int i, lp_size;
if (((regs[15] ^ (u32)&segv_sigaction) & 0xff000000) == 0 || // PC is in our segment or
(((regs[15] ^ (u32)g_linkpage) & ~(LINKPAGE_ALLOC - 1)) == 0) || // .. in linkpage
{
// real crash - time to die
err("segv %d %p @ %08x\n", info->si_code, info->si_addr, regs[15]);
+ for (i = 0; i < 8; i++)
+ err(" r%d=%08x r%2d=%08x\n", i, regs[i], i+8, regs[i+8]);
signal(num, SIG_DFL);
raise(num);
return;
void emu_init(void *map_bottom)
{
- struct sigaction segv_action = {
+ sigaction_t segv_action = {
.sa_sigaction = segv_sigaction,
.sa_flags = SA_SIGINFO,
};
*((char *)g_handler_stack_end - 4096) = 1;
g_linkpage = (void *)(((u32)map_bottom - LINKPAGE_ALLOC) & ~0xfff);
- pret = mmap(g_linkpage, LINKPAGE_ALLOC, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+ pret = mmap(g_linkpage, LINKPAGE_ALLOC, PROT_READ|PROT_WRITE,
+ MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
if (pret != g_linkpage) {
perror(PFX "mmap linkpage");
exit(1);
// host stuff
ret = host_video_init(&host_stride, 0);
if (ret != 0) {
- err("can't alloc screen\n");
+ err("can't init video\n");
exit(1);
}
host_screen = host_video_flip();
// mmsp2 defaults
mmsp2.mlc_stl_adr = 0x03101000; // fb2 is at 0x03381000
+ mmsp2.mlc_stl_cntl = 0x4ab; // 16bpp, region 1 active
sigemptyset(&segv_action.sa_mask);
sigaction(SIGSEGV, &segv_action, NULL);
if (fd == FAKEDEV_FB1)
return emu_mmap_dev(length, prot, flags, offset + 0x03381000);
- err("bad/ni mmap(?, %d, %x, %x, %d, %08x)", length, prot, flags, fd, offset);
+ err("bad/ni mmap(?, %d, %x, %x, %d, %08x)\n", length, prot, flags, fd, offset);
errno = EINVAL;
return MAP_FAILED;
}
-#include <sys/ioctl.h>
-#include <linux/soundcard.h>
-
static int emu_sound_ioctl(int fd, int request, void *argp)
{
int *arg = argp;
return ioctl(fd, request, argp);
}
-#include <linux/fb.h>
-
int emu_do_ioctl(int fd, int request, void *argp)
{
if (fd == emu_interesting_fds[IFD_SOUND].fd)
return emu_sound_ioctl(fd, request, argp);
- if (argp == NULL)
- goto fail;
+ switch (fd) {
+ /* *********************** */
+ case FAKEDEV_FB0:
+ case FAKEDEV_FB1:
+ if (argp == NULL)
+ goto fail;
- if (fd == FAKEDEV_FB0 || fd == FAKEDEV_FB1) {
switch (request) {
case FBIOGET_FSCREENINFO: {
struct fb_fix_screeninfo *fix = argp;
strcpy(fix->id, "mmsp2_RGB0");
fix->type = FB_TYPE_PACKED_PIXELS;
fix->accel = FB_ACCEL_NONE;
+ fix->visual = FB_VISUAL_TRUECOLOR;
+ fix->line_length = 320*2;
fix->smem_start = (fd == FAKEDEV_FB0) ? 0x03101000 : 0x03381000;
fix->smem_len = 320*240*2;
return 0;
}
case FBIOGET_VSCREENINFO: {
struct fb_var_screeninfo *var = argp;
- static const struct fb_bitfield fbb_red = { offset: 0, length: 4, };
- static const struct fb_bitfield fbb_green = { offset: 0, length: 4, };
- static const struct fb_bitfield fbb_blue = { offset: 0, length: 4, };
+ static const struct fb_bitfield fbb_red = { offset: 11, length: 5, };
+ static const struct fb_bitfield fbb_green = { offset: 5, length: 6, };
+ static const struct fb_bitfield fbb_blue = { offset: 0, length: 5, };
memset(var, 0, sizeof(*var));
var->activate = FB_ACTIVATE_NOW;
var->blue = fbb_blue;
return 0;
}
+ case FBIOPUT_VSCREENINFO: {
+ struct fb_var_screeninfo *var = argp;
+ dbg(" put vscreen: %dx%d@%d\n", var->xres, var->yres, var->bits_per_pixel);
+ if (var->xres != 320 || var->yres != 240 || var->bits_per_pixel != 16)
+ return -1;
+ return 0;
+ }
}
+
+ /* *********************** */
+ case FAKEDEV_TTY0:
+ // fake tty0 to make GPH SDL happy
+ if (request == 0x4b46) // KDGKBENT
+ return -1;
+ return 0;
}
fail:
- err("bad/ni ioctl(%d, %08x, %p)", fd, request, argp);
+ err("bad/ni ioctl(%d, %08x, %p)\n", fd, request, argp);
errno = EINVAL;
return -1;
}
+static const struct {
+ const char *from;
+ const char *to;
+} path_map[] = {
+ { "/mnt/tmp/", "/tmp/" },
+};
+
+// FIXME: threads..
+static const char *wrap_path(const char *path)
+{
+ static char tmp_path[512];
+ int i, len;
+
+ // do only path mapping for now
+ for (i = 0; i < ARRAY_SIZE(path_map); i++) {
+ len = strlen(path_map[i].from);
+ if (strncmp(path, path_map[i].from, len) == 0) {
+ snprintf(tmp_path, sizeof(tmp_path), "%s%s", path_map[i].to, path + len);
+ dbg("mapped path \"%s\" -> \"%s\"\n", path, tmp_path);
+ return tmp_path;
+ }
+ }
+
+ return path;
+}
+
+void *emu_do_fopen(const char *path, const char *mode)
+{
+ return fopen(wrap_path(path), mode);
+}
+
+int emu_do_system(const char *command)
+{
+ static char tmp_path[512];
+ char *p, *p2;
+
+ if (command == NULL)
+ return -1;
+
+ // pass through stuff in PATH
+ p = strchr(command, ' ');
+ p2 = strchr(command, '/');
+ if (p2 == NULL || (p != NULL && p2 > p))
+ return system(command);
+
+ make_local_path(tmp_path, sizeof(tmp_path), "ginge_prep");
+ p = tmp_path + strlen(tmp_path);
+
+ snprintf(p, sizeof(tmp_path) - (p - tmp_path), " %s", wrap_path(command));
+ dbg("system: \"%s\"\n", tmp_path);
+ return system(tmp_path);
+}
+
--- /dev/null
+#!/bin/sh
+
+root=$1
+shift
+
+loader="${root}lib/ld-linux.so.2"
+export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${root}lib"
+export LD_PRELOAD="${root}ginge_dyn"
+
+export GINGE_ROOT="${root}"
+
+exec "${loader}" "$@"
-#include "../common/host_fb.h"
+#ifndef INCLUDE_sQt5fY5eUJn5tKV0IBTDxK0zqQutTqTp
+#define INCLUDE_sQt5fY5eUJn5tKV0IBTDxK0zqQutTqTp 1
#define PFX "ginge: "
#define err(f, ...) fprintf(stderr, PFX f, ##__VA_ARGS__)
#define log(f, ...) fprintf(stdout, PFX f, ##__VA_ARGS__)
-#if 1
+#ifdef DBG
#define dbg log
#define dbg_c printf
#else
IFD_SOUND = 0,
};
+// note: __FD_SETSIZE is 1024, fd_set stuff will crash if made larger
enum {
- FAKEDEV_MEM = 10001,
+ FAKEDEV_MEM = 1001,
FAKEDEV_GPIO,
FAKEDEV_FB0,
FAKEDEV_FB1,
FAKEDEV_MMUHACK,
+ FAKEDEV_TTY0,
FAKEDEV_FD_BOUNDARY,
};
void *emu_do_mmap(unsigned int length, int prot, int flags, int fd, unsigned int offset);
int emu_do_ioctl(int fd, int request, void *argp);
int emu_read_gpiodev(void *buf, int count);
+void *emu_do_fopen(const char *path, const char *mode);
+int emu_do_system(const char *command);
int host_read_btns(void);
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+#endif /* INCLUDE_sQt5fY5eUJn5tKV0IBTDxK0zqQutTqTp */
#include <linux/input.h>
#include "header.h"
+#include "realfuncs.h"
static int ifds[2] = { -1, -1 };
static int init_done;
for (ifd = -1, i = 0; ifds[0] == -1 || ifds[1] == -1; i++) {
snprintf(buff, sizeof(buff), "/dev/input/event%i", i);
- ifd = open(buff, O_RDONLY | O_NONBLOCK);
+ ifd = open(buff, O_RDONLY | O_NONBLOCK, 0);
if (ifd == -1)
break;
#include <sys/mman.h>
#include "header.h"
+#include "realfuncs.h"
#define CHECK_(val, fail_operator, expect, err_msg) \
if (val fail_operator expect) { \
for (i = 0; i < ARRAY_SIZE(maps); i++) {
ret = fscanf(fi, "%lx-%lx %*s %*s %*s %*s %*s\n", &maps[i].start, &maps[i].end);
- if (ret == 0)
+ if (ret <= 0)
break;
CHECK_EQ(ret, 2, "maps parse error");
}
--- /dev/null
+// vim:shiftwidth=2:expandtab
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <signal.h>
+#include <termios.h>
+
+#include "realfuncs.h"
+#include "header.h"
+
+#if (DBG & 1)
+#define strace printf
+#else
+#define strace(...)
+#endif
+
+#define UNUSED __attribute__((unused))
+
+static const struct dev_fd_t takeover_devs[] = {
+ { "/dev/mem", FAKEDEV_MEM },
+ { "/dev/GPIO", FAKEDEV_GPIO },
+ { "/dev/fb0", FAKEDEV_FB0 },
+ { "/dev/fb/0", FAKEDEV_FB0 },
+ { "/dev/fb1", FAKEDEV_FB1 },
+ { "/dev/fb/1", FAKEDEV_FB1 },
+ { "/dev/mmuhack", FAKEDEV_MMUHACK },
+ { "/dev/tty", -1 }, // XXX hmh..
+ { "/dev/tty0", FAKEDEV_TTY0 },
+};
+
+static int w_open(const char *pathname, int flags, mode_t mode)
+{
+ int i, ret;
+
+ for (i = 0; i < ARRAY_SIZE(takeover_devs); i++) {
+ if (strcmp(pathname, takeover_devs[i].name) == 0) {
+ ret = takeover_devs[i].fd;
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(takeover_devs))
+ ret = open(pathname, flags, mode);
+
+ if (ret >= 0) {
+ for (i = 0; emu_interesting_fds[i].name != NULL; i++) {
+ if (strcmp(pathname, emu_interesting_fds[i].name) == 0) {
+ emu_interesting_fds[i].fd = ret;
+ break;
+ }
+ }
+ }
+
+ strace("open(%s) = %d\n", pathname, ret);
+ return ret;
+}
+
+static void *w_mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
+{
+ void *ret;
+ if (FAKEDEV_MEM <= fd && fd < FAKEDEV_FD_BOUNDARY)
+ ret = emu_do_mmap(length, prot, flags, fd, offset);
+ else
+ ret = mmap(addr, length, prot, flags, fd, offset);
+
+ // threads are using heap before they mmap their stack
+ // printf needs valid stack for pthread/errno
+ if (((long)&ret & 0xf0000000) == 0xb0000000)
+ strace("mmap(%p, %x, %x, %x, %d, %lx) = %p\n", addr, length, prot, flags, fd, (long)offset, ret);
+ return ret;
+}
+#define w_mmap2 w_mmap
+
+static ssize_t w_read(int fd, void *buf, size_t count)
+{
+ ssize_t ret;
+ if (fd == FAKEDEV_GPIO)
+ ret = emu_read_gpiodev(buf, count);
+ else
+ ret = read(fd, buf, count);
+
+ //strace("read(%d, %p, %d) = %d\n", fd, buf, count, ret);
+ return ret;
+}
+
+static int w_ioctl(int fd, int request, void *argp)
+{
+ int ret;
+
+ if ((FAKEDEV_MEM <= fd && fd < FAKEDEV_FD_BOUNDARY) ||
+ fd == emu_interesting_fds[IFD_SOUND].fd)
+ ret = emu_do_ioctl(fd, request, argp);
+ else
+ ret = ioctl(fd, request, argp);
+
+ strace("ioctl(%d, %08x, %p) = %d\n", fd, request, argp, ret);
+ return ret;
+}
+
+static int w_sigaction(int signum, const void *act, void *oldact)
+{
+ strace("sigaction(%d, %p, %p) = %d\n", signum, act, oldact, 0);
+ return 0;
+}
+
+/* dynamic only */
+static UNUSED int w_tcgetattr(int fd, struct termios *termios_p)
+{
+ int ret;
+ if (fd != FAKEDEV_TTY0)
+ ret = tcgetattr(fd, termios_p);
+ else
+ ret = 0;
+
+ strace("tcgetattr(%d, %p) = %d\n", fd, termios_p, ret);
+ return ret;
+}
+
+static UNUSED int w_tcsetattr(int fd, int optional_actions,
+ const struct termios *termios_p)
+{
+ int ret;
+ if (fd != FAKEDEV_TTY0)
+ ret = tcsetattr(fd, optional_actions, termios_p);
+ else
+ ret = 0;
+
+ strace("tcsetattr(%d, %x, %p) = %d\n", fd, optional_actions, termios_p, ret);
+ return ret;
+}
+
+static UNUSED FILE *w_fopen(const char *path, const char *mode)
+{
+ FILE *ret = emu_do_fopen(path, mode);
+ strace("fopen(%s, %s) = %p\n", path, mode, ret);
+ return ret;
+}
+
+static UNUSED int w_system(const char *command)
+{
+ int ret = emu_do_system(command);
+ strace("system(%s) = %d\n", command, ret);
+ return ret;
+}
+
+#undef open
+#undef fopen
+#undef mmap
+#undef read
+#undef ioctl
+#undef sigaction
+#undef tcgetattr
+#undef tcsetattr
+#undef system
+
+#ifdef DL
+
+#define MAKE_WRAP_SYM(sym) \
+ /* alias wrap symbols to real names */ \
+ typeof(sym) sym __attribute__((alias("w_" #sym))); \
+ /* wrapper to real functions, to be set up on load */ \
+ static typeof(sym) *p_real_##sym
+
+MAKE_WRAP_SYM(open);
+MAKE_WRAP_SYM(fopen);
+MAKE_WRAP_SYM(mmap);
+MAKE_WRAP_SYM(read);
+MAKE_WRAP_SYM(ioctl);
+MAKE_WRAP_SYM(sigaction);
+MAKE_WRAP_SYM(tcgetattr);
+MAKE_WRAP_SYM(tcsetattr);
+MAKE_WRAP_SYM(system);
+typeof(mmap) mmap2 __attribute__((alias("w_mmap")));
+
+#define REAL_FUNC_NP(name) \
+ { #name, (void **)&p_real_##name }
+
+static const struct {
+ const char *name;
+ void **func_ptr;
+} real_funcs_np[] = {
+ REAL_FUNC_NP(open),
+ REAL_FUNC_NP(fopen),
+ REAL_FUNC_NP(mmap),
+ REAL_FUNC_NP(read),
+ REAL_FUNC_NP(ioctl),
+ REAL_FUNC_NP(sigaction),
+ REAL_FUNC_NP(tcgetattr),
+ REAL_FUNC_NP(tcsetattr),
+ REAL_FUNC_NP(system),
+};
+
+#define open p_real_open
+#define fopen p_real_fopen
+#define mmap p_real_mmap
+#define read p_real_read
+#define ioctl p_real_ioctl
+#define sigaction p_real_sigaction
+#define tcgetattr p_real_tcgetattr
+#define tcsetattr p_real_tcsetattr
+#define system p_real_system
+
+#undef MAKE_WRAP_SYM
+#undef REAL_FUNC_NP
+
+#endif
+
+// just call real funcs for static, pointer for dynamic
+int real_open(const char *pathname, int flags, mode_t mode)
+{
+ return open(pathname, flags, mode);
+}
+
+FILE *real_fopen(const char *path, const char *mode)
+{
+ return fopen(path, mode);
+}
+
+void *real_mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
+{
+ return mmap(addr, length, prot, flags, fd, offset);
+}
+
+int real_read(int fd, void *buf, size_t count)
+{
+ return read(fd, buf, count);
+}
+
+int real_ioctl(int d, int request, void *argp)
+{
+ return ioctl(d, request, argp);
+}
+
+int real_sigaction(int signum, const sigaction_t *act, sigaction_t *oldact)
+{
+ return sigaction(signum, act, oldact);
+}
+
+int real_tcgetattr(int fd, struct termios *termios_p)
+{
+ return tcgetattr(fd, termios_p);
+}
+
+int real_tcsetattr(int fd, int optional_actions,
+ const struct termios *termios_p)
+{
+ return tcsetattr(fd, optional_actions, termios_p);
+}
+
+int real_system(const char *command)
+{
+ return system(command);
+}
// vim:shiftwidth=2:expandtab
#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
#include "header.h"
#include "sys_cacheflush.h"
-#if 0
-#define strace printf
-#else
-#define strace(...)
-#endif
+#include "override.c"
// note: first mask must be always full for search algo
static const unsigned int sig_mask_all[] = {
};
#define sig_mask_mmap sig_mask_all
-static const unsigned int sig_mmap_[] = {
+static const unsigned int sig_mmap2[] = {
0xe52d5004, 0xe59d5008, 0xe52d4004, 0xe59d4008,
0xe1b0ca05, 0x1a000006, 0xe1a05625, 0xef9000c0
};
-#define sig_mask_mmap_ sig_mask_all
+#define sig_mask_mmap2 sig_mask_all
static const unsigned int sig_read[] = {
0xe59fc080, 0xe59cc000, 0xe33c0000, 0x1a000003, 0xef900003
0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000
};
-static const struct dev_fd_t takeover_devs[] = {
- { "/dev/mem", FAKEDEV_MEM },
- { "/dev/GPIO", FAKEDEV_GPIO },
- { "/dev/fb0", FAKEDEV_FB0 },
- { "/dev/fb/0", FAKEDEV_FB0 },
- { "/dev/fb1", FAKEDEV_FB1 },
- { "/dev/fb/1", FAKEDEV_FB1 },
- { "/dev/mmuhack", FAKEDEV_MMUHACK },
-};
-
-static int w_open(const char *pathname, int flags, mode_t mode)
-{
- int i, ret;
-
- for (i = 0; i < ARRAY_SIZE(takeover_devs); i++) {
- if (strcmp(pathname, takeover_devs[i].name) == 0) {
- ret = takeover_devs[i].fd;
- break;
- }
- }
-
- if (i == ARRAY_SIZE(takeover_devs))
- ret = open(pathname, flags, mode);
-
- if (ret >= 0) {
- for (i = 0; emu_interesting_fds[i].name != NULL; i++) {
- if (strcmp(pathname, emu_interesting_fds[i].name) == 0) {
- emu_interesting_fds[i].fd = ret;
- break;
- }
- }
- }
-
- strace("open(%s) = %d\n", pathname, ret);
- return ret;
-}
-
-static void *w_mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
-{
- void *ret;
- if (FAKEDEV_MEM <= fd && fd < FAKEDEV_FD_BOUNDARY)
- ret = emu_do_mmap(length, prot, flags, fd, offset);
- else
- ret = mmap(addr, length, prot, flags, fd, offset);
-
- // threads are using heap before they mmap their stack
- // printf needs valid stack for pthtead/errno
- if (((long)&ret & 0xf0000000) == 0xb0000000)
- strace("mmap(%p, %x, %x, %x, %d, %lx) = %p\n", addr, length, prot, flags, fd, (long)offset, ret);
- return ret;
-}
-#define w_mmap_ w_mmap
-
-static ssize_t w_read(int fd, void *buf, size_t count)
-{
- ssize_t ret;
- if (fd != FAKEDEV_GPIO)
- return read(fd, buf, count);
-
- ret = emu_read_gpiodev(buf, count);
- //strace("read(%d, %p, %d) = %d\n", fd, buf, count, ret);
- return ret;
-}
-
-static int w_ioctl(int fd, int request, void *argp)
-{
- int ret;
-
- if ((FAKEDEV_MEM <= fd && fd < FAKEDEV_FD_BOUNDARY) ||
- fd == emu_interesting_fds[IFD_SOUND].fd)
- ret = emu_do_ioctl(fd, request, argp);
- else
- ret = ioctl(fd, request, argp);
-
- strace("ioctl(%d, %08x, %p) = %d\n", fd, request, argp, ret);
- return ret;
-}
-
-static int w_sigaction(int signum, const void *act, void *oldact)
-{
- strace("sigaction(%d, %p, %p) = %d\n", signum, act, oldact, 0);
- return 0;
-}
#define PATCH(f) { sig_##f, sig_mask_##f, ARRAY_SIZE(sig_##f), w_##f }
} patches[] = {
PATCH(open),
PATCH(mmap),
- PATCH(mmap_), // mmap using mmap2 syscall
+ PATCH(mmap2), // mmap2 syscall
PATCH(read),
PATCH(ioctl),
PATCH(sigaction),
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <signal.h>
+#include <termios.h>
+
+
+int real_open(const char *pathname, int flags, mode_t mode);
+FILE *real_fopen(const char *path, const char *mode);
+void *real_mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
+int real_read(int fd, void *buf, size_t count);
+int real_ioctl(int fd, int request, void *argp);
+int real_sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
+typedef struct sigaction sigaction_t;
+int real_tcgetattr(int fd, struct termios *termios_p);
+int real_tcsetattr(int fd, int optional_actions, const struct termios *termios_p);
+int real_system(const char *command);
+
+#define open real_open
+#define fopen real_fopen
+#define mmap real_mmap
+#define read real_read
+#define ioctl real_ioctl
+#define sigaction real_sigaction
+#define tcgetattr real_tcgetattr
+#define tcsetattr real_tcsetattr
+#define system real_system
+
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <signal.h>
+#include <termios.h>
+
+static int open_(const char *name)
+{
+ int fd = open(name, O_RDWR);
+ if (fd < 0) {
+ fprintf(stderr, "%s: ", name);
+ perror("open");
+ return 1;
+ }
+
+ return fd;
+}
int main(int argc, char *argv[])
{
volatile void *memregs;
- int memdev;
+ void *fbmem;
+ int memdev, fbdev;
int i;
printf("hi, home=%s\n", getenv("HOME"));
for (i = 0; i < argc; i++)
printf("%d \"%s\"\n", i, argv[i]);
- memdev = open("/dev/mem", O_RDWR);
- if (memdev < 0) {
- perror("open");
- return 1;
- }
+ memdev = open_("/dev/mem");
+ fbdev = open_("/dev/fb0");
memregs = mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, memdev, 0xc0000000);
+ fbmem = mmap(NULL, 320*240*2, PROT_READ|PROT_WRITE, MAP_SHARED, fbdev, 0);
+
ioctl(-1, 0);
signal(7, SIG_DFL);
+// tcgetattr(-1, NULL);
+// tcsetattr(-1, 0, NULL);
+#if 1
for (i = 0; i < 2; i++)
printf("%02x %04x %08x\n", ((char *)memregs)[0x2011],
((short *)memregs)[0x1198/2], ((int *)memregs)[0xbcdc/4]);
+#endif
+ memset(fbmem, 0xff, 320*240*2);
- //sleep(1000);
+ sleep(10);
return 0;
}