From 3f916a0cf7b2516e3eaa720a5c77efbe53527eeb Mon Sep 17 00:00:00 2001 From: pepepper Date: Thu, 14 Oct 2021 01:23:15 +0900 Subject: [PATCH] Ready for use --- .gitignore | 2 ++ Makefile | 15 +++++++++ README.md | 13 +++++++ extract.py | 34 +++++++++++++++++++ main.S | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 163 insertions(+) create mode 100644 .gitignore create mode 100755 Makefile create mode 100755 extract.py create mode 100755 main.S diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7bbed04 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.elf +*.bin diff --git a/Makefile b/Makefile new file mode 100755 index 0000000..eb10adc --- /dev/null +++ b/Makefile @@ -0,0 +1,15 @@ +CROSS_COMPILE:=arm-linux-gnueabihf- +AS:=$(CROSS_COMPILE)as +CC:=$(CROSS_COMPILE)gcc +STRIP:=$(CROSS_COMPILE)strip + +.PHONY: +all: AppMain.bin + +.PHONY: +clean: + @rm -f *.bin *.elf + +AppMain.bin: + @$(AS) main.S -o main.elf + @./extract.py -p main.elf AppMain.bin diff --git a/README.md b/README.md index 39cfeeb..6f8a17c 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,15 @@ # boot4u U-Boot loader for PW-x1 + +# Build + +```sh +apt install gcc-arm-linux-gnueabihf +pip3 install pyelftools +make +``` + +# Run + - Create a directory `/path/to/sd/APP/foo` + - Create index.din `touch /path/to/sd/APP/foo/index.din` + - Copy and rename the raw executable `cp AppMain.bin /path/to/sd/APP/foo/AppMain.bin` diff --git a/extract.py b/extract.py new file mode 100755 index 0000000..8432ceb --- /dev/null +++ b/extract.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 + +import sys +from elftools.elf.elffile import ELFFile # pip install pyelftools + + +def main(): + if len(sys.argv) < 3: + print(f'Usage: {sys.argv[0]} in.elf out.bin') + sys.exit(1) + + with open(sys.argv[-2], 'rb') as f: + extract(ELFFile(f)) + + +def extract(elf): + text = elf.get_section_by_name('.text') + if text is None: + print('Input ELF has no .text section', file=sys.stderr) + sys.exit(1) + + with open(sys.argv[-1], 'wb') as f: + if '-p' in sys.argv: + print(f'Pure .text mode is enabled') + f.write(text.data()) + else: + elf.stream.seek(0) + elf.stream.read(text.header.sh_offset) + f.write(elf.stream.read()) + + print(f'Successfully extracted the necessary sections to "{sys.argv[2]}"') + + +main() diff --git a/main.S b/main.S new file mode 100755 index 0000000..eedac97 --- /dev/null +++ b/main.S @@ -0,0 +1,99 @@ +.text + .align 4 + .global _start + +_start: +//preload U-Boot from sd + ldr r4, =0x60006400 //fopen addr + adr r0, [.LC0] //file name + adr r1, [.LC1] //open mode + blx r4 + add r5, r4, #0xc //fread addr + mov r3, r0 //file descriptor + ldr r0, =0x37500000 //fread destination + mov r1, #1 //read unit size + mov r2, r0 //read unit count(over size) + blx r5 + bl continue //to avoid strings address exceeds pc relative offset limit + + .LC0: + .ascii "SD0:\\u-boot.bin\000" + .LC1: + .ascii "r\000" +.align 4 + continue: + cpsid if //disable interrupt + +//copy U-Boot to head of RAM + ldr r3, =0x37500000 //copy start + ldr r1, =0x37540000 //copy end + copy_loop: + mov r2, r3 + sub r3, r3, #0x7500000 //copy distination + ldr r0, [r2], #4 + cmp r2, r1 + str r0, [r3] + mov r3, r2 + bne copy_loop + +//RAM clear + ldr r2,=0x60200000 //clear start + ldr r3,=0x68000000 //clear end + sub r3,r3,#4 + eor r1,r1,r1 + clear_loop: + cmp r2,r3 + str r1,[r2],#4 + beq clear_loop + + ldr r0, =0x60000000 + + mrc p15, 0, r8, c14, c2, 1 + bic r8, r8, #1 + mcr p15, 0, r8, c14, c2, 1 + mrc p15, 0, r8, c14, c3, 1 + bic r8, r8, #1 + mcr p15, 0, r8, c14, c3, 1 + + mov r9, #0 + mrc p15, 0, r6, c1, c0, 0 + bic r6, r6, #4 @ disable dcache + bic r6, r6, #4096 @ disable icache + mcr p15, 0, r6, c1, c0, 0 // write ctrl regs + + mcr p15, 0, r9, c7, c5, 0 // invalidate icache + + // from: https://www.aps-web.jp/academy/ca/229/#i-2 + mov r10,#0 // データキャッシュを選択 + mcr p15,2,r10,c0,c0,0 // キャッシュサイズ選択レジスタ(CSSELR)で + // データキャッシュを選択 + isb // 命令同期バリア命令で再フェッチ + mrc p15,1,r1,c0,c0,0 // CCSIDRを読み込み + and r2,r1,#7 // キャッシュラインサイズを取得(b001=8ワード/ライン) + add r2,r2,#4 // DCISWレジスタのセット番号のシフト数を求める + ldr r4,=0x3FF // 最大ウェイ数マスク設定値を設定 + ands r4,r4,r1,LSR #3 // r4レジスタにウェイ数を設定 + clz r5,r4 // DCISWレジスタのウェイ番号のシフト数を求める + ldr r7,=0x7FFF // セット数マスク設定値を設定 + ands r7,r7,r1,LSR #13 // r7レジスタにセット数を設定 + // 0x7F=12Kbyte/0xFF=32Kbyte/0x1FF=64Kbyte + loop2: + mov r9,r4 // r9レジスタにウェイ数を設定 + loop3: + orr r11,r10,r9,LSL r5 // ウェイ番号とキャッシュ番号を設定 + orr r11,r11,r7,LSL r2 // セット番号を設定 + mcr p15,0,r11,c7,c6,2 // DCISWレジスタでセット/ウェイによる + // データキャッシュラインの無効化 + subs r9,r9,#1 // ウェイ番号を-1 + bge loop3 // ウェイ毎の初期化を実施 + subs r7,r7,#1 // セット番号を-1 + bge loop2 // セット毎の初期化を実施 + + mcr p15, 0, r9, c8, c7, 0 // invalidate TLB + mcr p15, 0, r9, c7, c5, 6 // invalidate branch predictor array + + bic r6, r6, #1 @ disable MMU + mcr p15, 0, r6, c1, c0, 0 // write ctrl regs + + bx r0 +