CSS Styles

Tuesday, May 11, 2021

Linux - Kernel Version

Source

# Extract
 gzip -dc ../initrd.gz | cpio -idmv --no-absolute-filenames

# Rebuild
 find . | cpio -o -H newc | gzip -9 > ../initrd.gz

XZ Base (Redhat)

# Extract
 xz -dc ../initrd.img | cpio -idmv --no-absolute-filenames

# Rebuild
 find . | cpio -o -H newc | xz -9 > ../initrd.img

Other Distros

Kernel 目錄下 Makefile 的前幾行, 記錄著版本資訊。
以下面的內容為例, 其版本號碼為 2.6.36.2。

 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 36
 EXTRAVERSION = .2

Friday, May 7, 2021

Linux chroot - Active Firmware Image Update

In embedded system firmware update for active image requires additional process to accomplish it. To save the cost and maximize the usage of non-volatile memory, the content of flash is not fully loaded into RAM, instead is used at runtime, so called MTD (Memory Technology Device) in Linux. Since MTD is in use and supposedly not to be changed arbitrarily unless disconnected from all tasks and not accessible further.

Here comes an example which BMC updates the active image itself under Linux console with AMI based firmware.


Copy Firmware to Target

wget <URL>/<firmware> -P /tmp # under BMC console in this case
Any methods which can copy file to target, says ftp, sftp, tftp, scp, rsync, ssh, nc, native or cloud files sharing.

Commands under Target Console

Ensure root privilege (option)

id uid=0(root) gid=0(sysadmin) groups=0(sysadmin)

Identify firmware active image number (option)

method 1 (The booted image number is at the end of output line)
cat /proc/cmdline root=/dev/mtdblock3 ro ip=none mem=496M console=ttyS4,115200 rootfstype=cramfs bigphysarea=8192 bootlogo=2b80040 imagebooted=1

method 2 (AMI IPMI OEM command to read the active image number)
ipmitool -H 127.0.0.1 -U admin -P admin raw 0x32 0x8f 7 1

Stop tasks which may interfere process as possible (not required for inactive image)

for i in ad av c d ext fl hd ipm l mc pa procp redf redisr rm rs sy ti ua up vm; do
  for j in /etc/init.d/$i*; do [ -e $j ] && $j stop; done
done
killall udhcpc dhcp6c
Ignore tasks which are protected and can't be stopped, see if everything OK or not.

Build root filesystem in RAM and switch to it (not required for inactive image)

mkdir -p /tmp/rootfs/usr
cd /tmp/rootfs
cp -a /bin /sbin /lib /tmp .
cp -a /usr/bin /usr/sbin /usr/lib /usr/local usr
for i in dev sys var proc etc run; do mkdir -p $i; mount --rbind /$i $i; done
chroot /tmp/rootfs /bin/bash

Update firmware through MTD interface (tools may be diffrent on other platforms)

method 1 (flash_erase + dd)
flash_erase /dev/mtd0 0 1024 # 64KB/block, 1024*64KB=64MB, quicker than mtd_debug
dd if=/tmp/<firmware> of=/dev/mtd0 bs=1M seek=0

method 2 (mtd_debug)
f=/tmp/<firmware>
mtd_debug erase /dev/mtd0 0 0x4000000 # 3~5 mins or even longer, platform dependent
mtd_debug write /dev/mtd0 0 `stat -c%s $f` $f
In this case of 64MB firmware image size, 0x0000000 is the 1st image offset and 0x4000000 is the 2nd image offset.

Reboot

reboot # shutdown -rfn now
Booting from which image is determined by boot policy.
AMI IPMI OEM command can specify booting image number, example for image number 1: raw 0x32 0x8f 1 1.


Sunday, May 2, 2021

Linux - Device-to-Bus Mapping

Block Device Bus



ls -l /sys/block



Net Device Bus



ls -l /sys/class/net



IPMI Device Bus



ls -l /sys/class/ipmi



Other Device Buses



Most links of devices can be found under /sys/class.

Thursday, April 29, 2021

Linux initrd - Customization

Extraction -> Customization -> Rebuilding

- commands issued under the temporary working directory.
- switch to root if required like mknod needs privilege.

GZ Based (Debian)

Extraction

gzip -dc ../initrd.gz | cpio -idmv --no-absolute-filenames

Rebuilding

find . | cpio -o -H newc | gzip -9 > ../initrd.gz

XZ Based (Redhat)

Extraction

xz -dc ../initrd.img | cpio -idmv --no-absolute-filenames

Rebuilding

find . | cpio -o -H newc | xz -9 > ../initrd.img

Other Distros

Analyze file format then do extraction and rebuilding accordingly.


Monday, April 19, 2021

Network - BMC as a Router

vNIC  virtual NIC over USB created by BMC FW, says AMI MegaRAC
<==>  ip forward and iptables

BMC Setup


Basic Configuration

nicip() { i=`ip a s dev $1 | grep "inet "`; i=${i/*inet }; echo ${i%% *}; }
bwan=eth0 # bmc wan to network
blan=usb0 # bmc lan to host
bwanip=`nicip $bwan` # bmc wan ip/prefix
blanip=`nicip $blan` # bmc lan ip/prefix
hosti=`{ i=${blanip%/*}; [ ${i##*.} = 1 ] && j=2 || j=1; echo ${i%.*}.$j; }` # referred host ip


Routing Option - Simple, implicit rules (ephemeral ports) unsupported

echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o $bwan -j MASQUERADE


Routing Option - Full, works for tftp

bwani0=<ip in same $bwanip domain> # 2nd bmc wan ip, assigned manually
echo 1 > /proc/sys/net/ipv4/ip_forward
ip a a $bwani0/${bwanip#*/} dev $bwan
iptables -t nat -A POSTROUTING -j SNAT -s $hosti --to $bwani0
iptables -t nat -A PREROUTING -j DNAT -d $bwani0 --to $hosti


# optional domain check

ipa2d() { i=${1%/*} n=; for j in 24 16 8 0; do n=$((n+${i%%.*}*2**j)); i=${i#*.}; done; echo $n; }
msk2d() { echo $((2**32-2**(32-${1#*/}))); }
dom2d() { echo $((`ipa2d $1` & `msk2d $1`)); }
[ `dom2d $bwanip` = `dom2d $bwani0/${bwanip#*/}` ] || echo different domain


# optional function to convert prefix to address

prefix2addr() {
 n=${1#*/} s=
 for i in 0 1 2 3; do d=8; [ $n -lt 8 ] && d=$n; s=$s$((256-2**(8-d))).; n=$((n-d)); done
 echo ${s%.}
}
prefix2addr $blanip


Host Setup


Generic Configuration (values are environment and requirement dependent)

namevaluenotes
niceth0NIC name in UEFI, could be different in OS 
ip169.254.0.1host IP address, refer to $hosti in BMC 
prefix16host subnet mask in prefix notation, refer to ${blanip#*/}in BMC
netmask255.255.0.0host subnet mask in address notation, refer to prefix2addr $blanip
gateway169.254.0.17host gateway address, refer to ${blanip%/*} in BMC
dns8.8.8.8Google DNS


U-Boot

setenv ethact eth0
setenv ipaddr 169.254.0.1
setenv gatewapip 169.254.0.17
setenv netmask 255.255.0.0
setenv dnsip 8.8.8.8


UEFI Shell

ifconfig -s eth0 static 169.254.0.1 255.255.0.0 169.254.0.17 dns 8.8.8.8


UEFI Grub2 (requires cdc_ether supported)

net_add_dns 8.8.8.8
net_add_route default 0.0.0.0/0 gw 169.254.0.17
net_add_addr eth0 efinet0 169.254.0.1


Linux based OS

nic=`ls /sys/bus/usb/drivers/cdc_ether/*/net` # host nic to bmc

: ' # may be required in Redhat based distros
sudo nmcli con down $nic >&/dev/null # get rid of NetworkManager control
sudo systemctl stop NetworkManager
sudo systemctl stop firewalld # get rid of firewall control
'

sudo ip addr add 169.254.0.1/16 dev $nic
sudo ip link set $nic up
sudo ip route add default via 169.254.0.17
sudo sh -c "echo nameserver 8.8.8.8 >> /etc/resolv.conf"

Monday, March 13, 2017

【DOS】VBS Extension

相對於 *nix, DOS 功能簡陋, 拼拼湊湊勉強堪用, 進階處理著實捉襟見肘, 令人苦惱。 以數值計算為例, 僅提供 32-bit 有號整數, 不支援浮點; 還好 DOS 可以輕易呼叫 VBS (Visual Basic Script), 讓缺憾得以彌補。

以下短短不起眼指令, 讓 DOS 盡情揮灑 VBS 的能力:

eval.vbs 檔案內容

 WScript.Echo Eval(WScript.Arguments.Item(0))

DOS Prompt 下呼叫 eval.vbs

 cscript eval.vbs "Sin(1)"
 0.841470984807897


DOS 批次檔中調用 eval.vbs

 for /F %%i in ('cscript eval.vbs "Sin(1)"') do set r=%%i
r = returned VBS result

Friday, February 24, 2017

【DOS】String - Lowercase

lowercase 不像 uppercase 擁有美麗巧合, 無法與 find 或其它指令擦出火花, 只能土法練鋼。 DOS 基本指令中皆未含字碼轉換能力, 所以最快的方法就是查表法。

:LOWERCASE
 set r=
 set "i=%~1"
 set tab=AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz
:LRC1
 if "%i%" == "" exit /b
 set c=%i:~0,1%
 if "%c%" GEQ "A" if "%c%" LEQ "Z" call set c=%%tab:*%c%=%%& set c=%c:~0,1%
 set r=%r%%c%
 set i=%i:~1%
 goto :LRC1
r = returned uppercase string