xxx.c为C文件
xxx.S为汇编原文件
0.arm-linux-gcc -c -o xxx.o xxx.c
1.arm-linux-gcc -c -o xxx.o xxx.S
2.arm-linux-ld Ttext 0 xxx.o -o xxx.elf
3.arm-linux-objcopy -O binary -S xxx.elf xxx.bin
4.将生成的.bin文件,复制回Windows目录中;
5.打开命令行CMD,CD bin文件所在目录,oflash xxx.bin
Make [目标];(若无目标指定,指定第一个目标)
目标:依赖源…(可为多个)
[TAB]命令
若目标不存在,或者依赖源有更新,则执行命令。
.PHONY:[目标],可以使目标变为虚拟目标,不受同名文件影响。
Makefile通配符:
1.$@:目标
2.$^:所有依赖文件
3.$<:第一个依赖文件
4.*.x:所有类型.x的文件
赋值:
:= 及时生效
= 延时生效(被调用了才生效)
?= 延时生效,且如果是第一次定义才生效
+= 附加(取决于原先定义)
bootloarer相关:
u-boot 是bootloader的其中一种(类似于Windows的Bios),初始化硬件设备、建立内存空间映射图,从而将系统的软硬件环境带到一个合适状态,最终目的:启动内核。
u-boot需要达到的功能
1.读写Flash->读出内核
2.初始化SDRAM、硬件相关初始化->将Flash内容写到SDRAM、配置时钟、接口
3.启动内核
u-boot编译相关步骤
1.解压u-boot 例如: tar xjf xxxxx.bz2
2.进相应目录打补丁 例如:patch -p1 <../xxxx.patch
3.配置(支持哪种单板) 例如:
4.编译
5.将u-boot.bin oflash进开发板
内核启动、及编译相关
内核的目的:启动运行应用程序(App位于根文件系统中)。
例如:内核怎么启动初始化应用程序BusyBox:
1.sys_open (dev/console or dev/none) //打开一个设备
2.init -> busybox // sbin/init
3.run_init_process(); // etc/inittab
4.运行配置文件中指定的应用程序
5.各类库文件
1.解压内核文件 例:tar xjf xxxx.bz2
2.进相应目录打补丁 例:patch -p1 <../xxxx.patch
3.配置->{ 1.可以直接make menuconfig (从头逐项配置)
2.可以使用默认配置
( 2.1.先找到配置文件xxx_defconfig;(find -name "*defconfig")
2.2.make xxx_defconfig(结果保存在.config);
2.3.make menuconfig(在之前.config基础上配置) )
3.使用厂家提供配置
4.编译 例:make uImage->{ 1. .config生成autoconfig.h
2. 生成aotu.config
5.烧写uImage进单板 例:先让单板准备读USB,用dnw软件通过usb烧写
最小根目录系统
如何创建一个最小的根目录系统:
1.dev/conselo,dev/none
2.init (busybox)
3.inittab
4.配置要启动应用程序
5.C库
udev机制
udev机制:可以自动创建dev/设备节点
0.参考Busybox现成的mdev.txt
1.mount -t sysfs sysfs /sys(在系统目录)
2.修改etc/fstab,修改etc/init.d/rcS
3.编译映像文件(yaffs2、jffs2);
4.烧录
NFS
NFS:(免烧录,从服务器挂载系统)
A.从Flash上启动根文件系统,再用命令挂接NFS
B:直接从NFS启动(
需提前配置参数:(可以参考内核的nfsroot.txt)
1.服务器IP及目录、本身的IP等等)
例如:set bootargs noinitrd root=/dev/nfs nfsroot=服务器IP:/work/nfs_root/文件目录 ip=本机IP:服务器IP:网关:子网掩码::设备(eth0):off init=/linuxrc console=ttySAC0
应用程序如何驱动内核
应用层->引发SWI软中断->异常处理函数->内核函数->驱动硬件
1.编写驱动文件&Makefile,编译(make)
2.传入单板,insmod xxx.ko (相关:lsmod\rmmod)
3.查看是否挂载成功 (cat /proc/devices)
第一个字符驱动程序
//驱动程序
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/arch/regs-gpio.h>
#include <asm/hardware.h>
static struct class *firstdrv_class;
static struct class_device *firstdrv_class_dev;
volatile unsigned long *gpfcon = NULL;
volatile unsigned long *gpfdat = NULL;
static int first_drv_open(struct inode *inode,struct file *file)
{
//printk("first_drv_open\n");
/*配置GPF4\5\6为输出*/
*gpfcon &= ~((0x3<<(4*2)) | (0x3 <<(5*2)) | (0x3 <<(6*2)));//清零
*gpfcon |= ((0x1<<(4*2)) | (0x1 <<(5*2)) | (0x1 <<(6*2)));
return 0;
}
static ssize_t first_drv_write(struct file *file,const char __user *buf,size_t count,loff_t *ppos)
{
int val;
copy_from_user(&val,buf,count);//把用户程序的变量复制到内核空间
//copy_to_user() 内核到用户程序
if(val == 1)
{
//点灯
*gpfdat &= ~((1<<4) | (1<<5) | (1<<6));
}
else
{
*gpfdat |= ((1<<4) | (1<<5) | (1<<6));
}
//printk("first_drv_write\n");
return 0;
}
/*应用层的open和write在这里被对应为first_drv_xxx函数*/
static struct file_operations first_drv_fops = {
.owner = THIS_MODULE,
.open = first_drv_open,
.write = first_drv_write,
};
int major;
static int first_drv_init(void) //由82行module_init宏告诉内核,这是入口函数
{
/*告诉内核,注册这些成员(接口)*/
major = register_chrdev(0,"first_drv", &first_drv_fops);
firstdrv_class = class_create(THIS_MODULE, "firstdrv_class");//先创建一个类
// if (IS_ERR(firstdrv_class))
// return PTR_ERR(firstdrv_class);
//再创建一个device
firstdrv_class_dev = class_device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xyzy"); /*会创建/dev/xyzy */
// if (unlikely(IS_ERR(firstdrv_class_dev)))
// return PTR_ERR(firstdrv_class_dev);
gpfcon = (volatile unsigned long *)ioremap(0x56000050,16);//(起始,长度)
gpfdat = gpfcon + 1;
return 0;
}
static void first_drv_exit(void)//由83行module_exit宏告诉内核,这是出口函数
{
unregister_chrdev(major,"first_drv");
class_device_unregister(firstdrv_class_dev);//删除设备
class_destroy(firstdrv_class);//删除该类
iounmap(gpfcon);
iounmap(gpfdat);
}
module_init(first_drv_init);
module_exit(first_drv_exit);
MODULE_LICENSE("GPL");
//应用层测试程序
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
/* firstdrvtest on打开
* firstdrvtest off关闭
* argv[0] argv[1]
*/
int main(int argc,char **argv)
{
int fd;
int val = 1;
fd = open("/dev/xyzy",O_RDWR);
if(fd < 0)
{
printf("cant open!\n");
}
if(argc != 2)//程序名+一个参数
{
printf("Usage:\n");
printf("%s <on|off>\n",argv[0]);//打印第一个参数(程序名)
return 0;
}
if(strcmp(argv[1],"on") == 0)//==on
{
val = 1;
}
else
{
val = 0;
}
write(fd, &val, 4);
return 0;
}