Mozilla JavaScript 的 MIPS N32 ABI 支持补丁

Mozilla JavaScript 17.0 已经合并了 MIPS 公司开发的 MIPS 相关 JIT 补丁,仅支持 O32 ABI 的,此补丁用于增加 N32 ABI 的支持。

Mozilla JavaScript 官方版本:http://ftp.mozilla.org/pub/mozilla.org/js/mozjs17.0.0.tar.gz
N32 ABI 支持补丁:http://mirrors.heiher.info/sources/extra/js/

jit-test

python2 ./jit_test.py ../js17                                                                                                         
[4876|   0|   0|4876]    100% =======================================>|  466.9s
PASSED ALL

v8 benchmark

../js17 -m -n -f run.js
Richards: 838
DeltaBlue: 1063
Crypto: 1098
RayTrace: 330
EarleyBoyer: 991
RegExp: 128
Splay: 1182
NavierStokes: 732
----
Score (version 7): 659

Over!

提升 QEMU 中 MIPS-Malta 机器的 RAM 容量上限

目前 QEMU 中 MIPS-Malta 机器的 RAM 容量被限制在了最高 256M,原因是其外围设备被映射在了物理地址空间的 0x10000000 – 0x20000000 之间。为了使用更多的 RAM,需要同时修改机器的“硬件”配置和内核中的地址空间映射表来使用高端内存。为此需要使用 MIPS-5Kf 处理器且需要使用64位的内核,因为要访问 0x20000000 之后的物理地址空间。

在 QEMU 中,当 RAM 配置 <= 256M 时,只使用低 256M物理地址空间来映射;当 RAM 配置 > 256M 时,将其余部分映射到 0x20000000 之后,配置为:

0x00000000 - 0x0fffffff => RAM
0x10000000 - 0x1fffffff => 设备
0x20000000 -            => RAM

在 内核 中,增加一个内存映射表项,来标记 0x20000000 – 0x? 为 BOOT_MEM_RAM。

QEMU 补丁 => https://github.com/heiher/hev-patches/blob/master/qemu/qemu-mips-malta.diff
Kernel 补丁 => https://github.com/heiher/hev-patches/blob/master/linux/mips-malta.diff
Kernel 配置 => http://heiher.info/sftp/files/config.malta

目前,最高可设置为 2047M 的 RAM。

Over!

udevd worker timeout

Error information

Waiting for UDev uevents to be processed    [BUSY]
udevd[155]: worker [173] timeout, kill it
udevd[155]: seq 1431 '/devices/pci0000:00/0000:00:1c.1/0000:12:00.0' killed
udevd[155]: worker [173] terminated by signal 9 (Killed)

PCI device

12:00.0 Network controller: Broadcom Corporation BCM4313 802.11b/g/n Wireless LAN Controller (rev 01)

How to fix?
Edit /etc/rc.conf

MODULES=(fuse brcmsmac)  # add brcmsmac

Over!

Python for MIPS 修正记录

最近发现 Python2 和 Python3 在 import 共享库形式的模块时经常出现 “invalid mode parameter” 错误,追踪后发现是由于 MIPS 平台中 RTLD_GLOBAL 等宏和 x86 平台中定义值是不同的,而 Python 源代码中是默认为 x86 平台生成的,所以在编译前需要重新生成。

重新生成方法
Python2

cd Lib/plat-linux2/
./regen

Python3

cd Lib/plat-linux2/
./regen
cd Lib/plat-linux3/
./regen

Over!

Linux 输入设备共享程序: RInput

是否在调试中因频繁切换 Target 和 Host 的输入设备而感觉头大?是否因为 Target 主机的键盘不适应还感到不爽?RInput
帮你解决这个问题,它可以通过定义的一个按键来将 Host 主机的输入设备在两个主机间切换。

How to Build
Linux:

git clone --recursive https://gitlab.com/hev/hev-rinput
cd hev-rinput
make

Android:

mkdir hev-rinput
cd hev-rinput
git clone --recursive https://gitlab.com/hev/hev-rinput jni
ndk-build

How to Use
Receiver:

cat conf/main.ini
[Main]
Port=6380
Address=0.0.0.0
 
sudo bin/hev-rinput conf/main.ini

Sender:

cat conf/main.ini
[Main]
Port=6380
Address=192.168.1.2
; See /usr/include/linux/input-event-codes.h
SwitchKeyCode=119
 
sudo bin/hev-rinput conf/main.ini

默认 Switch Key
Pause

Over!

Build fastboot for Loongson(MIPS)

Step 1: Clone source code from git repos

git clone https://android.googlesource.com/platform/system/core.git

Step 2: Write a standalone Makefile

vim core/fastboot/Makefile
# Makefile for fastboot
 
SRCS+=protocol.c
SRCS+=engine.c
SRCS+=bootimg.c
SRCS+=fastboot.c
SRCS+=usb_linux.c
SRCS+=util_linux.c
 
VPATH+= ../libzipfile
SRCS+= centraldir.c
SRCS+= zipfile.c
 
CPPFLAGS+= -DADB_HOST=1
CPPFLAGS+= -DHAVE_FORKEXEC=1
CPPFLAGS+= -DHAVE_SYMLINKS
CPPFLAGS+= -DHAVE_TERMIO_H
CPPFLAGS+= -D_GNU_SOURCE
CPPFLAGS+= -D_XOPEN_SOURCE
CPPFLAGS+= -I.
CPPFLAGS+= -I../include
CPPFLAGS+= -I../mkbootimg
CPPFLAGS+= -I../../../external/zlib
 
CFLAGS+= -O2 -Wno-unused-parameter
LDFLAGS= 
LIBS= -lrt -lpthread -lz
 
TOOLCHAIN= mipsel-unknown-linux-gnu-
CC= $(TOOLCHAIN)gcc
LD= $(TOOLCHAIN)gcc
 
OBJS= $(SRCS:.c=.o)
 
all: fastboot
 
fastboot: $(OBJS)
	$(LD) -o $@ $(LDFLAGS) $(OBJS) $(LIBS)
 
clean:
	rm -rf $(OBJS)

Step 3: Build

cd core/fastboot
make

Over!

在 MIPS 平台上运行时动态生成指令并执行 (2)

上次是直接在可执行的栈中写入指令并转移至执行的,这次在当栈和堆都不可执行的情况下,分配空间、写入指令并执行。还是直接看代码吧。

#include <stdio.h>
#include <errno.h>
#include <sys/mman.h>
 
int main(int argc, char *argv[])
{
	unsigned int *insn = NULL;
 
	insn = mmap(NULL, 4096, PROT_READ | PROT_WRITE | PROT_EXEC,
				MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
	if(MAP_FAILED != insn)
	{
		printf("%p\n", insn);
		insn[0] = 0x1000ffff;
		insn[1] = 0x00000000;
		__asm__ volatile (
					"jr %0 \n\t"
					"nop \n\t"
					::"r"(insn)
				);
		munmap(insn, 4096);
	}
	else
	{
		printf("%s\n", strerror(errno));
	}
 
	return 0;
}

在上面的代码中,使用系统调用 mmap 分配了一块 4096 字节的可读写、可执行的私有、匿名 VMA,并在此 VMA 中写入指令并转移至执行了。

我们来看一下此程序的运行时输出与 maps:

0x2ac88000
00400000-00404000 r-xp 00000000 08:04 262145                             /home/heiher/tmp/test
00410000-00414000 rw-p 00000000 08:04 262145                             /home/heiher/tmp/test
2ac64000-2ac88000 r-xp 00000000 08:02 917518                             /lib/ld-2.14.so
2ac88000-2ac8c000 rwxp 00000000 00:00 0 
2ac94000-2ac98000 rw-p 00020000 08:02 917518                             /lib/ld-2.14.so
2ac98000-2aca8000 rw-p 00000000 00:00 0 
2acb4000-2ae0c000 r-xp 00000000 08:02 918040                             /lib/libc-2.14.so
2ae0c000-2ae18000 ---p 00158000 08:02 918040                             /lib/libc-2.14.so
2ae18000-2ae1c000 r--p 00154000 08:02 918040                             /lib/libc-2.14.so
2ae1c000-2ae20000 rw-p 00158000 08:02 918040                             /lib/libc-2.14.so
2ae20000-2ae24000 rw-p 00000000 00:00 0 
7fc04000-7fc28000 rwxp 00000000 00:00 0                                  [stack]
7fff4000-7fff8000 r-xp 00000000 00:00 0                                  [vdso]

我们看到确定多出了一个我们所需要的 VMA:

2ac88000-2ac8c000 rwxp 00000000 00:00 0

但其长度却不是 4096 字节,而是 16K(16384)。这是因为我们当前的操作系统页面长度是 16K(16384),分配一个VMA至少需要一个完整的页面,当小于它的时候也需要分配一个完整的页面。

如何让进程的栈和堆都不可执行呢?有没有办法可以修改代码段的数据?在上面分配了 4096 字节的内存,而实际则是 16K,那么其 4096 之后的空间是否可以使用呢?动态生成指令随后立即执行是否有问题呢?

Over!