code style

2019年8月2日 星期五

u-boot arm64 from QEMU

#!/bin/bash
PREFIX="aarch64-linux-gnu-"
arch="arm64"
TOP=`pwd`

UBOOT_SRC_URL="https://ftp.denx.de/pub/u-boot/u-boot-2018.11.tar.bz2"
TOOLCHAIN_SRC_URL="http://releases.linaro.org/components/toolchain/binaries/6.5-2018.12/aarch64-linux-gnu/gcc-linaro-6.5.0-2018.12-x86_64_aarch64-linux-gnu.tar.xz"
BUSYBOX_SRC_URL="http://busybox.net/downloads/busybox-1.23.2.tar.bz2"
KERNEL_SRC_URL="https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.4.8.tar.xz"

UBOOT_DIR="uboot_src"
TOOLCHAIN_DIR="toolchain_src"
BUSYBOX_DIR="busybox_src"
KERNEL_DIR="linux_src"

TOOLCHAIN_PATH="$TOP/$TOOLCHAIN_DIR/bin"

BUSYBOX_PALTFORM="busybox-$arch"
LINUX_PALTFORM="linux-$arch-basic"



download_src(){
if [ -d "$1" ]; then
echo "The $1 has been downloaded"
else
mkdir "$1"
wget -P /tmp/ "$2" && tar $3 "/tmp/`basename $2`" -C "$1" --strip-components=1
fi
}

toolchain() {
download_src $TOOLCHAIN_DIR $TOOLCHAIN_SRC_URL xJf
export PATH=${PATH}:${TOOLCHAIN_PATH}
export ARCH=$arch
export CROSS_COMPILE=$PREFIX
}


uboot() {
download_src $UBOOT_DIR $UBOOT_SRC_URL jxvf
toolchain;
cd "$UBOOT_DIR"
make qemu_arm64_defconfig
make -j4
}


busybox() {
download_src $BUSYBOX_DIR $BUSYBOX_SRC_URL xjf
toolchain;
mkdir -pv $TOP/initramfs
mkdir -pv $TOP/obj/$BUSYBOX_PALTFORM

cd "$BUSYBOX_DIR"
    make mrproper
    make O=$TOP/obj/$BUSYBOX_PALTFORM defconfig
sed -i 's/.*CONFIG_STATIC.*/CONFIG_STATIC=y/' $TOP/obj/$BUSYBOX_PALTFORM/.config
sed -i 's/.*CONFIG_INSTALL_NO_USR.*/CONFIG_INSTALL_NO_USR=y/' $TOP/obj/$BUSYBOX_PALTFORM/.config
sed -i 's/.*CONFIG_FEATURE_PREFER_APPLETS.*/CONFIG_FEATURE_PREFER_APPLETS=y/' $TOP/obj/$BUSYBOX_PALTFORM/.config
sed -i 's/.*CONFIG_FEATURE_SH_STANDALONE.*/CONFIG_FEATURE_SH_STANDALONE=y/' $TOP/obj/$BUSYBOX_PALTFORM/.config
    make clean
    make O=$TOP/obj/$BUSYBOX_PALTFORM -j12 2>&1 | tee  ../busybox_build.log
    make O=$TOP/obj/$BUSYBOX_PALTFORM install

# initramfs
cd $TOP/initramfs
mkdir -pv {bin,sbin,etc/init.d,proc,sys,dev,lib,usr/{bin,sbin}}
cp -av $TOP/obj/$BUSYBOX_PALTFORM/_install/* .

cd dev
sudo mknod -m 660 null c 1 3
sudo mknod -m 622 console c 5 1
sudo mknod -m 622 tty0 c 4 0
ln -sf null tty2
ln -sf null tty3
ln -sf null tty4
cd ..
    #cp -a $TOP/toolchain_src/arm-linux-gnueabihf/libc/* lib

#don't have any space or tab when use EOF to output file
cat << EOF > etc/init.d/rcS
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
echo -e "\nBoot took $(cut -d" " -f1 /proc/uptime) seconds\n"
EOF

    chmod 755 etc/init.d/rcS
    find . -print0 \
        | cpio --null -ov --format=newc \
        | gzip -9 > $TOP/obj/$BUSYBOX_PALTFORM/initramfs-"$BUSYBOX_PALTFORM".cpio.gz
}

initramfs() {
    TOP=`pwd`
    cd $TOP/initramfs/"$BUSYBOX_PALTFORM"

    #find ./ | cpio -o -H newc | gzip > $TOP/obj/initramfs-$BUSYBOX_PALTFORM.cpio.gz

    find . -print0 \
    | cpio --null -ov --format=newc \
    | gzip -9 > $TOP/obj/BUSYBOX_PALTFORM/initramfs-"$BUSYBOX_PALTFORM".cpio.gz
}

kernel() {
download_src $KERNEL_DIR $KERNEL_SRC_URL xJf
toolchain;
# build kernel
cd $TOP
    mkdir -pv obj/"$LINUX_PALTFORM"
    make -C $KERNEL_DIR O=../obj/$LINUX_PALTFORM mrproper
    make  -C $KERNEL_DIR O=../obj/$LINUX_PALTFORM  defconfig
    sed -i 's/.*CONFIG_EXPERIMENTAL.*/CONFIG_EXPERIMENTAL=y/' ../obj/$LINUX_PALTFORM/.config
sed -i 's/.*CONFIG_DEBUG_INFO.*/CONFIG_DEBUG_INFO=y/' ../obj/$LINUX_PALTFORM/.config
sed -i 's/.*CONFIG_KGDB.*/CONFIG_KGDB=y/' ../obj/$LINUX_PALTFORM/.config
sed -i 's/.*CONFIG_KGDB_LOW_LEVEL_TRAP.*/CONFIG_KGDB_LOW_LEVEL_TRAP=y/' ../obj/$LINUX_PALTFORM/.config
sed -i 's/.*CONFIG_FRAME_POINTER.*/CONFIG_FRAME_POINTER=y/' ../obj/$LINUX_PALTFORM/.config
sed -i 's/.*CONFIG_MAGIC_SYSRQ.*/CONFIG_MAGIC_SYSRQ=y/' ../obj/$LINUX_PALTFORM/.config
sed -i 's/.*CONFIG_8139CP.*/CONFIG_8139CP=y/' ../obj/$LINUX_PALTFORM/.config
sed -i 's/.*CONFIG_DEBUG_SET_MODULE_RONX.*/CONFIG_DEBUG_SET_MODULE_RONX=n/' obj/$LINUX_PALTFORM/.config
sed -i 's/.*CONFIG_DEBUG_RODATA.*/CONFIG_DEBUG_RODATA=n/' ../obj/$LINUX_PALTFORM/.config
sed -i 's/.*CONFIG_MODULE_FORCE_LOAD.*/CONFIG_MODULE_FORCE_LOAD=y/' ../obj/$LINUX_PALTFORM/.config
sed -i 's/.*CONFIG_MODULE_UNLOAD.*/CONFIG_MODULE_UNLOAD=y/' ../obj/$LINUX_PALTFORM/.config
sed -i 's/.*CONFIG_MODULE_FORCE_UNLOAD.*/CONFIG_MODULE_FORCE_UNLOAD=y/' ../obj/$LINUX_PALTFORM/.config

cat << EOF >> ../obj/"$LINUX_PALTFORM"/.config
CONFIG_KPROBES_ON_FTRACE=y
CONFIG_UPROBES=y
CONFIG_TRACE_IRQFLAGS=y
CONFIG_TRACER_MAX_TRACE=y
CONFIG_RING_BUFFER_ALLOW_SWAP=y
CONFIG_FTRACE=y
CONFIG_FUNCTION_TRACER=y
CONFIG_FUNCTION_GRAPH_TRACER=y
CONFIG_IRQSOFF_TRACER=y
CONFIG_SCHED_TRACER=y
CONFIG_FTRACE_SYSCALLS=y
CONFIG_TRACER_SNAPSHOT=y
CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP=y
CONFIG_STACK_TRACER=y
CONFIG_UPROBE_EVENT=y
CONFIG_DYNAMIC_FTRACE=y
CONFIG_DYNAMIC_FTRACE_WITH_REGS=y
CONFIG_FUNCTION_PROFILER=y
CONFIG_FTRACE_MCOUNT_RECORD=y
CONFIG_FTRACE_SELFTEST=y
CONFIG_FTRACE_STARTUP_TEST=y
CONFIG_EVENT_TRACE_TEST_SYSCALLS=y
CONFIG_MMIOTRACE=y
CONFIG_PERCPU_RWSEM=y
EOF

yes '' | make -C $KERNEL_DIR O=../obj/$LINUX_PALTFORM oldconfig
make -C $KERNEL_DIR O=../obj/$LINUX_PALTFORM clean
time make -C $KERNEL_DIR O=../obj/$LINUX_PALTFORM -j12 2>&1 | tee kernel_build.log
}


qemu() {
    qemu-system-aarch64 -machine virt -cpu cortex-a53 -nographic -m 2048 \
    -kernel obj/"$LINUX_PALTFORM"/arch/arm64/boot/Image \
    -initrd obj/$BUSYBOX_PALTFORM/initramfs-"$BUSYBOX_PALTFORM".cpio.gz \
    -append "root=/dev/ram rdinit=/sbin/init console=ttyAMA0,115200"
}



initramfs() {
    cd $TOP/initramfs/"$BUSYBOX_PALTFORM"

    #find ./ | cpio -o -H newc | gzip > $TOP/obj/initramfs-$BUSYBOX_PALTFORM.cpio.gz

    find . -print0 \
    | cpio --null -ov --format=newc \
    | gzip -9 > $TOP/obj/$BUSYBOX_PALTFORM/initramfs-"$BUSYBOX_PALTFORM".cpio.gz
}

while true; do
    case "$1" in
-t|--toolchain) toolchain; exit 0;;
-u|--uboot) uboot; exit 0;;
-b|--busybox) busybox; exit 0;;
-i|--initramfs) initramfs; exit 0;;
-k|--kernel) kernel; exit 0;;
        -r|--run) qemu; exit 0;;
        --) shift; break;;
    esac
    shift
done


2019年7月28日 星期日

espressobin boot from UART

ESPRESSObin v7 boot from UART



如果版子上沒有bootloader(u-boot), 可使用UART mode 來recovery.
a. build UART images, they are located in build/a3700/debug/uart-images/ directory:
$ ls build/a3700/debug/uart-images
TIM_ATF.bin  atf-ntim.txt  boot-image_h.bin  wtmi_h.bin

b. 調jump to UART mode, 參考boot modes table


Boot modes - ESPRESSObin v7
ESPRESSObin boot modeJ11J3J10
Serial NOR flash download mode2-32-31-2
eMMC download mode2-31-22-3
eMMC alternate download mode2-31-22-3
SATA download mode2-31-22-3
Serial NAND flash download mode2-31-22-3
UART mode2-31-22-3
MicroSD card2-31-22-3
 c.  open comport from windows and we should  should see the > prompt presented on the HyperTerminal screen. In this terminal, type wtp to switch the BootROM to WTP download mode.
 d.  download the WTPTP tools from extranet
 e. run this command from cmd.exe(-C 38 is your COM number)
>> WtpDownload.exe -P UART -C 38 -R 115200 -B path\to\TIM_ATF.bin -I path\to\wtmi_h.bin -I path\to\boot-image_h.bin -E

f. when you see the "Mavell>>" , use tftp to update bootloader
 set ip address

Marvell>> setenv serverip 192.168.x.x
Marvell>> setenv ipaddr 192.168.x.x
check
Marvell>> ping $serverip
update u-boot

Marvell>> bubt espressobin-bootloader-cpu-1000-ddr3-2cs-1g-atf-ga3306ab-uboot-gaee49fc-20180129-REL.bin
Burning U-BOOT image "espressobin-bootloader-cpu-1000-ddr3-2cs-1g-atf-ga3306ab-uboot-gaee49fc-20180129-REL.bin" from "tftp" to "spi"
Using neta@30000 device
TFTP from server 192.168.10.134; our IP address is 192.168.10.145
Filename 'espressobin-bootloader-cpu-1000-ddr3-2cs-1g-atf-ga3306ab-uboot-gaee49fc-20180129-REL.bin'.
Load address: 0x2000000
Loading: #################################################################
 #################################################################
 #################################################################
 #################################################################
 ##########################
 2.3 MiB/s
done
Bytes transferred = 4194304 (400000 hex)
Image checksum...OK!
SF: Detected w25q32dw with page size 256 Bytes, erase size 4 KiB, total 4 MiB
Erasing 4198400 bytes (1025 blocks) at offset 0 ...Done!
Writing 4194304 bytes from 0x2000000 to offset 0 ...Done!
g. chang jump to "Serial NOR flash download mode"

2019年7月15日 星期一

Bootloader

embedded linux system上, software可分4個層次:
1. 引導加載程序:
是系統上電後運行的第一段code。包括在firmware中的boot code(option)和bootloader兩部分
2.kernel:
包括訂製kernel和啟動參數
3.rootfs:
位於flash上的rootfs.通常用ramdisk來作為rootfs.
4.application:
實際上板子上開發應用的程式

x86主機:
引導加載程序由BIOS(位於flash rom)和位於硬碟的MBR中的OS BootLooader組成(GRUB,LILO..)
系統上電後運行BIOS => 硬體檢測,資源分配 => 將MBR中的 BootLooader由硬碟讀到ram=>
將控制權交給OS BootLoader

embedded linux system的boot loader:
而在嵌入式系統中,通常並沒有像BIOS那樣的程式(注,有的嵌入式CPU也會內嵌一段短小的啟動程序),因此整個系統的加載啟動任務就完全由BootLoader來完成.

比如在一個基於ARM7TDMI core的嵌入式系統中,系統在上電或複位時通常都從地址0x00000000處開始執行,而在這個地址處安排的通常就是系統的BootLoader程序.

簡單地說,BootLoader就是在kernel運行之前運行的一段小程序.通過這段小程序,我們可以初始化硬體設備、建立內存空間的映射圖,從而將系統的軟硬體環境帶到一個合適的狀態,以便為最終調用kernel准備好正確的環境.

啟動過程:
可分為Single Stage和Multi-Stage, 一般flash上使用的是Multi-Stage. 大多是stage1和stage2.
stage1:
硬體設備initial
RAM空間 inital
copy BootLoader 的stage2 到RAM空間中
設置好stack point(sp)
跳轉到stage2的 c entry point

stage2:
硬體設備initial
檢測memory map
將kernel和rootfs從flash中讀到RAM
為kernel設置啟動參數
調用kernel