程序的编译\链接\下载,及Makefile\bootloader相关


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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值