专注于操作系统内核的实现
分类: 嵌入式
2013-07-02 11:02:15
很多天没有写博客,一是因为没有时间,二还是因为没有时间,所以
呢想写篇博文证明我还活着,LMOS还活着……
那么这些天我都干了些什么呢,第一我修证了LMOS的一些问题,第二
我又开始一个全新OS旅程——LMOSEM,这个名字看起来和LMOS差不多,
但是它是一个全新的从零开始的内核,基于嵌入式平台的“软”实时内核
而且从一开始就完全开源。我在次申明LMOSEM和LMOSx86—64体系没有任
何关系。
为什么我要这么做,因为从现在种种迹象表明,嵌入式平台正在疯狂
的改变着我们今天的生活,哦!我可能错了,不是今天,好像嵌入式平台
从计算机出现开始,就应用于各大领域,只是它被嵌入在大系统中某个环
节中不为人知罢了。也许你日常使用的PC机中正运行着许多小的嵌入式OS,
比如你的PC机中的USB控制器中也运行着OS,你相信吗,你应该相信的。
那么为什么我没有直接移植LMOS内核,而是重新写了一个,我疯了吧,我
想我有点。但是我有很多理由:1.LMOS大部分特性只适用于通用平台,比
多CPU,虚拟内存,一些复杂的同步机制。2.由于上述原因LMOS无法强实
时性要求。3.LMOS的代码复杂度已经很大了,有些东西,有些代码完全是
为了处理通用性的,然而这些代码运行在嵌入式平台就表现的太慢了。所
以我决定重新开始写一个,LMOSEM运行在嵌入式平台,LMOS运行在通用平
台。
关于LMOSEM的特性。
1.可移植性,LMOSEM有定义完好的hal层,移植的人几乎只要改写hal
层的几个文件可以了,嵌入式平台的多样性,使之LMOSEM更强调可
移植性。
2.LMOSEM1.0版没有虚拟内存机制,内存没有受保护。
3.LMOSEM1.0版的 进程和内核是不分开的(你可能受不了)。容我
稍后解释。
4.LMOSEM1.0版内核将管理这几个方面。
(1).中断处理。
(2).物理内存分配和回收。
(3).进程的创建和消毁、调度,(虽然不分开,但还是有进程)。
(4).驱动程序的接口与模型。
(5).LMOSEM1.0版将不提供引导程序,所以你要运行只有借助
u-boot之类的专业引导器。因为嵌入式平台的引导器不只是
引导内核,还要初始化硬件,而平台的差异巨大。所以我也
没有开发引导程序,实际上嵌入式平台的引导更像是PC上的
BIOS。
5.我暂时是基于minis3c2440平台开发的,有兴趣的同可以移植到其它
开发版。
你看到上面这些特性,不惊诧异,会问这能叫os吗,事实上我开始也
不愿承认这就是os,由于嵌入式平台的特性,可以认为这就是个OS内核也
可以不认为这是OS内核,可以说成是监控程序。并且很多成名的嵌入式OS
就是这样的。
LMOSEM是开源的,等我把相关性工作做完好后,我会把代码挂在github
上的。今天就可以先让大家看看一些代码。
.extern lmosemhal_start
.global _start
.global lmde
.align 4
_start:
@关闭irq和fiq中断,并且切换到SVE模式。
msr cpsr , #0xc0|0x13
@关闭看门狗。
ldr r0 , =WTCON
mov r1 , #0
str r1 , [r0]
@屏蔽所有中断
ldr r0 , =INTMASK
ldr r1 , =0xffffffff
str r1 , [r0]
@屏蔽所有子中断
ldr r0 , =INTSUBMASK
ldr r1 , =0x7fff
str r1 , [r0]
ldr sp,=INIT_HEAD_STACK_ADDR
bl lmosemhal_start
..............
/****************************************************************
LMOSEM HAL全局初始化文件halinit.c
*****************************************************************
彭东 @ 2013.07.01.10.30
****************************************************************/
#include "lmosemtypes.h"
#include "lmosemmctrl.h"
LKHEAD_T void hal_init()
{
init_mmu();
init_vector();
//......
return;
}
LKHEAD_T void init_mmu()
{
#ifdef CFG_S3C2440_PLATFORM
s3c2440mmu_init();
#endif
return;
}
LKHEAD_T void init_vector()
{
#ifdef CFG_S3C2440_PLATFORM
s3c2440vector_init();
#endif
return;
}
.....................
/**********************************************************
平台相关的文件platform.c
***********************************************************
彭东 @ 2013.07.01.10.40
**********************************************************/
#include "lmosemtypes.h"
#include "lmosemmctrl.h"
#ifdef CFG_S3C2440_PLATFORM
LKHEAD_T void s3c2440mmu_init()
{
uint_t vaddr=0,paddr=0;
u32_t pgdsc=0;
u32_t* pgdiradr=(u32_t*)PAGE_TLB_DIR;
for(uint_t i=0;i
pgdsc=paddr|PTE_SECT_AP|PTE_SECT_DOMAIN|PTE_SECT_NOCW|PTE_SECT_BIT;
pgdiradr[i]=pgdsc;
paddr+=0x100000;
}
pgdiradr[0]=SDRAM_MAPVECTPHY_ADDR|PTE_SECT_AP|PTE_SECT_DOMAIN|PTE_SECT_NOCW|PTE_SECT_BIT;
s3c2440mmu_set_tblbass(PAGE_TLB_DIR);
s3c2440mmu_set_domain(~0);
s3c2440mmu_invalid_dicache();
s3c2440mmu_enable();
return;
}
LKHEAD_T void s3c2440mmu_invalid_dicache()
{
__asm__ __volatile__(
"mov r0, #0 \n\t"
"mcr p15, 0, r0, c7, c7, 0 \n\t" /* 使无效ICaches和DCaches */
"mcr p15, 0, r0, c7, c10, 4 \n\t" /* drain write buffer on v4 */
"mcr p15, 0, r0, c8, c7, 0 \n\t" /* 使无效指令、数据TLB */
:
:
:"cc","memory","r0"
);
return;
}
LKHEAD_T void s3c2440mmu_set_domain(u32_t domain)
{
__asm__ __volatile__(
"mcr p15,0,%[domval],c3,c0,0 \n\t"
:
: [domval]"r"(domain)
: "cc","memory"
);
return;
}
LKHEAD_T void s3c2440mmu_set_tblbass(u32_t tblbphyadr)
{
__asm__ __volatile__(
"mcr p15,0,%[tbass],c2,c0,0 \n\t"
:
: [tbass]"r"(tblbphyadr)
: "cc","memory"
);
return;
}
LKHEAD_T void s3c2440mmu_enable()
{
__asm__ __volatile__(
"mrc p15,0,r0,c1,c0,0 \n\t"
"orr r0 ,#1 \n\t"
"mcr p15,0,r0,c1,c0,0 \n\t"
"nop \n\t"
"nop \n\t"
"nop \n\t"
"nop \n\t"
"nop \n\t"
"nop \n\t"
"nop \n\t"
:
:
: "r0","cc","memory"
);
return;
}
LKHEAD_T void s3c2440vector_init()
{
s3c2440vector_copy();
return;
}
.....................................
/**********************************************************
cpu控制文件cpuctrl.c
***********************************************************
彭东 @ 2013.06.24.11.40
**********************************************************/
#include "lmosemtypes.h"
#include "lmosemmctrl.h"
void hal_disable_fiq()
{
__asm__ __volatile__(
"mrs r0,cpsr \n\t"
"orr r0,r0,%[closefiq]\n\t"
"msr cpsr,r0 \n\t"
:
: [closefiq] "I" (CFIQ)
: "r0","cc","memory"
);
return;
}
void hal_enable_fiq()
{
__asm__ __volatile__(
"mrs r0,cpsr \n\t"
"bic r0,r0,%[openfiq]\n\t"
"msr cpsr,r0 \n\t"
:
: [openfiq] "I" (CFIQ)
: "r0","cc","memory"
);
return;
}
void hal_disable_irq()
{
__asm__ __volatile__(
"mrs r0,cpsr \n\t"
"orr r0,r0,%[closeirq]\n\t"
"msr cpsr,r0 \n\t"
:
: [closeirq] "I" (CIRQ)
: "r0","cc","memory"
);
return;
}
void hal_enable_irq()
{
__asm__ __volatile__(
"mrs r0,cpsr \n\t"
"bic r0,r0,%[openirq]\n\t"
"msr cpsr,r0 \n\t"
:
: [openirq] "I" (CIRQ)
: "r0","cc","memory"
);
return;
}
void hal_disable_irqfiq()
{
__asm__ __volatile__(
"mrs r0,cpsr \n\t"
"orr r0,r0,%[closeifiq]\n\t"
"msr cpsr,r0 \n\t"
:
: [closeifiq] "I" (CIRQFIQ)
: "r0","cc","memory"
);
return;
}
void hal_enable_irqfiq()
{
__asm__ __volatile__(
"mrs r0,cpsr \n\t"
"bic r0,r0,%[openifiq]\n\t"
"msr cpsr,r0 \n\t"
:
: [openifiq] "I" (CIRQFIQ)
: "r0","cc","memory"
);
return;
}
void hal_disablefiq_savecpuflg(cpuflg_t* cpuflg)
{
cpuflg_t tmpcpsr;
__asm__ __volatile__(
"mrs r7,cpsr \n\t"
"mov %[tmpcpr],r7 \n\t"
"orr r7,r7,%[closefiq] \n\t"
"msr cpsr,r7 \n\t"
: [tmpcpr] "=r" (tmpcpsr)
: [closefiq] "I" (CFIQ)
: "r7","cc","memory"
);
*cpuflg=tmpcpsr;
return;
}
void hal_enablefiq_restcpuflg(cpuflg_t* cpuflg)
{
__asm__ __volatile__(
"msr cpsr,%[ordcpr] \n\t"
:
: [ordcpr] "r" (*cpuflg) //我不知道GCC能不能自动处理这种约束"r" (*cpuflg)
: "cc","memory"
);
return;
}
void hal_disableirq_savecpuflg(cpuflg_t* cpuflg)
{
cpuflg_t tmpcpsr;
__asm__ __volatile__(
"mrs r7,cpsr \n\t"
"mov %[tmpcpr],r7 \n\t"
"orr r7,r7,%[closeirq] \n\t"
"msr cpsr,r7 \n\t"
: [tmpcpr] "=r" (tmpcpsr)
: [closeirq] "I" (CIRQ)
: "r7","cc","memory"
);
*cpuflg=tmpcpsr;
return;
}
void hal_enableirq_restcpuflg(cpuflg_t* cpuflg)
{
__asm__ __volatile__(
"msr cpsr,%[ordcpr] \n\t"
:
: [ordcpr] "r" (*cpuflg) //我不知道GCC能不能自动处理这种约束"r" (*cpuflg)
: "cc","memory"
);
return;
}
void hal_disableirqfiq_savecpuflg(cpuflg_t* cpuflg)
{
cpuflg_t tmpcpsr;
__asm__ __volatile__(
"mrs r7,cpsr \n\t"
"mov %[tmpcpr],r7 \n\t"
"orr r7,r7,%[closefirq] \n\t"
"msr cpsr,r7 \n\t"
: [tmpcpr] "=r" (tmpcpsr)
: [closefirq] "I" (CIRQFIQ)
: "r7","cc","memory"
);
*cpuflg=tmpcpsr;
return;
}
void hal_enableirqfiq_restcpuflg(cpuflg_t* cpuflg)
{
__asm__ __volatile__(
"msr cpsr,%[ordcpr] \n\t"
:
: [ordcpr] "r" (*cpuflg) //我不知道GCC能不能自动处理这种约束"r" (*cpuflg)
: "cc","memory"
);
return;
}
cpuflg_t hal_read_cpuflg()
{
cpuflg_t cpuflg;
__asm__ __volatile__(
"mrs %[retcpr],cpsr \n\t"
: [retcpr] "=r" (cpuflg)
:
: "cc","memory"
);
return cpuflg;
}
void hal_write_cpuflg(cpuflg_t cpuflg)
{
__asm__ __volatile__(
"msr cpsr,%[cpr] \n\t"
:
: [cpr] "r" (cpuflg)
: "cc","memory"
);
return;
}
cpuflg_t hal_read_scpuflg()
{
cpuflg_t scpuflg;
__asm__ __volatile__(
"mrs %[retscpr],spsr \n\t"
: [retscpr] "=r" (scpuflg)
:
: "cc","memory"
);
return scpuflg;
}
void hal_write_scpuflg(cpuflg_t scpuflg)
{
__asm__ __volatile__(
"msr cpsr,%[cpr] \n\t"
:
: [cpr] "r" (scpuflg)
: "cc","memory"
);
return;
}
void hal_cpumode_switch(uint_t mode)
{
__asm__ __volatile__(
"mrs r7,cpsr \n\t"
"orr r7,r7,%[cmod] \n\t"
"msr cpsr,r7 \n\t"
:
: [cmod] "r" (mode)
: "r7","cc","memory"
);
return;
}
uint_t hal_cpumodeswitch_retoldmode(uint_t mode)
{
uint_t oldmode;
__asm__ __volatile__(
"mrs r7,cpsr \n\t"
"mov %[oldmod],r7 \n\t"
"orr r7,r7,%[cmod] \n\t"
"msr cpsr,r7 \n\t"
: [oldmod] "=r"(oldmode)
: [cmod] "r" (mode)
: "r7","cc","memory"
);
return oldmode;
}
u8_t hal_io8_read(uint_t ioadr)
{
u8_t retdata;
__asm__ __volatile__(
"ldrb %[retdta],[%[ioadrr]] \n\t"
: [retdta] "=r"(retdata)
: [ioadrr] "r" (ioadr)
: "memory"
);
return retdata;
}
u16_t hal_io16_read(uint_t ioadr)
{
u16_t retdata;
__asm__ __volatile__(
"ldrh %[retdta],[%[ioadrr]] \n\t"
: [retdta] "=r"(retdata)
: [ioadrr] "r" (ioadr)
: "memory"
);
return retdata;
}
u32_t hal_io32_read(uint_t ioadr)
{
u32_t retdata;
__asm__ __volatile__(
"ldr %[retdta],[%[ioadrr]] \n\t"
: [retdta] "=r"(retdata)
: [ioadrr] "r" (ioadr)
: "memory"
);
return retdata;
}
void hal_io8_write(uint_t ioadr,u8_t val)
{
__asm__ __volatile__(
"strb %[valdta],[%[ioadrr]] \n\t"
:
: [valdta] "r"(val),[ioadrr] "r" (ioadr)
: "memory"
);
return;
}
void hal_io16_write(uint_t ioadr,u16_t val)
{
__asm__ __volatile__(
"strh %[valdta],[%[ioadrr]] \n\t"
:
: [valdta] "r"(val),[ioadrr] "r" (ioadr)
: "memory"
);
return;
}
void hal_io32_write(uint_t ioadr,u32_t val)
{
__asm__ __volatile__(
"str %[valdta],[%[ioadrr]] \n\t"
:
: [valdta] "r"(val),[ioadrr] "r" (ioadr)
: "memory"
);
return;
}
void hal_spinlock_init(spinlock_t* lock)
{
__asm__ __volatile__(
"swp %[lockval],%[lockval],[%[lockadr]] \n\t"
:
: [lockval] "r"(0),[lockadr] "r" (&lock->lock)
: "memory"
);
return;
}
void hal_spinlock_lock(spinlock_t* lock)
{
/*
慢且烧电,不过单CPU一加锁就会成功,
若不成功就死机。应该只有一种情况会
加锁失败,就是一进程加锁了还没解锁
之前发生了中断,中断处理程序又去加
同样一把锁,其它情况都视为程序员的
问题。为了处理这种情况,我提供了这
样的:lmhal_spinlock_saveflg_cli()
加锁之关掉中断同时保存原来的CPSR寄
存器!!
*/
__asm__ __volatile__(
"mov r8,#1 \n\t"
"1:swp r7,r8,[%[lockadr]] \n\t"
"cmp r7,#0 \n\t"
"bne 1b \n\t"
:
: [lockadr] "r" (&lock->lock)//我不知道GCC能不能自动处理这种约束
//"r"(&lock->lock)编译能通过,未验证
: "r7","r8","cc","memory"
);
return;
}
void hal_spinlock_unlock(spinlock_t* lock)
{
__asm__ __volatile__(
"swp %[lockval],%[lockval],[%[lockadr]] \n\t"
:
: [lockval] "r"(0),[lockadr] "r" (&lock->lock)
: "memory"
);
return;
}
void hal_spinlock_saveflg_cli(spinlock_t* lock, cpuflg_t* cpuflg)
{
cpuflg_t tmpcpsr;
__asm__ __volatile__(
"mrs r7,cpsr \n\t"
"mov %[tmpcpr],r7 \n\t"
"orr r7,r7,%[closefirq] \n\t"
"msr cpsr,r7 \n\t"
: [tmpcpr] "=r" (tmpcpsr)
: [closefirq] "I" (CIRQFIQ)
: "r7","cc","memory"
);
*cpuflg=tmpcpsr;
__asm__ __volatile__(
"mov r8,#1 \n\t"
"1:swp r7,r8,[%[lockadr]] \n\t"
"cmp r7,#0 \n\t"
"bne 1b \n\t"
:
: [lockadr] "r" (&lock->lock)//我不知道GCC能不能自动处理这种约束
//"r"(&lock->lock)编译能通过,未验证
: "r7","r8","cc","memory"
);
return;
}
void hal_spinunlock_restflg_sti(spinlock_t* lock, cpuflg_t* cpuflg)
{
__asm__ __volatile__(
"swp %[lockval],%[lockval],[%[lockadr]] \n\t"
:
: [lockval] "r"(0),[lockadr] "r" (&lock->lock)
: "memory"
);
__asm__ __volatile__(
"msr cpsr,%[ordcpr] \n\t"
:
: [ordcpr] "r" (*cpuflg) //我不知道GCC能不能自动处理这种约束"r" (*cpuflg)
: "cc","memory"
);
return;
}
#endif