安装编译工具链
sudo apt install gcc-aarch64-linux-gnu
sudo apt install libncurses5-dev build-essential git bison flex libssl-dev
编译busybox
cd ~/busybox-1.31.1/
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
make menuconfig
Settings --->
[*] Build static binary (no shared libs)
make -j$(nproc) && make install
编译内核
cd linux-5.4.34/
make defconfig ARCH=arm64
make menuconfig ARCH=arm64
Kernel hacking --->
Compile-time checks and compiler options --->
[*] Compile the kernel with debug info
[*] Provide GDB scripts for kernel debugging
[*] Kernel debugging
Kernel Features ---->
[] Randomize the address of the kernel image (KASLR)
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
make -j$(nproc)
编写测试文件test.c
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
int main()
{
time_t tt;
struct timeval tv;
struct tm *t;
#if 0
gettimeofday(&tv,NULL);
#else
asm volatile(
"add x0, x29, 16\n\t" //X0寄存器用于传递参数&tv
"mov x1, #0x0\n\t" //X1寄存器用于传递参数NULL
"mov x8, #0xa9\n\t" //使用X8传递系统调用号169
"svc #0x0\n\t" //触发系统调用
);
#endif
tt = tv.tv_sec; //tv是保存获取时间结果的结构体
t = localtime(&tt); //将世纪秒转换成对应的年月日时分秒
printf("time: %d/%d/%d %d:%d:%d\n",
t->tm_year + 1900,
t->tm_mon,
t->tm_mday,
t->tm_hour,
t->tm_min,
t->tm_sec);
return 0;
}
分析系统调用过程
调用el0_sync进入中断程序
kernel_entry函数保存现场
el0_svc
elo_svc_handler通过x8获得系统调用号
__invoke_syscall执行系统调用,这里的syscall_fn就是gettimeofday系统调用