Linux启动流程
驱动(程序) : 驱使设备行动的程序
1. 启动bootloader---引导操作系统启动的(裸机)程序,为操作系统启动准备环境,并引导操作系统启动
2. 启动kernel---操作系统核心 (俗称的操作系统)
3. 加载根文件系统---一堆文件的集合(根目录下的文件)
存储分类 | ||||
---|---|---|---|---|
RAM(随机存储) |
SRAM
静态
|
DRAM 动态 |
SDRAM 同步动态 |
SDR(DDR2\3\4\5) |
ROM(只读存储) |
PROM
可编程
|
EPROM 可擦除 |
EEPROM文章来源:https://www.toymoban.com/news/detail-817487.html 电子可擦除文章来源地址https://www.toymoban.com/news/detail-817487.html |
Bootloader
:一个裸机程序
|
Kernel
:一个复杂的程序
|
根文件系统:一堆文件的集合
|
uboot ------ booloader
初始
CPU(
工作模式
)
初始化异常向量表
初始化栈
初始化时钟
初始化内存
关看门狗
关闭
Cache
初始相关外设
集成相关的协议
搬移
kernel
到内存
向内核传参
(
根文件系统类型
/
位
置
/init
进程
/
内核启动阶段使用
ip/
调试串口
)
引导
kernel
启动
(
设置
PC
)
—
(bootloader
从此不再控制
cpu
cpu
的控制权彻底移交
kernel)
|
内存管理
文件管理
进程管理
网络管理
设备管理
启动到最后阶段时加载
(
挂载的
形式
)
根文件系统
先启动
init
进程
- > shell -> app
|
配置文件
系统命令
(
程序
)
库文件
(
动
/
静态库
)
用户程序
普通文件
(
文本
/mp3/
图片
)
|
内核编译:
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/cdev.h>
#include <asm/string.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <linux/miscdevice.h>
#include <linux/interrupt.h>
#include <linux/irqreturn.h>
#include <linux/wait.h>
#include <linux/sched.h>
#define MAJOR_NUM 251
#define MINOR_NUM 0
#define DEV_NAME "adc"
#define ADCCON 0x58000000
#define ADCDAT0 0x5800000C
#define CLKCON 0x4C00000C
static volatile unsigned long * adccon;
static volatile unsigned long * adcdat0;
static volatile unsigned long * clkcon;
static wait_queue_head_t wq;
static unsigned int condition = 0;
static irqreturn_t irq_handler(int num, void * arg)
{
printk("irq_handler num = %d\n", num);
condition = 1;
wake_up_interruptible(&wq);
return IRQ_HANDLED;
}
static int init_adc(void)
{
*adccon = (1 << 14) | (49 << 6);
return 0;
}
static int adc_start(void)
{
*adccon |= (1 << 0);
return 0;
}
static unsigned short adc_read(void)
{
unsigned short adc_value = *adcdat0 & 0x3ff;
return adc_value;
}
static int open(struct inode * node, struct file * file)
{
init_adc();
printk("adc open ...\n");
return 0;
}
static ssize_t read(struct file * file, char __user * buf, size_t len, loff_t * loff)
{
unsigned short data = 0;
printk("adc read start ...\n");
condition = 0;
adc_start();
wait_event_interruptible(wq, condition);
data = adc_read();
copy_to_user(buf, &data, sizeof(data));
printk("adc read end ...\n");
return sizeof(data);
}
static ssize_t write(struct file * file, const char __user * buf, size_t len, loff_t * loff)
{
return 0;
}
static int close(struct inode * node, struct file * file)
{
printk("adc close ...\n");
return 0;
}
static struct file_operations fops =
{
.owner = THIS_MODULE,
.open = open,
.read = read,
.write = write,
.release = close
};
static struct miscdevice misc_dev =
{
.minor = MISC_DYNAMIC_MINOR,
.name = DEV_NAME,
.fops = &fops
};
static int __init adc_init(void)
{
int ret = 0;
ret = misc_register(&misc_dev);
if(ret < 0)
goto err;
ret = request_irq(IRQ_ADC, irq_handler, IRQF_DISABLED, "irq_adc", NULL);
if(ret < 0)
goto err_irq;
init_waitqueue_head(&wq);
adccon = ioremap(ADCCON, sizeof(adccon));
adcdat0 = ioremap(ADCDAT0, sizeof(adcdat0));
clkcon = ioremap(CLKCON, sizeof(clkcon));
*clkcon |= (1 << 15);
printk("CLKCON = %lx\n", *clkcon);
printk("adc_init ###############################\n");
return 0;
err:
misc_deregister(&misc_dev);
printk("adc cdev_add failed ret = %d\n", ret);
return ret;
err_irq:
disable_irq(IRQ_ADC);
free_irq(IRQ_ADC, NULL);
misc_deregister(&misc_dev);
printk("adc cdev_add failed ret = %d\n", ret);
return ret;
}
static void __exit adc_exit(void)
{
iounmap(clkcon);
iounmap(adcdat0);
iounmap(adccon);
disable_irq(IRQ_ADC);
free_irq(IRQ_ADC, NULL);
misc_deregister(&misc_dev);
printk("adc_exit ###############################\n");
}
module_init(adc_init);
module_exit(adc_exit);
MODULE_LICENSE("GPL");
到了这里,关于ARM-Linux驱动内核(S3C2440)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!