有什么错误希望大家指出来,一起学习;
1.详细说明arm有哪几种工作模式,并说明什么情况下进入相应的工作模式运行。
答:
arm 一共有 7 种工作模式:
user(用户):
Mode number :0b10000
正常程序执行的模式;不能切换到其它模式
system(系统):
Mode number :0b11111
属于特权模式;特权模式间可通过寄存器CPSR切换模式
运行具有特权操作的系统任务(基于ARMV4架构及以上)
supervisor(<svc> 管理):
Mode number :0b10011
属于特权模式,也属于异常模式;特权模式间可通过寄存器CPSR切换模式
一种对当前工作系统的保护模式
abort(中止):
Mode number :0b10111
属于特权模式,也属于异常模式;特权模式间可通过寄存器CPSR切换模式
数据中止:段错误的最低层
指令预取中止:是取到非法指令时,在执行阶段发现指令被标记,执行指令中止
undefined(未定义):
Mode number :0b11011
属于特权模式,也属于异常模式;特权模式间可通过寄存器CPSR切换模式
支持硬件协处理器的软件仿真
interrupt(中断):
Mode number :0b10010
属于特权模式,也属于异常模式;特权模式间可通过寄存器CPSR切换模式
被使用于各种中断相应
fast interrupt(快速中断):
Mode number :0b10001
属于特权模式,也属于异常模式;特权模式间可通过寄存器CPSR切换模式
支持告诉数据传输程序或告诉通道程序的执行;
2.简述arm指令和Thumb指令的区别。
答:
(1).arm指令都是32位,Thumb指令都是16位的
(2).arm指令功能强大,绝大多数的指令支持条件执行,eg:mcr;Thumb指令除了跳转指令支持条件执行,其它都不支持
(3).arm指令能访问某些特殊寄存器(cpsr);Thumb指令不能访问
3.简述寄存器R13,R14,R15的用途。
答:
R13(sp):堆栈指针寄存器;用于栈相关操作
R14(lr):连接寄存器;当执行bl子程序调用指令时,lr中得到pc的备份
R15(pc):程序计数器;用于控制程序中指令的执行顺序,其指向下下条指令
内核版本:3.4.24
大家发现什么错误一定要告诉我,大家共同学习了;
########## 内核模块 ###########
1.开发阶段,不能每改一次程序就重新编译一次内核,所以我们通过向内核添加模块的方式调试注:a.编译内核时,出现的警告也不能忽略,可能导致大错误
b.向其添加模块的内核必须是正确编译通过的
2.向内核添加模块,必须:
a.与内核版本有关;不能把写好的模块插入到其它版本的内核中
b.与内核配置相关;不能把写好的模块插入到相同版本不同配置的内核中
抢占式内核(2.6板之后的内核支持):
默认不支持,可配置成支持抢占
抢占式内核响应迅速,并且一个进程意外死在内核里不会影响整个内核
3.代码参考/nfsroot/code/01module
vim Makefile //创建 Makefile
--> LINUX_PATH := /home/musesea/arm_class/smdk6410_lzy/src/linux3.4 //内核所在路径
obj-m += module_test.o //编译模块
prefix ?= /home/musesea/nfsroot
//以下格式是固定的
//涵义:告诉内核的Makefile,模块在这,内核的Makefile 来给你编译,并将生成的文件放在这个目录下
all:
make -C $(LINUX_PATH) M=`pwd` modules
//-C:指定编译路径;
//M=`pwd`:模块所在路径,pwd是命令,显示当前路径;
//modules:内核对于编译模块实现的一个宏
//注意,pwd 上的两个单引号是键盘 Tab 键上面的那个键
clean:
make -C $(LINUX_PATH) M=`pwd` modules clean
//modules clean:内核对于删除模块实现的一个宏
install:
make -C $(LINUX_PATH) M=`pwd` modules_install INSTALL_MOD_PATH=$(prefix)
//modules_install:内核对于安装模块实现的宏
//INSTALL_MOD_PATH=$(prefix):将实现的模块安装到变量prefix 定义的路径下
<-- //INSTALL_MOD_PATH:内核实现的宏
=======================================================================================
= make 之后生成xxx.ko 文件就是模块
= make install 后在本目录和创建的根文件系统目录/lib/modules/3.4.24/extra/都会有一个 .ko 文件
= 开发板在成功挂载根文件系统后,执行 insmod xxx.ko 命令即可插入模块
= 成功插入后,lsmod 查看插入的内核模块,会显示
= module_test1 585 0 - Live 0xbf018000 (O)
= 模块名字 模块大小 没有依赖(有依赖会显示个数,紧接着显示被谁依赖) 模块状态 位置
=======================================================================================
vim module_test1.c //编写练习程序
--> //这两个头文件一上来写上就好,宏和函数经常会用到
#include <linux/init.h>
#include <linux/module.h>
//实现来自modules_test2.c
//使用之前必须声明,以后在写C程序的时候在使用的时侯最好也声明,这样在编译的时候会检测函数参数的正确性
void my_printf(int num);
//规则和添加驱动时一样
static __init int module_test_init(void)
{
printk("hello world!\n");
my_printf(100);
return 0;
}
//类型是定死的,类型void,参数void;代码放在exit段,被保留到程序最后,最后执行,执行完释放
static __exit void module_test_exit(void)
{
printk("Bye bye\n");
}
//在插入模块的时候只执行一次
//insmod xxx.ko
module_init(module_test_init);
//在模块删除时执行
//rmmod xxx.ko
//rmmod xxx
module_exit(module_test_exit);
MODULE_LICENSE("GPL"); //开源规则;必须有这句,下面可有可无
MODULE_AUTHOR("musesea"); //声明作者
MODULE_VERSION("1.0"); //声明版本
MODULE_DESCRIPTION("Class test for module");//声明描述
vim module_test2.c //被上面的函数依赖
--> #include <linux/init.h>
#include <linux/module.h>
//普通的函数实现,相当于C语言中写函数,没有固定格式
void my_printf(int num)
{
printk("nihao module %d\n", num);
}
//模块间标号共享
EXPORT_SYMBOL(my_printf);
<-- MODULE_LICENSE("GPL");
===============================================================
= C语言函数名默认是共享的
= 汇编语言的标号默认是不共享的
= 内核模块函数名默认是不共享的,只有EXPORT_SYMBOL(函数名),才能共享
===============================================================
######### PS #####################################
inclede/linux/ 此目录下的代码一般是平台无关
include/asm/ 此目录下的代码一般是平台相关
include/linux/stat.h 保存的是和权限相关的宏定义
include/linux/moduleparam.h
module_param_named
module_param
module_param_string
module_param_array
###################################################
< 模块参数 >
vim module_test3.c
--> #include <linux/init.h>
#include <linux/module.h>
//insmod xxx.ko xxx(参数)
//与此int main(int argc, char *argv[])比较
//事先声明需传的参数
static int age = 10;
char * name = "zhangsan";
char s[100];//必须事先分配空间
int array[100];
//module_param_named(a, age, int, S_IRUGO);
//S_IRUGO 是文件的权限;宏定义的位置,include/linux/stat.h
//module_param_named(n, name, charp, S_IRUGO);
//默认名字和变量相同
module_param(age, int, S_IRUGO)
//等价于module_param_named(age, age, int, S_IRUGO);
module_param(name, charp, S_IRUGO) //charp 指针类型
//等价于module_param_named(name, name, charp, S_IRUGO);
module_param_string(s, s, 100, S_IRUGO);
//100传入字符串最大长度字节,可以小于100,规定大小为了防止越界
//内核会自动把传入的元素个数放入num
int num;
module_param_array(array, int, &num, S_IRUGO);
static __init int module_test_init(void)
{
printk("hello world!\n");
printk("age = %d\n", age);
printk("name = %s\n", name);
printk("string = %s\n", s);
while(num--)
printk("array[%d] = %d\n", num, array[num]);
return 0;
}
static __exit void module_test_exit(void)
{
printk("Bye bye\n");
}
module_init(module_test_init);
module_exit(module_test_exit);
MODULE_LICENSE("GPL");//开源规则
支持多平台的Assetbundle的应用示例,贴代码,供学习!
这里不同平台的StreamingAssets是不同的,所以我们要写预处理!
using UnityEngine; using System.Collections; public class RunScript : MonoBehaviour { //不同平台下StreamingAssets的路径是不同的,这里需要注意一下。 public static readonly string PathURL = #if UNITY_ANDROID "jar:file://" + Application.dataPath + "!/assets/"; #elif UNITY_IPHONE Application.dataPath + "/Raw/"; #elif UNITY_STANDALONE_WIN || UNITY_EDITOR "file://" + Application.dataPath + "/StreamingAssets/"; #else string.Empty; #endif void OnGUI() { if(GUILayout.Button("Main Assetbundle")) { //StartCoroutine(LoadMainGameObject(PathURL + "Prefab0.assetbundle")); //StartCoroutine(LoadMainGameObject(PathURL + "Prefab1.assetbundle")); StartCoroutine(LoadMainCacheGameObject(PathURL + "Prefab0.assetbundle")); StartCoroutine(LoadMainCacheGameObject(PathURL + "Prefab1.assetbundle")); } if(GUILayout.Button("ALL Assetbundle")) { StartCoroutine(LoadALLGameObject(PathURL + "ALL.assetbundle")); } if(GUILayout.Button("Open Scene")) { StartCoroutine(LoadScene()); } } //读取一个资源 private IEnumerator LoadMainGameObject(string path) { WWW bundle = new WWW(path); yield return bundle; //加载到游戏中 yield return Instantiate(bundle.assetBundle.mainAsset); bundle.assetBundle.Unload(false); } //读取全部资源 private IEnumerator LoadALLGameObject(string path) { WWW bundle = new WWW(path); yield return bundle; //通过Prefab的名称把他们都读取出来 Object obj0 = bundle.assetBundle.Load("Prefab0"); Object obj1 = bundle.assetBundle.Load("Prefab1"); //加载到游戏中 yield return Instantiate(obj0); yield return Instantiate(obj1); bundle.assetBundle.Unload(false); } private IEnumerator LoadMainCacheGameObject(string path) { WWW bundle = WWW.LoadFromCacheOrDownload(path,5); yield return bundle; //加载到游戏中 yield return Instantiate(bundle.assetBundle.mainAsset); bundle.assetBundle.Unload(false); } private IEnumerator LoadScene() { WWW download = WWW.LoadFromCacheOrDownload ("file://"+Application.dataPath + "/MyScene.unity3d", 1); yield return download; var bundle = download.assetBundle; Application.LoadLevel ("Level"); } }
截图: