写在前面
买了很多Linux开发板但是从来没有好好的进行过Linux开发(驱动,应用等)的系统学习。趁着暑假这几天的空闲,捡起一块来进行Linux的系统性学习,在这作为一个记录来记录学习过程和遇到的一些问题。
使用的开发板是旺仔的平地铲D1S开发板,使用芯片为全志Allwinner的F133B,提供的SDK的Linux版本为5.4。前期根据旺仔提供的教程进行开发学习。后续如果使用别的开发板也写在这里吧。
Linux内核的开发
Linux内核程序可以选择作为动态模块加载,这样每次编译内核程序不用替换开发板的内核固件,比较方便。
动态模块开发相关
首先要确保Linux的内核支持动态模块,主要确认的是Kernel Configuration里:
[*]Enable loadable module support
...
[*]Module unloading
将上述内容保存并编译后烧录新的固件到开发板中即可,目前使用的开发板默认配置是开启的。
动态模块程序与编译
先来一个动态模块的程序、编译模板,大概了解一下Linux的动态模块程序该怎么写,Makefile怎么写,怎么启动、怎么退出等。
首先在开发板的Linux源码的drivers下创建目录:ko_test作为模块目录,在这个项目里完整路径为:
/home/zyc/linux_work/d1s/linux-5.4/drivers/ko_test/
然后在这个目录下主要创建两个文件,ko.c和Makefile,一个是程序源文件,一个是编译文件:
// SPDX-License-Identifier: GPL-2.0
/*
* My first linux kernel code.
*
* Copyright (C) 2025 Wangzai 《搞linux的旺仔》
*
* This module serves no practical purpose and is solely for testing purposes.
*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/module.h>
static int __init fcode_init(void)
{
int ret = 0;
/*
* 打印当前函数
*/
pr_info("===> %s running\n", __func__);
return ret;
}
static void __exit fcode_exit(void)
{
pr_info("===> %s running\n", __func__);
}
MODULE_AUTHOR("Piglet");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("This is my first code");
module_init(fcode_init);
module_exit(fcode_exit);
CROSS_PREFIX := ~/linux_work/d1s/riscv64-wangzai-linux-gnu-gcc/bin/riscv64-unknown-linux-gnu-
KERNEL_DIR := ~/linux_work/d1s/linux-5.4/
arch := riscv
obj-m := ko.o
cc := $(CROSS_PREFIX)gcc
ld := $(CROSS_PREFIX)ld
.PHONY:all
all:
make ARCH=$(arch) CC=$(cc) LD=$(ld) -C $(KERNEL_DIR) M=$(shell pwd) modules V=1
.PHONY:clean
clean:
make ARCH=$(arch) CC=$(cc) LD=$(ld) -C $(KERNEL_DIR) M=$(shell pwd) clean
下面对上述的文件内容做一些说明:
首先是ko.c源文件:
其中// SPDX-License-Identifier: GPL-2.0是Linux内核要求的格式。
static int __init fcode_init(void)
{
int ret = 0;
/*
* 打印当前函数
*/
pr_info("===> %s running\n", __func__);
return ret;
}
为动态模块的初始化入口函数,当动态模块被加载,这个函数就会被调用运行。
Comments