Initial commit
This commit is contained in:
commit
7218a9965a
65
README.MD
Normal file
65
README.MD
Normal file
@ -0,0 +1,65 @@
|
||||
# AMX MST701 Reverse Engineering
|
||||
|
||||
The [AMX MST701](https://www.amx.com/en/products/mst-701) is a nice little tablet intended for media control in conference rooms. It features a nice full-color TFT, a speaker, and touchscreen for user input, all powered over PoE.
|
||||
|
||||
This repository aims to document the hardware to allow repurposing as this device has now reached its end of life.
|
||||
|
||||
## Hardware
|
||||
|
||||
* LCD: Custom 1024x600 full-color TFT, connected over LVDS
|
||||
* Touchscreen: TSC2048, connected over SPI
|
||||
* Ethernet: AX88772BLF, connected over USB (usbh1)
|
||||
* Ethernet (unused): SMSC8720A, connected via (R)MII+SMI
|
||||
* USB: Internal USB-OTG port _or_ External USB-A port (via usbotg)
|
||||
* Audio: SGTL5000 + Speaker amp + Microphone, connected over i2s/i2c
|
||||
* Power: TPS65150, DA9053
|
||||
* CPU: i.MX53 (single-core @ 1 GHz)
|
||||
* RAM: 512 MB, 327 MB usable (rest is for GPU/VPU)
|
||||
* Storage: 4 GB Micro-SD card
|
||||
* Power: PoE
|
||||
* Misc: Power/User button on the top right, LED notification lights (unpopulated)
|
||||
* Misc dev: Debug LED on SoM, UART header on J3: \[?, TX, GND, RX\]
|
||||
|
||||
Note: The "generic" system components are placed on a little SoM mounted on the main PCB.
|
||||
|
||||
## Original Software
|
||||
|
||||
The original system runs on an ancient 2.6 kernel, with a giant monolithic binary for the official functionality. Audio runs through ALSA, display output is directly written to the framebuffer/DRM. The system is booted by a heavily modified U-Boot that also appears a little broken (e.g. passing kernel arguments doesn't really work).
|
||||
|
||||
### How to Explore?
|
||||
|
||||
* Passive: Open the device, grab the SD card, browse.
|
||||
* Active: Remove the SD card, patch the root login password, boot the system, log in over serial.
|
||||
|
||||
## Running Custom Linux
|
||||
|
||||
All system components have mainline Linux support. The necessary device tree can be found in `linux`.
|
||||
|
||||
To set up your custom SD card, follow these steps:
|
||||
|
||||
1. Write `linux/sd_card_head.img` to an SD card.
|
||||
2. Partition the SD card as needed for your distribution, keeping a 40 MB space before the first partition
|
||||
3. Write rootfs to SD card (e.g. [ArchLinuxArm](http://fl.us.mirror.archlinuxarm.org/os/ArchLinuxARM-armv7-latest.tar.gz))
|
||||
4. Compile Linux kernel (see below) and use `scripts/flash_sd.sh /dev/sdX` to flash kernel to the SD card (it goes into that "empty" 40 MB space)
|
||||
5. Copy Linux kernel modules to rootfs
|
||||
|
||||
For future updates via SSH, look into `scripts/upload_and_flash.sh`.
|
||||
|
||||
### Compiling Linux
|
||||
|
||||
* Make sure to include the full cmdline hardcoded in the kernel as the U-Boot is a little flaky:
|
||||
* `console=ttymxc0,115200 root=/dev/mmcblk0p1 rw fbcon=rotate:2`
|
||||
* or for debugging: `earlyprintk=serial,ttymxc0,115200 console=ttymxc0,115200 root=/dev/mmcblk0p2 rw fbcon=rotate:2 loglevel=7`
|
||||
* Make sure to include all drivers for the hardware
|
||||
* Copy and compile the device tree provided in `linux/imx53-amx-mst701.dts` to the kernel dir and add it to the build system.
|
||||
* Use build script `scripts/build.sh` to build a patched uImage with DTB attached to the kernel
|
||||
|
||||
## Open Issues
|
||||
|
||||
* Not yet implemented
|
||||
* Backlight (configured active by bootloader for now)
|
||||
* Notification LEDs (not populated on HW anyways)
|
||||
* Broken
|
||||
* Touchscreen does report any events
|
||||
* Speaker-amp (gpiochip4,2) not turned on automatically (needs to be activated using gpioset for now)
|
||||
|
353
linux/imx53-amx-mst701.dts
Normal file
353
linux/imx53-amx-mst701.dts
Normal file
@ -0,0 +1,353 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (C) 2024 Markus Koch <markus@notsyncing.net>
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
#include "imx53.dtsi"
|
||||
|
||||
/ {
|
||||
model = "AMX MST701";
|
||||
compatible = "amx,mst701", "fsl,imx53";
|
||||
|
||||
memory@70000000 {
|
||||
device_type = "memory";
|
||||
reg = <
|
||||
0x70000000 0x10000000
|
||||
0xb0000000 0x10000000
|
||||
>;
|
||||
};
|
||||
|
||||
reserved-memory {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
|
||||
gpu_reserved_mem: gpu_mem@76000000 {
|
||||
reg = <0x76000000 0x08000000>;
|
||||
};
|
||||
mxc_sdc_fb_0_legacy: gpu_fbmem@7e000000 {
|
||||
reg = <0x7e000000 0x02000000>;
|
||||
};
|
||||
gpu_graphics_mem_sram: gpu_graphics_mem@1 {
|
||||
reg = <0xf8020000 0x40000>;
|
||||
};
|
||||
};
|
||||
|
||||
aliases {
|
||||
display = &lvds0;
|
||||
lvds0 = &lvds0;
|
||||
};
|
||||
|
||||
sgtlsound: sound {
|
||||
compatible = "fsl,imx53-amxtablet-sgtl5000",
|
||||
"fsl,imx-audio-sgtl5000";
|
||||
model = "imx53-amxtablet-sgtl5000";
|
||||
simple-audio-card,aux-devs = <&speaker_amp>;
|
||||
simple-audio-card,routing =
|
||||
"Headphone Jack", "Speaker Amp OUTR",
|
||||
"Speaker Amp INR", "HP_OUT";
|
||||
ssi-controller = <&ssi2>;
|
||||
audio-codec = <&sgtl5000>;
|
||||
audio-routing =
|
||||
"Headphone Jack", "HP_OUT"
|
||||
;
|
||||
mux-int-port = <2>;
|
||||
mux-ext-port = <5>;
|
||||
};
|
||||
|
||||
speaker_amp: speaker-amp {
|
||||
compatible = "simple-audio-amplifier";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_spkamp>;
|
||||
sound-name-prefix = "Speaker Amp";
|
||||
/* enable-gpios = <&gpio5 2 GPIO_ACTIVE_HIGH>; */ // TODO: I don't know how to link my "imx-audio-sgtl5000" to this amp node (see above)
|
||||
};
|
||||
|
||||
reg_3p2v: regulator-3p2v {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "3P2V";
|
||||
regulator-min-microvolt = <3200000>;
|
||||
regulator-max-microvolt = <3200000>;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
reg_usbotg_vbus: regulator-usbotg-vbus {
|
||||
compatible = "regulator-fixed";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usbotg_reg>;
|
||||
regulator-name = "VCC_USB";
|
||||
regulator-min-microvolt = <5000000>;
|
||||
regulator-max-microvolt = <5000000>;
|
||||
gpio = <&gpio4 15 GPIO_ACTIVE_HIGH>;
|
||||
enable-active-high;
|
||||
};
|
||||
|
||||
reg_usbh1_vbus: regulator-usbh1-vbus {
|
||||
compatible = "regulator-fixed";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usbh1_reg>;
|
||||
regulator-name = "VCC_USB_INT";
|
||||
regulator-min-microvolt = <5000000>;
|
||||
regulator-max-microvolt = <5000000>;
|
||||
gpio = <&gpio2 26 GPIO_ACTIVE_HIGH>;
|
||||
enable-active-high;
|
||||
};
|
||||
|
||||
gpio-poweroff { /* In case you didn't see it, there's power button on the top left of the device. */
|
||||
compatible = "gpio-poweroff";
|
||||
gpios = <&gpio2 15 GPIO_ACTIVE_LOW>;
|
||||
timeout-ms = <3000>;
|
||||
// TODO: pinctrl
|
||||
};
|
||||
|
||||
gpio-leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
system-status {
|
||||
label = "Status";
|
||||
linux,default-trigger = "heartbeat";
|
||||
gpios = <&gpio3 15 GPIO_ACTIVE_HIGH>;
|
||||
// TODO: pinctrl
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&ecspi1 {
|
||||
status = "okay";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_ecspi1>;
|
||||
|
||||
touchscreen0: tsc2046@1 {
|
||||
reg = <1>;
|
||||
|
||||
compatible = "ti,tsc2046";
|
||||
interrupt-parent = <&gpio1>;
|
||||
interrupts = <8 0>;
|
||||
pendown-gpio = <&gpio1 8 GPIO_ACTIVE_LOW>;
|
||||
|
||||
spi-max-frequency = <1000000>;
|
||||
|
||||
wakeup-source;
|
||||
};
|
||||
};
|
||||
|
||||
&ldb {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_lvds0>;
|
||||
status = "okay";
|
||||
|
||||
lvds0: lvds-channel@0 {
|
||||
fsl,data-mapping = "spwg";
|
||||
fsl,data-width = <24>;
|
||||
status = "okay";
|
||||
|
||||
display-timings {
|
||||
native-mode = <&lvds0_timing0>;
|
||||
|
||||
lvds0_timing0: timing-mst701disp {
|
||||
clock-frequency = <48960000>;
|
||||
hactive = <1024>;
|
||||
vactive = <600>;
|
||||
hback-porch = <144>;
|
||||
hsync-len = <104>;
|
||||
hfront-porch = <40>;
|
||||
vback-porch = <18>;
|
||||
vsync-len = <3>;
|
||||
vfront-porch = <1>;
|
||||
hsync-active = <0>;
|
||||
vsync-active = <0>;
|
||||
de-active = <1>;
|
||||
pixelclk-active = <1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&ssi2 {
|
||||
fsl,mode = "i2s-master";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2c1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_i2c1>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2c2 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_i2c2>;
|
||||
status = "okay";
|
||||
sgtl5000: codec@a {
|
||||
compatible = "fsl,sgtl5000";
|
||||
reg = <0x0a>;
|
||||
#sound-dai-cells = <0>;
|
||||
clocks = <&clks IMX5_CLK_SSI_EXT1_GATE>;
|
||||
VDDA-supply = <®_3p2v>;
|
||||
VDDIO-supply = <®_3p2v>;
|
||||
};
|
||||
};
|
||||
|
||||
&i2c3 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_i2c3>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&cpu0 {
|
||||
operating-points = <
|
||||
/* kHz */
|
||||
166666 850000
|
||||
400000 900000
|
||||
800000 1050000
|
||||
1000000 1200000
|
||||
// 1200000 1300000 // SKU does not support 1.2 GHz
|
||||
>;
|
||||
};
|
||||
|
||||
&audmux {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_audmux>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&iomuxc {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_hog>;
|
||||
|
||||
pinctrl_hog: hoggrp {
|
||||
fsl,pins = <
|
||||
MX53_PAD_GPIO_0__CCM_SSI_EXT1_CLK 0x80000000 /* SSI_MCLK */
|
||||
// MX53_PAD_DISP0_DAT8__WDOG1_WDOG_B TODO
|
||||
// MX53_PAD_GPIO_1__PWM2_PWMO
|
||||
// MX53_PAD_GPIO_9__PWM1_PWMO
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_usbotg_reg: usbotgreggrp {
|
||||
fsl,pins = <
|
||||
MX53_PAD_EIM_DA15__GPIO3_15 0x0 /* VBUS_EN */
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_usbh1_reg: usbh1reggrp {
|
||||
fsl,pins = <
|
||||
MX53_PAD_EIM_RW__GPIO2_26 0x0 /* VBUS_EN (ETH) */
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_ecspi1: ecspi1grp {
|
||||
fsl,pins = <
|
||||
MX53_PAD_EIM_D16__ECSPI1_SCLK 0x80000000
|
||||
MX53_PAD_EIM_D17__ECSPI1_MISO 0x80000000
|
||||
MX53_PAD_EIM_D18__ECSPI1_MOSI 0x80000000
|
||||
MX53_PAD_EIM_D19__ECSPI1_SS1 0x80000000
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_audmux: audmuxgrp {
|
||||
fsl,pins = <
|
||||
MX53_PAD_KEY_COL0__AUDMUX_AUD5_TXC 0x80000000
|
||||
MX53_PAD_KEY_ROW0__AUDMUX_AUD5_TXD 0x80000000
|
||||
MX53_PAD_KEY_COL1__AUDMUX_AUD5_TXFS 0x80000000
|
||||
MX53_PAD_KEY_ROW1__AUDMUX_AUD5_RXD 0x80000000
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_spkamp: spkampgrp {
|
||||
fsl,pins = <
|
||||
MX53_PAD_GPIO_12__GPIO4_2 0x0
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_uart1: uart1grp {
|
||||
fsl,pins = <
|
||||
MX53_PAD_PATA_DIOW__UART1_TXD_MUX 0x1e4
|
||||
MX53_PAD_PATA_DMACK__UART1_RXD_MUX 0x1e4
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_esdhc1: esdhc1grp {
|
||||
fsl,pins = <
|
||||
MX53_PAD_SD1_DATA0__ESDHC1_DAT0 0x1d5
|
||||
MX53_PAD_SD1_DATA1__ESDHC1_DAT1 0x1d5
|
||||
MX53_PAD_SD1_DATA2__ESDHC1_DAT2 0x1d5
|
||||
MX53_PAD_SD1_DATA3__ESDHC1_DAT3 0x1d5
|
||||
MX53_PAD_SD1_CMD__ESDHC1_CMD 0x1d5
|
||||
MX53_PAD_SD1_CLK__ESDHC1_CLK 0x1d5
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_fec: fecgrp {
|
||||
fsl,pins = <
|
||||
MX53_PAD_FEC_MDC__FEC_MDC 0x80000000
|
||||
MX53_PAD_FEC_MDIO__FEC_MDIO 0x80000000
|
||||
MX53_PAD_FEC_REF_CLK__FEC_TX_CLK 0x80000000
|
||||
MX53_PAD_FEC_RX_ER__FEC_RX_ER 0x80000000
|
||||
MX53_PAD_FEC_CRS_DV__FEC_RX_DV 0x80000000
|
||||
MX53_PAD_FEC_RXD1__FEC_RDATA_1 0x80000000
|
||||
MX53_PAD_FEC_RXD0__FEC_RDATA_0 0x80000000
|
||||
MX53_PAD_FEC_TX_EN__FEC_TX_EN 0x80000000
|
||||
MX53_PAD_FEC_TXD1__FEC_TDATA_1 0x80000000
|
||||
MX53_PAD_FEC_TXD0__FEC_TDATA_0 0x80000000
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_i2c2: i2c2grp {
|
||||
fsl,pins = <
|
||||
MX53_PAD_KEY_ROW3__I2C2_SDA 0x400001e4
|
||||
MX53_PAD_KEY_COL3__I2C2_SCL 0x400001e4
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_i2c1: i2c1grp {
|
||||
fsl,pins = <
|
||||
MX53_PAD_EIM_D21__I2C1_SCL 0x400001e4
|
||||
MX53_PAD_EIM_D28__I2C1_SDA 0x400001e4
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_i2c3: i2c3grp {
|
||||
fsl,pins = <
|
||||
MX53_PAD_GPIO_6__I2C3_SDA 0x400001e4
|
||||
MX53_PAD_GPIO_5__I2C3_SCL 0x400001e4
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_lvds0: lvds0grp {
|
||||
fsl,pins = <
|
||||
MX53_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3 0x80000000
|
||||
MX53_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK 0x80000000
|
||||
MX53_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2 0x80000000
|
||||
MX53_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1 0x80000000
|
||||
MX53_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0 0x80000000
|
||||
>;
|
||||
};
|
||||
};
|
||||
|
||||
&esdhc1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_esdhc1>;
|
||||
status = "okay";
|
||||
//max-frequency = <25000000>;
|
||||
};
|
||||
|
||||
&uart1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_uart1>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usbotg { /* External USB port */
|
||||
dr_mode = "host";
|
||||
status = "okay";
|
||||
vbus-supply = <®_usbotg_vbus>;
|
||||
};
|
||||
|
||||
&usbh1 { /* USB Ethernet controller */
|
||||
phy_type = "utmi";
|
||||
dr_mode = "host";
|
||||
vbus-supply = <®_usbh1_vbus>;
|
||||
status = "okay";
|
||||
};
|
BIN
linux/sd_card_head.img.zst
Normal file
BIN
linux/sd_card_head.img.zst
Normal file
Binary file not shown.
36
scripts/analyze_iomux.py
Executable file
36
scripts/analyze_iomux.py
Executable file
@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import re
|
||||
import sys
|
||||
|
||||
|
||||
baseaddr=0x53FA8000
|
||||
pinfunc="/home/markus/projects/amx-tablet/linux/arch/arm/boot/dts/nxp/imx/imx53-pinfunc.h"
|
||||
memdump=sys.argv[1]
|
||||
|
||||
|
||||
re_define = re.compile(r'^#define (\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+).*$')
|
||||
|
||||
pinfuncs = {}
|
||||
with open(pinfunc) as file:
|
||||
for line in file:
|
||||
m = re_define.match(line)
|
||||
if m:
|
||||
name = m.group(1)
|
||||
offset = baseaddr + int(m.group(2), 16)
|
||||
mux_mode = int(m.group(5), 16)
|
||||
if not offset in pinfuncs:
|
||||
pinfuncs[offset] = [None] * 8
|
||||
pinfuncs[offset][mux_mode] = name
|
||||
|
||||
|
||||
with open(memdump) as file:
|
||||
for line in file:
|
||||
name = line.split()
|
||||
addr = int(name[0], 16)
|
||||
value = int(name[1], 16)
|
||||
if addr in pinfuncs:
|
||||
mux_mode = value & 7
|
||||
func_str = pinfuncs[addr][mux_mode]
|
||||
func = func_str.split("__")
|
||||
print(f"{func[0]}:\r\t\t\t\t{func[1]}")
|
22
scripts/build.sh
Executable file
22
scripts/build.sh
Executable file
@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
echo "BUILDING KERNEL..."
|
||||
|
||||
IMAGETYPE=zImage
|
||||
LDA=0x70008000
|
||||
|
||||
rm -f zImage-with-dtb uImage-with-dtb
|
||||
make LOADADDR=$LDA $IMAGETYPE dtbs
|
||||
|
||||
cat arch/arm/boot/$IMAGETYPE arch/arm/boot/dts/nxp/imx/imx53-amxtablet.dtb > zImage-with-dtb
|
||||
mkimage -A arm -O linux -T kernel -C none -a $LDA -e $LDA -n "Linux kernel" -d zImage-with-dtb uImage-with-dtb
|
||||
|
||||
|
||||
echo "BUILDING INITRAMFS..."
|
||||
RD_LDA=0x71008000 #+16M from kernel
|
||||
mkimage -n 'Ramdisk Image' -A arm -O linux -T ramdisk -C gzip -d distro/initramfs-lts.cpio -a $RD_LDA initramfs.uImage
|
||||
|
||||
|
||||
#make INSTALL_MOD_PATH=_install modules_install
|
130
scripts/devmem/devmem2.c
Normal file
130
scripts/devmem/devmem2.c
Normal file
@ -0,0 +1,130 @@
|
||||
/*
|
||||
* devmem2.c: Simple program to read/write from/to any location in memory.
|
||||
*
|
||||
* Copyright (C) 2000, Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl)
|
||||
*
|
||||
*
|
||||
* This software has been developed for the LART computing board
|
||||
* (http://www.lart.tudelft.nl/). The development has been sponsored by
|
||||
* the Mobile MultiMedia Communications (http://www.mmc.tudelft.nl/)
|
||||
* and Ubiquitous Communications (http://www.ubicom.tudelft.nl/)
|
||||
* projects.
|
||||
*
|
||||
* The author can be reached at:
|
||||
*
|
||||
* Jan-Derk Bakker
|
||||
* Information and Communication Theory Group
|
||||
* Faculty of Information Technology and Systems
|
||||
* Delft University of Technology
|
||||
* P.O. Box 5031
|
||||
* 2600 GA Delft
|
||||
* The Netherlands
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <ctype.h>
|
||||
#include <termios.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#define FATAL do { fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", \
|
||||
__LINE__, __FILE__, errno, strerror(errno)); exit(1); } while(0)
|
||||
|
||||
#define MAP_SIZE 4096UL
|
||||
#define MAP_MASK (MAP_SIZE - 1)
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int fd;
|
||||
void *map_base, *virt_addr;
|
||||
unsigned long read_result, writeval;
|
||||
off_t target;
|
||||
int access_type = 'w';
|
||||
|
||||
if(argc < 2) {
|
||||
fprintf(stderr, "\nUsage:\t%s { address } [ type [ data ] ]\n"
|
||||
"\taddress : memory address to act upon\n"
|
||||
"\ttype : access operation type : [b]yte, [h]alfword, [w]ord\n"
|
||||
"\tdata : data to be written\n\n",
|
||||
argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
target = strtoul(argv[1], 0, 0);
|
||||
|
||||
if(argc > 2)
|
||||
access_type = tolower(argv[2][0]);
|
||||
|
||||
|
||||
if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) FATAL;
|
||||
printf("/dev/mem opened.\n");
|
||||
fflush(stdout);
|
||||
|
||||
/* Map one page */
|
||||
map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, target & ~MAP_MASK);
|
||||
if(map_base == (void *) -1) FATAL;
|
||||
printf("Memory mapped at address %p.\n", map_base);
|
||||
fflush(stdout);
|
||||
|
||||
virt_addr = map_base + (target & MAP_MASK);
|
||||
switch(access_type) {
|
||||
case 'b':
|
||||
read_result = *((unsigned char *) virt_addr);
|
||||
break;
|
||||
case 'h':
|
||||
read_result = *((unsigned short *) virt_addr);
|
||||
break;
|
||||
case 'w':
|
||||
read_result = *((unsigned long *) virt_addr);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Illegal data type '%c'.\n", access_type);
|
||||
exit(2);
|
||||
}
|
||||
printf("Value at address 0x%X (%p): 0x%X\n", target, virt_addr, read_result);
|
||||
fflush(stdout);
|
||||
|
||||
if(argc > 3) {
|
||||
writeval = strtoul(argv[3], 0, 0);
|
||||
switch(access_type) {
|
||||
case 'b':
|
||||
*((unsigned char *) virt_addr) = writeval;
|
||||
read_result = *((unsigned char *) virt_addr);
|
||||
break;
|
||||
case 'h':
|
||||
*((unsigned short *) virt_addr) = writeval;
|
||||
read_result = *((unsigned short *) virt_addr);
|
||||
break;
|
||||
case 'w':
|
||||
*((unsigned long *) virt_addr) = writeval;
|
||||
read_result = *((unsigned long *) virt_addr);
|
||||
break;
|
||||
}
|
||||
printf("Written 0x%X; readback 0x%X\n", writeval, read_result);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
if(munmap(map_base, MAP_SIZE) == -1) FATAL;
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
19
scripts/flash_sd.sh
Executable file
19
scripts/flash_sd.sh
Executable file
@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
|
||||
patch=uImage-with-dtb
|
||||
rdpatch=initramfs.uImage
|
||||
device=$1
|
||||
echo "Patch $patch/$rdpatch to $device. Sure?"
|
||||
read
|
||||
|
||||
echo "Flashing kernel..."
|
||||
sudo dd if=$patch of=$device bs=512 seek=2048 conv=notrunc
|
||||
|
||||
#echo "Flashing backup kernel..."
|
||||
#sudo dd if=$patch of=$device bs=512 seek=40960 conv=notrunc
|
||||
|
||||
echo "Flashing initrd..."
|
||||
#sudo dd if=$rdpatch of=$device bs=512 seek=34816 conv=notrunc # 2048 + 16*1024*1024/512
|
||||
echo "skipped."
|
||||
|
||||
sync
|
45
scripts/on_target/boot.ld
Normal file
45
scripts/on_target/boot.ld
Normal file
@ -0,0 +1,45 @@
|
||||
__heap_size = 0x80;
|
||||
__stack_size = 0x80;
|
||||
|
||||
MEMORY
|
||||
{
|
||||
ROM (rwx) : ORIGIN = 0x72000000, LENGTH = 0x1000
|
||||
RAM (rwx) : ORIGIN = 0x73000000, LENGTH = 0x1000
|
||||
}
|
||||
SECTIONS
|
||||
{
|
||||
.text :
|
||||
{
|
||||
*(.boot)
|
||||
*(.text)
|
||||
*(.text)
|
||||
*(.rodata*)
|
||||
} > ROM
|
||||
.data :
|
||||
{
|
||||
*(.sbss)
|
||||
*(.data)
|
||||
*(.bss)
|
||||
*(.rela*)
|
||||
*(COMMON)
|
||||
} > RAM
|
||||
|
||||
.heap :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
PROVIDE ( end = . );
|
||||
_sheap = .;
|
||||
. = . + __heap_size;
|
||||
. = ALIGN(4);
|
||||
_eheap = .;
|
||||
} >RAM
|
||||
|
||||
.stack :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_estack = .;
|
||||
. = . + __stack_size;
|
||||
. = ALIGN(4);
|
||||
_sstack = .;
|
||||
} >RAM
|
||||
}
|
10
scripts/on_target/build.sh
Executable file
10
scripts/on_target/build.sh
Executable file
@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
CC=arm-amx-linux-gnueabihf-
|
||||
${CC}gcc -nostdlib -nostartfiles -ffreestanding -T boot.ld -Os -o bootrom.elf main.c
|
||||
#riscv64-elf-objdump -D bootrom.elf
|
||||
${CC}objcopy -O binary bootrom.elf bootrom.bin
|
||||
r2 -A -c 'pdf @ sym._start' -q bootrom.elf
|
||||
|
||||
mkimage -A arm -O linux -T kernel -C none -a 0x80000000 -e 0x80000000 -n "Linux kernel" -d bootrom.bin uImage
|
30
scripts/on_target/main.c
Normal file
30
scripts/on_target/main.c
Normal file
@ -0,0 +1,30 @@
|
||||
#include <inttypes.h>
|
||||
|
||||
#define UART0_BASE 0x53FBC000
|
||||
#define UART0_SR (*((volatile uint32_t *) (UART0_BASE + 0x00)))
|
||||
#define UART0_DR (*((volatile uint32_t *) (UART0_BASE + 0x40)))
|
||||
|
||||
#define UART0_SR_RX_DATA_EMPTY (1 << 0)
|
||||
#define UART0_SR_TX_FULL (1 << 1)
|
||||
|
||||
/*
|
||||
// Set up stack pointer
|
||||
asm("_start:\
|
||||
xor sp, sp, sp;\
|
||||
lui sp, 0x80100;\
|
||||
j main;\
|
||||
");
|
||||
*/
|
||||
|
||||
__attribute__((noreturn)) void _start() {
|
||||
uint8_t state = 0;
|
||||
uint8_t c='a';
|
||||
uint8_t opcode;
|
||||
uint8_t *ptr;
|
||||
uint32_t length;
|
||||
uint32_t sr;
|
||||
|
||||
while (1) {
|
||||
UART0_DR = c++;
|
||||
}
|
||||
}
|
28
scripts/on_target/send_image
Executable file
28
scripts/on_target/send_image
Executable file
@ -0,0 +1,28 @@
|
||||
#!/usr/bin/ckermit
|
||||
# usage: send_image FILE_NAME OFFSET
|
||||
# e.g. send_image output.bin 1F00000
|
||||
|
||||
set port /dev/ttyUSB0
|
||||
set speed 115200
|
||||
set serial 8N1
|
||||
set carrier-watch off
|
||||
set handshake none
|
||||
set flow-control none
|
||||
robust
|
||||
set file type bin
|
||||
set file name lit
|
||||
set rec pack 1000
|
||||
set send pack 1000
|
||||
set window 5
|
||||
set prompt Kermit>
|
||||
|
||||
out \13
|
||||
out loadb
|
||||
out \13
|
||||
#send bootrom.bin
|
||||
send uImage
|
||||
out \13
|
||||
#in 10 ## Start Addr
|
||||
connect
|
||||
quit
|
||||
exit 0
|
21
scripts/open_serial.kermit
Executable file
21
scripts/open_serial.kermit
Executable file
@ -0,0 +1,21 @@
|
||||
#!/usr/bin/ckermit
|
||||
# usage: send_image FILE_NAME OFFSET
|
||||
# e.g. send_image output.bin 1F00000
|
||||
|
||||
set port /dev/ttyUSB0
|
||||
set speed 115200
|
||||
set serial 8N1
|
||||
set carrier-watch off
|
||||
set handshake none
|
||||
set flow-control none
|
||||
robust
|
||||
set file type bin
|
||||
set file name lit
|
||||
set rec pack 1000
|
||||
set send pack 1000
|
||||
set window 5
|
||||
set prompt Kermit>
|
||||
|
||||
connect
|
||||
quit
|
||||
exit 0
|
9
scripts/patch_sd.sh
Executable file
9
scripts/patch_sd.sh
Executable file
@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
patch=$1
|
||||
device=$2
|
||||
echo "Patch $patch to $device. Sure?"
|
||||
read
|
||||
|
||||
sudo dd if=$patch of=$device bs=1 seek=1048576 conv=notrunc
|
||||
sync
|
12
scripts/reinstall_firstrun.sh
Normal file
12
scripts/reinstall_firstrun.sh
Normal file
@ -0,0 +1,12 @@
|
||||
echo "amx-tablet" > /etc/hostname
|
||||
|
||||
pacman-key --init
|
||||
pacman-key --populate archlinux
|
||||
pacman-key --populate archlinuxarm
|
||||
|
||||
pacman -Sy archlinux-keyring archlinuxarm-keyring
|
||||
pacman -Su htop sudo tmux lxde mpv alsa-utils libgpiod bash-completion firmware-imx linux-firmware-qcom
|
||||
|
||||
echo '%wheel ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers
|
||||
|
||||
echo -e "MANUAL TODO:\n\t* Install SSH Keys"
|
11
scripts/reinstall_sd.sh
Executable file
11
scripts/reinstall_sd.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
umount /dev/sdb2
|
||||
|
||||
set -e
|
||||
mkfs.ext4 /dev/sdb2
|
||||
mount /dev/sdb2 /mnt/temp
|
||||
bsdtar -xpf /home/markus/Downloads/ArchLinuxARM-armv7-latest.tar.gz -C /mnt/temp
|
||||
cp -r _install/lib/modules/6.12.0-rc7-00189-ge8bdb3c8be08-dirty /mnt/temp/lib/modules/
|
||||
umount /mnt/temp
|
||||
sync
|
5
scripts/test_patch.sh
Normal file
5
scripts/test_patch.sh
Normal file
@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
dd if=/dev/zero of=test.img bs=1k count=32
|
||||
dd if=/dev/urandom of=random.img bs=1k count=1
|
||||
|
6
scripts/upload_and_flash.sh
Executable file
6
scripts/upload_and_flash.sh
Executable file
@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "Uploading..."
|
||||
scp uImage-with-dtb alarm@amx-tablet:/tmp/uImage
|
||||
echo "Flashing and rebooting..."
|
||||
ssh alarm@amx-tablet 'sudo dd if=/tmp/uImage of=/dev/mmcblk0 bs=512 seek=2048 conv=notrunc; sync; sudo reboot'
|
Loading…
Reference in New Issue
Block a user