ARM64 架构入门(第三章实验)
ARM64 架构入门
1.在树莓派上安装 Raspberry Pi OS
(1)获取安装文件
下载一个最新的树莓派 OS,国内小伙伴可以从清华开源软件站点下载。
(2)烧录安装文件(与树莓派OpenEuler安装类似)
显示complete则烧录成功
修改 MircoSD 卡中 boot 分区里面的 config.txt 配置文件,在这个文件里新增两行。
uart_2ndstage=1 enable_uart=1
再把bootu盘插到树莓派上,接电即可使用。
树莓派 OS 默认的用户名:pi,密码为:raspberry
注:这里很多同学可能在Putty上登录的时候会出现Network Error问题,这时候只需在boot分区下新建一个文本文件,命名为ssh,并删去后缀名,即可。之后还会出现一个对话框,只需点击是,输入用户,密码就进入我们的树莓派的界面啦~
(3)配置树莓派上的 wifi
(4)更新软件包。
我们最好是全系统的更新软件包,这样会自动更新了 SPI BootRom 固件
sudo apt update sudo apt full-upgrade sudo reboot
至此,Raspberry Pi OS安装完成。
2.汇编语言练习——查找最大数
1.实验目的
通过本实验了解和熟悉ARM64汇编语言
2.实验要求
使用 ARM64 汇编语言来实现如下功能:在给定的一组数中查找最大数。程序可使用
GCC(Aarch64 版本)工具来编译,并且可在树莓派 Linux 系统或者 QEMU + ARM64 实
验平台上运行。(本次实验我在树莓派Linux系统下进行的)
3.实验代码链接
.section .data
.align 3
my_data:
.quad 1
.quad 2
.quad 5
.quad 8
.quad 10
.quad 12
my_data_count:
.quad 6
.align 3
print_data:
.string "big data: %d\n"
.section .text
.global main
main:
stp x29,x30,[sp,-16]!
ldr x0,=my_data
ldr x1,my_data_count
add x4,x0,#40
mov x3,xzr
1:
ldr x2,[x0],#8
cmp x2,x3
csel x3,x2,x3,hi
cmp x0,x4
b.ls 1b
ldr x0, =print_data
mov x1,x3
bl printf
ldp x29,x30,[sp],16
ret
4.编译运行过程
注:输入6个数字,最大数字是12,与最终编译结果相符,运行正确。
5.调试我们可以使用gdb来单步调试汇编程序:
(1)启动gdb来调试test程序
在main函数里设置一个断点,并输入“r”命令运行test程序
然后就可以单步调试 test 程序了。输入“s”进行单步调试。
可以使用“info reg”命令来查看寄存器的值。
3.汇编语言练习——通过C语言调用汇编函数
1.实验目的
通过本实验了解和熟悉 C 语言中如何调用汇编函数。
2.实验平台
在新安装好的树莓派OpenEuler系统下操作的
3.实验代码
compare.S
.section .text .globl compare_data compare_data: cmp x0, x1 csel x0, x0, x1, hi ret
main.c
#include <stdio.h> extern int compare_data(int a, int b); int main() { int val; val = compare_data(5, 6); printf("big data: %d\n", val); }
makefile
main:main.o compare.o gcc -o main main.o compare.o main.o:main.c gcc -c main.c compare.o:compare.S gcc -c compare.S clean: rm main main.o compare.o
4.编译运行
4.汇编语言练习——通过汇编语言调用C函数
1.实验目的
通过本实验了解和熟悉汇编语言中如何调用 C 函数。
2.实验平台
在新安装好的树莓派OpenEuler系统下操作的
3.实验代码
compare.c
int compare_data(int a, int b) { return (a >= b) ? a : b; }
main.S
.section .data .align 3 print_data: .string "big data: %d\n" .section .text .globl main main: stp x29, x30, [sp, -16]! mov x0, #6 mov x1, #5 bl compare_data mov x1, x0 ldr x0, =print_data bl printf ldp x29, x30, [sp], 16 ret
makefile
main:main.o compare.o gcc -o main main.o compare.o main.o:main.S gcc -c main.S compare.o:compare.c gcc -c compare.c clean: rm main main.o compare.o
4.编译运行
5.汇编语言练习——GCC内联汇编
1.实验目的
通过本实验了解和熟悉 GCC 内联汇编的使用。
2.实验平台
在新安装好的树莓派OpenEuler系统下操作的
3.实验代码
#include <stdio.h> static int compare_data(int a, int b) { int val; asm volatile ( "cmp %1, %2\n" "csel %0, %1, %2, hi\n" : "+r" (val) : "r" (a), "r" (b) : "memory"); return val; } int main() { int val; val = compare_data(5, 6); printf("big data: %d\n", val); val = compare_data(6, 4); printf("big data: %d\n", val); }
5.编译运行
6.在树莓派上编写一个裸机程序(参考链接:https://www.lmlphp.com/user/13377/article/item/433984/)
1.实验目的
(1)通过本实验了解和熟悉 ARM64 汇编语言。
(2)了解和熟悉如何使用 QEMU 和 GDB 调试裸机程序。
2.实验要求
(1)编写一个裸机程序并运行在 QEMU 虚拟机中,输出“hello world!”字符串。
(2)把编译好的裸机程序放到树莓派上运行。
3.实验代码
hello.c
#include <linux/init.h> #include <linux/module.h> #include <linux/moduleparam.h> MODULE_LICENSE("Dual BSD/GPL"); static int hello_init(void) { printk(KERN_ALERT"Hello, world\n"); return 0; } static void hello_exit(void) { printk(KERN_ALERT"Goodbye, cruel world\n"); } module_init(hello_init); module_exit(hello_exit);
makefile
ifneq ($(KERNELRELEASE),) obj-m := hello.o else KDIR := /home/hcx/work/boards/RPi/kernel/linux-rpi-3.6.y all: make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=/home/hcx/work/boards/RPi/kernel/RpiTools/arm-bcm2708/arm-bcm2708hardfp-linux-gnueabi/bin/arm-bcm2708hardfp-linux-gnueabi- clean: rm -f *.ko *.o *.mod.o *.mod.c *.symvers modul* endif
4.编译运行