X86_QEMU
- build gdb
如果gdb提示:GDB Remote 'g' packet reply is too long
修改gdb/remote.c文件,屏蔽process_g_packet函數中的下列兩行:
#if 0
if (buf_len > 2 * rsa->sizeof_g_packet) {
error(_("Remote 'g' packet reply is too long: %s"), rs->buf);
}
#else
if (buf_len > 2 * rsa->sizeof_g_packet) {
rsa->sizeof_g_packet = buf_len ;
for (i = 0; i < gdbarch_num_regs(gdbarch); i++) {
if (rsa->regs[i].pnum == -1) {
continue;
}
if (rsa->regs[i].offset >= rsa->sizeof_g_packet) {
rsa->regs[i].in_g_packet = 0;
} else {
rsa->regs[i].in_g_packet = 1;
}
}
}
#endif
./configure --prefix=/usr/local/gdb-7.9.1
make -j24
sudo make install
- tftp server
sudo apt-get install tftp-hpa tftpd-hpa
/etc/default/tftpd-hpa
# /etc/default/tftpd-hpa
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/home/shihyu/tftpboot"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="-l -c -s"
mkdir ~/tftpboot
chmod 777 ~/tftpboot
- restart service
sudo service tftpd-hpa restart
- qemu using tftp
#tftp上傳 , 下面操作都是在 qemu shell 執行 command
tftp -p -l init 192.168.100.9
-p:Put file
-l :Local FILE
init:上傳的檔案
192.168.100.9:tftp server的IP
tftp -g -r test.c 192.168.100.9
-g: Get file
-r :Remote FILE
test.c:下載的檔案
192.168.100.9:tftp server的IP
- tftp_get & tftp_push
/ # tftp_push init
init 100% |*******************************| 325 0:00:00 ETA
- x86_build.sh
#! /bin/bash
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/testing/linux-4.3-rc3.tar.xz"
DROPBEAR_SRC_URL="https://matt.ucc.asn.au/dropbear/dropbear-2016.73.tar.bz2"
BUSYBOX="busybox_src"
KERNEL="linux_src"
DROPBEAR="dropbear_src"
BUSYBOX_PALTFORM="busybox-x86"
LINUX_PALTFORM="linux-x86-basic"
usage() {
cat <<USAGE
Usage:
bash $0 <TARGET_PRODUCT> [OPTIONS]
Description:
Builds Android tree for given TARGET_PRODUCT
OPTIONS:
-c, --clean_build
Clean build - build from scratch by removing entire out dir
-d, --debug
Enable debugging - captures all commands while doing the build
-h, --help
Display this help message
-i, --image
Specify image to be build/re-build (bootimg/sysimg/usrimg)
-j, --jobs
Specifies the number of jobs to run simultaneously (Default: 8)
-k, --kernel_defconf
Specify defconf file to be used for compiling Kernel
-l, --log_file
Log file to store build logs (Default: <TARGET_PRODUCT>.log)
-m, --module
Module to be build
-p, --project
Project to be build
-s, --setup_ccache
Set CCACHE for faster incremental builds (true/false - Default: true)
-u, --update-api
Update APIs
-v, --build_variant
Build variant (Default: userdebug)
USAGE
}
clean_build() {
TOP=`pwd`
echo $TOP
mkdir "$BUSYBOX"
mkdir "$KERNEL"
mkdir "$DROPBEAR"
wget -P /tmp/ "$BUSYBOX_SRC_URL" && tar xjf "/tmp/`basename $BUSYBOX_SRC_URL`" -C "$BUSYBOX" --strip-components=1
wget -P /tmp/ "$KERNEL_SRC_URL" && tar xJf "/tmp/`basename $KERNEL_SRC_URL`" -C "$KERNEL" --strip-components=1
wget -P /tmp/ "$DROPBEAR_SRC_URL" && tar xjf "/tmp/`basename $DROPBEAR_SRC_URL`" -C "$DROPBEAR" --strip-components=1
## build busybox
cd $TOP/$BUSYBOX
mkdir -pv ../obj/$BUSYBOX_PALTFORM
make mrproper
make O=../obj/$BUSYBOX_PALTFORM defconfig
sed -i 's/.*CONFIG_STATIC.*/CONFIG_STATIC=y/' ../obj/$BUSYBOX_PALTFORM/.config
sed -i 's/.*CONFIG_INETD.*/CONFIG_INETD=n/' ../obj/$BUSYBOX_PALTFORM/.config
make clean
make O=../obj/$BUSYBOX_PALTFORM -j12 2>&1 | tee ../busybox_build.log
make O=../obj/$BUSYBOX_PALTFORM install
# initramfs
mkdir -p $TOP/initramfs/"$BUSYBOX_PALTFORM"
cd $TOP/initramfs/"$BUSYBOX_PALTFORM"
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
ln -sf null tty2
ln -sf null tty3
ln -sf null tty4
cd ..
# x86_64 lib
cp -a /lib/x86_64-linux-gnu/ lib/
cp -a /lib64/ .
echo "tftp -p -l \$1 192.168.100.9" > bin/tftp_push
echo "tftp -g -r \$1 192.168.100.9" > bin/tftp_get
chmod 755 bin/tftp_push
chmod 755 bin/tftp_get
cd $TOP/initramfs/"$BUSYBOX_PALTFORM"
# root::0:0:root:/:/bin/sh // 不用密碼
# f0409
cat << EOF >>etc/passwd
root:95OnzVR4r6HAM:0:0:root:/root:/bin/sh
EOF
cat << EOF >>init
#!/bin/sh
/sbin/ifconfig lo 127.0.0.1
ifconfig eth0 down
ifconfig eth0 hw ether 08:90:90:59:62:21
ifconfig eth0 192.168.100.5 netmask 255.255.255.0 up
route add default gw 192.168.100.1
mount -t proc none /proc
mount -t sysfs none /sys
mount -t ramfs none /dev
mdev -s
# tty & ssh
mkdir -p /dev/pts
mount -t devpts devpts /dev/pts
dropbear -p 2222
# mount devpts in order to use telnetd
#mkdir /dev/pts
#mount -t devpts devpts /dev/pts
/usr/sbin/telnetd -l /bin/login
echo -e "\nBoot took $(cut -d" " -f1 /proc/uptime) seconds\n"
exec /bin/sh
EOF
chmod +x init
# build dropbear
cd $TOP/$DROPBEAR
./configure --prefix="$TOP"/initramfs/"$BUSYBOX_PALTFORM"
make PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp"
make PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp" install
cd $TOP/initramfs/"$BUSYBOX_PALTFORM"
mkdir -p etc/dropbear
rm -rf share
cd bin
./dropbearkey -t dss -f ../etc/dropbear/dropbear_dss_host_key
./dropbearkey -t rsa -s 1024 -f ../etc/dropbear/dropbear_rsa_host_key
cd ..
find . -print0 \
| cpio --null -ov --format=newc \
| gzip -9 > $TOP/obj/initramfs-$BUSYBOX_PALTFORM.cpio.gz
# build kernel
cd $TOP
mkdir -pv obj/$LINUX_PALTFORM
make -C $KERNEL O=../obj/$LINUX_PALTFORM mrproper
make -C $KERNEL O=../obj/$LINUX_PALTFORM x86_64_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 O=../obj/$LINUX_PALTFORM oldconfig
make -C $KERNEL O=../obj/$LINUX_PALTFORM clean
time make -C $KERNEL O=../obj/$LINUX_PALTFORM -j12 2>&1 | tee kernel_build.log
}
kernel_build() {
make -C $KERNEL O=../obj/$LINUX_PALTFORM clean
time make -C $KERNEL O=../obj/$LINUX_PALTFORM -j12 2>&1 | tee kernel_build.log
}
qemu() {
qemu-system-x86_64 \
-enable-kvm -m 1024 \
-localtime \
-kernel obj/$LINUX_PALTFORM/arch/x86_64/boot/bzImage \
-initrd obj/initramfs-$BUSYBOX_PALTFORM.cpio.gz \
-serial stdio \
-net nic \
-net tap,ifname=tap0,script=no \
-append "root=/dev/ram rdinit=/init console=ttyS0 noapic"
}
gdb() {
qemu-system-x86_64 -s -S \
-kernel obj/"$LINUX_PALTFORM"/arch/x86_64/boot/bzImage \
-initrd obj/initramfs-"$BUSYBOX_PALTFORM".cpio.gz \
-serial stdio \
-append "console=ttyS0"
}
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/initramfs-$BUSYBOX_PALTFORM.cpio.gz
}
while true; do
case "$1" in
-c|--clean_build) clean_build; exit 0;;
-h|--help) usage; exit 0;;
-r|--run) qemu; exit 0;;
-i|--initramfs) initramfs; exit 0;;
-d|--debug) gdb; exit 0;;
-k|--kernel) kernel_build; exit 0;;
--) shift; break;;
esac
shift
done
- nettap.sh
sude ./nettap.sh
tunctl -u shihyu -t tap0
ifconfig tap0 192.168.100.9 up
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -I FORWARD 1 -i tap0 -j ACCEPT
iptables -I FORWARD 1 -o tap0 -m state --state RELATED,ESTABLISHED -j ACCEPT
- hello.c
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
while(1) {
printf("Hello world\n");
sleep(10);
}
return 0;
}
- trace_me.sh
#!/bin/sh
pause() {
read -n 1 -p "$*" INP
if [ "$INP" != '' ] ; then
echo -ne '\b \n'
fi
}
if [ ! -d "/sys/kernel/debug/tracing" ]; then
mount -t debugfs none /sys/kernel/debug
fi
echo nop > /sys/kernel/debug/tracing/current_tracer
echo 16384 > /sys/kernel/debug/tracing/buffer_size_kb
echo 0 > /sys/kernel/debug/tracing/tracing_on
echo > /sys/kernel/debug/tracing/trace
pause 'press any key to start capturing...'
echo function_graph > /sys/kernel/debug/tracing/current_tracer
echo funcgraph-proc > /sys/kernel/debug/tracing/trace_options
echo 1 > /sys/kernel/debug/tracing/tracing_on
./fork
echo "Start recordng ftrace data"
pause "Press any key to stop..."
echo "Recording stopped..."
echo 0 > /sys/kernel/debug/tracing/tracing_on
echo "copying [+]"
time cp /sys/kernel/debug/tracing/trace ~/
echo "copying [-]"
FileDate=`date +%Y%m%d_%H%M%S`
tar zcvf "$FileDate".tar.gz trace
tftp_push "$FileDate".tar.gz
- fork.c
#include <unistd.h>
#include <stdio.h>
int main()
{
fork();
printf("%d\n",getpid());
return 0;
}
cat /sys/kernel/debug/tracing/trace
- Makefile
debug:
@sh build.sh -d
init:
@sh build.sh -i
build:
@sh build.sh -c
qemu:
@sh build.sh -r
- gdb
cgdb ./vmlinux
target remote localhost:1234
b *start_kernel
c