用户应用程序(用户态)使用SWI指令触发arm软件异常中断,cpu进入管理模式(内核态)
1.对内核系统调用编码,编写内核系统调用表
2.针对系统调用编写软件中断异常处理函数
3.编写与内核系统调用对应的系统调用接口
4.编译用户应用程序为elf
5.把用户应用程序写入vfs
6.用vfs制作磁盘镜像
7.运行os,在文件系统里找到用户应用程序运行
user_system_call.h
// 供用户应用程序使用的系统调用接口
#ifndef _USER_SYSTEM_CALL_H_
#define _USER_SYSTEM_CALL_H_
#define SYSTEM_CALL_TYPE_PRINT 0 //系统调用类型:打印
#define SYSTEM_CALL_TYPE_IO 1 //系统调用类型:IO
#define SYSTEM_CALL_TYPE_NUM 2 //系统调用类型总数
#define SYSTEM_CALL_RET_ERE -1
#define SYSTEM_CALL_RET_SUC 0
// 系统调用宏
// 系统调用返回值:ret(r0)
// 传递给内核的系统调用类型号:type(立即数)
// 参数个数:argc(r1)
// 参数数组首地址:args(r2)
// %0:ret,%1:type,%2:argc,%3:args
#define SYSTEM_CALL(type,argc,args,ret) do { \
asm volatile \
( \
"stmfd r13!,{lr}\n" /*用户模式返回地址入栈,为了用户模式调用SYSTEM_CALL后可返回*/ \
"mov r1,%2\n" \
"mov r2,%3\n" \
"swi %1\n" \
"ldmfd r13!,{lr}\n" /*用户模式返回地址出栈,为了用户模式调用SYSTEM_CALL后可返回*/ \
:"=r"(ret) \
:"i"(type),"r"(argc),"r"(args) \
: \
); \
}while(0);
#endif // _USER_SYSTEM_CALL_H_
user_main.c
#include "user_system_call.h"
int main(void)
{
const char *string = "this is in user main\n";
for (;;)
{
if (*string == '\0')
{
break;
}
*(volatile unsigned int *)0xd0000020 = *string; // leeos已开启mmu,串口虚拟地址为0xd0000020
string++;
}
int ret = -1;
SYSTEM_CALL(SYSTEM_CALL_TYPE_PRINT,3,(int *)30000000,ret);
string = "SYSTEM_CALL_RETURNED\n";
for (;;)
{
if (*string == '\0')
{
break;
}
*(volatile unsigned int *)0xd0000020 = *string;
string ++;
}
return(0);
}
// arm-none-eabi-gcc -e main -nostartfiles -nostdlib -Ttext 0x30100000 -o user_main.elf user_main.c
// arm-none-eabi-objcopy -O binary user_main.elf user_main.bin
abnormal.s
.equ SYS_MOD,0x1f
.equ IRQ_MOD,0x12
.equ FIQ_MOD,0x11
.equ ABT_MOD,0x17
.equ UND_MOD,0x1b
.equ DISABLE_IRQ,0x80
.equ DISBALE_FIQ,0x40
.macro CHANGE_TO_SYS
msr cpsr_c,#(DISABLE_IRQ | DISBALE_FIQ | SYS_MOD)
.endm
.macro CHANGE_TO_IRQ
msr cpsr_c,#(DISABLE_IRQ | DISBALE_FIQ | IRQ_MOD)
.endm
.global __vector_undefined
.global __vector_swi
.global __vector_prefetch_abort
.global __vector_data_abort
.global __vector_reserved
.global __vector_irq
.global __vector_fiq
.extern handle_abnormal_undefined
.extern handle_abnormal_swi
.extern os_system_call
.extern handle_abnormal_prefetch
.extern handle_abnormal_data
.extern handle_abnormal_reserved
.text
.code 32
__vector_undefined:
b handle_abnormal_undefined
__vector_swi:
str lr,[r13,#-4] @保存用户模式swi指令后一指令地址
mrs r0,spsr @取用户模式程序状态
str r0,[r13,#-8] @保存用户模式程序状态
mov r0,r13 @取软件中断异常状态(管理模式)栈指针
CHANGE_TO_SYS @切换到系统模式(内核态)
stmfd r13!,{r0} @把管理模式栈指针压入系统模式栈
ldr r0,[r0,#-4] @取用户模式swi指令后一指令地址
sub r0,r0,#4 @取用户模式swi指令地址
ldr r0,[r0] @取用户模式swi指令
bic r0,r0,#0xff000000 @取swi指令的后24位(系统调用类型号)
bl os_system_call @系统调用
ldmfd r13!,{r1} @管理模式栈指针出栈到r1
ldr r2,[r1,#-8] @取用户模式程序状态
msr cpsr,r2 @切换为用户模式程序状态
ldr pc,[r1,#-4] @取用户模式swi指令后一指令地址
__vector_prefetch_abort:
b handle_abnormal_prefetch
__vector_data_abort:
b handle_abnormal_data
__vector_reserved:
b handle_abnormal_reserved
__vector_irq:
sub lr,lr,#0x4
stmfd sp!,{lr}
bl common_irq_handler
mrs lr,spsr
msr cpsr_c,lr
ldmfd sp!,{lr}
mov pc,lr
__vector_fiq:
nop
@ __vector_irq:
@ sub r14,r14,#4 @取被中断进程的返回地址
@ stmfd r13!,{r0} @r0压入中断模式栈,被中断进程的args
@ stmfd r13!,{r1-r3} @r3-r1压入中断模式栈
@ // 清空中断相关寄存器
@ mov r2,#0xca000000 @取中断控制器地址
@ add r1,r2,#0x10
@ ldr r0,[r1]
@ ldr r3,[r2]
@ orr r3,r3,r1
@ str r3,[r2]
@ str r0,[r1]
@ ldmfd r13!,{r1-r3}
@ mov r0,r14
@ CHANGE_TO_SYS
@ stmfd r13!,{r0}
@ stmfd r13!,{r14}
@ CHANGE_TO_IRQ
@ ldmfd r13!,{r0}
@ ldr r14,=__asm_schedule
@ stmfd r13!,{r14}
@ ldmfd r13!,{pc}^
@ __asm_schedule:
@ stmfd r13!,{r0-r12}
@ mrs r1, cpsr
@ stmfd r13!,{r1}
@ mov r1,sp
@ bic r1,#0xff0
@ bic r1,#0xf
@ mov r0,sp
@ str r0,[r1]
@ bl __common_schedule
@ ldr sp,[r0]
@ ldmfd r13!,{r1}
@ msr cpsr_cxsf,r1
@ ldmfd r13!,{r0-r12,r14,pc}
@ __vector_irq: @书里中断异常的复杂处理程序
@ sub r14,r14,#0x4
@ stmfd r13!,{r14}
@ mrs r14,spsr
@ stmfd r13!,{r14}
@ CHANGE_TO_SVC
@ stmfd r13!,{r0,r1,r2,r3}
@ bl common_irq_handler
@ ldmfd r13!,{r0,r1,r2,r3}
@ CHANGE_TO_IRQ
@ ldmfd r13!,{r14}
@ msr spsr,r14
@ ldmfd r13!,{pc}^
@ __vector_irq: @书里优秀的中断异常处理程序
@ sub r14,r14,#0x4
@ str r14,[r13,#-0x4]
@ mrs r14,spsr
@ str r14,[r13,#-0x8]
@ str r0,[r13,#-0xc]
@ mov r0,r13
@ CHANGE_TO_SVC
@ str r14,[r13,#-0x8]!
@ ldr r14,[r0,#-0x4]
@ str r14,[r13,#-0x4]
@ ldr r14,[r0,#-0x8]
@ ldr r0,[r0,#-0xc]
@ stmdb r13!,{r0-r3,r14}
@ bl common_irq_handler
@ ldmia r13!,{r0-r3,r14}
@ msr spsr,r14
@ ldmfd r13!,{r14,pc}^
@ my__vector_swi: @用以实现系统调用的软件中断异常处理程序
@ str lr,[r13,#-4] @保存用户模式swi指令后一指令地址
@ mrs r0,spsr @取用户模式程序状态
@ str r0,[r13,#-8] @保存用户模式程序状态
@ mov r0,r13 @取软件中断异常状态(管理模式)栈指针
@ CHANGE_TO_SYS @切换到系统模式(内核态)
@ stmfd r13!,{r0} @把管理模式栈指针压入系统模式栈
@ ldr r0,[r0,#-4] @取用户模式swi指令后一指令地址
@ sub r0,r0,#4 @取用户模式swi指令地址
@ ldr r0,[r0] @取用户模式swi指令
@ bic r0,r0,#0xff000000 @取swi指令的后24位(系统调用类型号)
@ bl os_system_call @系统调用
@ ldmfd r13!,{r1} @管理模式栈指针出栈到r1
@ ldr r2,[r1,#-8] @取用户模式程序状态
@ msr cpsr,r2 @切换为用户模式程序状态
@ ldr pc,[r1,#-4] @取用户模式swi指令后一指令地址
start.s
.section .startup
.code 32
.align 0
.global _start
.extern __vector_reset
.extern __vector_undefined
.extern __vector_swi
.extern __vector_prefetch_abort
.extern __vector_data_abort
.extern __vector_reserved
.extern __vector_irq
.extern __vector_fiq
@程序入口地址_start
_start:
ldr pc,_vector_reset @pc = __vector_reset,处理复位异常
ldr pc,_vector_undefined @处理未定义异常
ldr pc,_vector_swi @处理软件中断异常
ldr pc,_vector_prefetch_abort @处理预取址中止异常
ldr pc,_vector_data_abort @处理数据中止异常
ldr pc,_vector_reserved @处理保留异常
ldr pc,_vector_irq @处理中断异常
ldr pc,_vector_fiq @处理快速中断异常
.align 4
_vector_reset: .word __vector_reset
_vector_undefined: .word __vector_undefined
_vector_swi: .word __vector_swi
_vector_prefetch_abort: .word __vector_prefetch_abort
_vector_data_abort: .word __vector_data_abort
_vector_reserved: .word __vector_reserved
_vector_irq: .word __vector_irq
_vector_fiq: .word __vector_fiq
init.s
.equ DISABLE_IRQ, 0x80
.equ DISABLE_FIQ, 0x40
.equ SYS_MOD, 0x1f
.equ IRQ_MOD, 0x12
.equ FIQ_MOD, 0x11
.equ SVC_MOD, 0x13
.equ ABT_MOD, 0x17
.equ UND_MOD, 0x1b
.equ MEM_SIZE, 0x800000
.equ TEXT_BASE, 0x30000000
.equ _SVC_STACK, (TEXT_BASE + MEM_SIZE - 4)
.equ _IRQ_STACK, (_SVC_STACK - 0x400)
.equ _FIQ_STACK, (_IRQ_STACK - 0x400)
.equ _ABT_STACK, (_FIQ_STACK - 0x400)
.equ _UND_STACK, (_ABT_STACK - 0x400)
.equ _SYS_STACK, (_UND_STACK - 0x400)
.text
.code 32
.global __vector_reset
.extern boot
.extern __bss_start__
.extern __bss_end__
@复位异常向量处理程序入口地址__vector_reset
__vector_reset:
msr cpsr_c,#(DISABLE_IRQ | DISABLE_FIQ | SVC_MOD)
ldr sp,=_SVC_STACK
msr cpsr_c,#(DISABLE_IRQ | DISABLE_FIQ | IRQ_MOD)
ldr sp,=_IRQ_STACK
msr cpsr_c,#(DISABLE_IRQ | DISABLE_FIQ | FIQ_MOD)
ldr sp,=_FIQ_STACK
msr cpsr_c,#(DISABLE_IRQ | DISABLE_FIQ | ABT_MOD)
ldr sp,=_ABT_STACK
msr cpsr_c,#(DISABLE_IRQ | DISABLE_FIQ | UND_MOD)
ldr sp,=_UND_STACK
msr cpsr_c,#(DISABLE_IRQ | DISABLE_FIQ | SYS_MOD)
ldr sp,=_SYS_STACK
_clear_bss:
ldr r1,_bss_start_
ldr r3,_bss_end_
mov r2,#0x0
_loop:
cmp r1,r3
beq boot
str r2,[r1],#0x4
b _loop
_bss_start_:
.word __bss_start__
_bss_end_:
.word __bss_end__
.end
types.h
#ifndef _TYPES_H_
#define _TYPES_H_
#define NULL (void *)0
#define ERR_RET -1
#define SUC_RET 0
#endif // _TYPES_H_
boot.c
// 欢迎来到c代码的世界
#include "types.h"
#include "string.h"
extern void init_sys_mmu(void);
extern void start_mmu(void);
extern void printk(char *fmt,...);
extern void memory_test(void);
extern void RamDiskTest(void);
extern void vfs_test(void);
extern void excute_test_bin(void);
extern void excute_test_elf(void);
#define USART_PHYSICAL_ADDR 0x50000020
static void helloworld(void)
{
const char *p = "helloworld\n";
while(*p)
{
*(volatile unsigned int *)USART_PHYSICAL_ADDR = *p;
p ++;
};
}
void boot(void)
{
helloworld();
init_sys_mmu();
start_mmu();
// memory_test();
//RamDiskTest();
// vfs_test();
// excute_test_bin();
excute_test_elf();
printk("in boot\n");
}
void handle_abnormal_undefined(void)
{
printk("handle_abnormal_undefined\n");
for (;;)
{
;
}
}
void handle_abnormal_swi(void)
{
printk("handle_abnormal_swi\n");
for (;;)
{
;
}
}
void handle_abnormal_prefetch(void)
{
printk("handle_abnormal_prefetch\n");
for (;;)
{
;
}
}
void handle_abnormal_data(void)
{
printk("handle_abnormal_data\n");
for (;;)
{
;
}
}
void handle_abnormal_reserved(void)
{
printk("handle_abnormal_reserved\n");
for (;;)
{
;
}
}
mmu.c
// 段页表基址mask
#define PAGE_TABLE_L1_BASE_ADDR_MASK (0xffffc000)
// 由虚拟地址到段页表项索引
#define VIRT_TO_PTE_L1_INDEX(addr) (((addr) & 0xfff00000) >> 18)
// 段页表项表示的页不使用cache和write_buf
#define PTE_L1_SECTION_NO_CACHE_AND_WB (0x0 << 2)
// 段页表项默认域标识
#define PTE_L1_SECTION_DOMAIN_DEFAULT (0x0 << 5)
// 段页表项默认权限标识
#define PTE_ALL_AP_L1_SECTION_DEFAULT (0x1 << 10)
// 段页表项获取物理地址mask
#define PTE_L1_SECTION_PADDR_BASE_MASK (0xfff00000)
// 一级页表标识
#define PTE_BITS_L1_SECTION (0x2)
// 段页表基地址
#define L1_PTR_BASE_ADDR 0x30700000
// 物理内存地址
#define PHYSICAL_MEM_ADDR 0x30000000
// 虚拟内存地址
#define VIRTUAL_MEM_ADDR 0x30000000
// 物理内存大小
#define MEM_MAP_SIZE 0x800000
// 物理外设地址
#define PHYSICAL_IO_ADDR 0x48000000
// 虚拟外设地址
#define VIRTUAL_IO_ADDR 0xc8000000
// 外设内存大小
#define IO_MAP_SIZE 0x18000000
// 异常向量虚拟地址
#define VECTOR_VIRTUAL_ADDR 0x0
// 异常向量物理地址
#define VECTOR_PHYSICAL_ADDR 0x30000000
void start_mmu(void)
{
unsigned int ttb = L1_PTR_BASE_ADDR;
asm (
"mcr p15,0,%0,c2,c0,0\n" /* set base address of page table*/
"mvn r0,#0\n"
"mcr p15,0,r0,c3,c0,0\n" /* enable all region access*/
"mov r0,#0x1\n"
"mcr p15,0,r0,c1,c0,0\n" /* set back to control register */
"mov r0,r0\n"
"mov r0,r0\n"
"mov r0,r0\n"
:
: "r" (ttb)
:"r0"
);
}
// 由物理内存获取段页表项
unsigned int gen_l1_pte(unsigned int paddr)
{
return (paddr & PTE_L1_SECTION_PADDR_BASE_MASK) | PTE_BITS_L1_SECTION;
}
// 由段页表基地址和虚拟地址获取段页表项地址
unsigned int gen_l1_pte_addr(unsigned int baddr, unsigned int vaddr)
{
return (baddr & PAGE_TABLE_L1_BASE_ADDR_MASK) | VIRT_TO_PTE_L1_INDEX(vaddr);
}
// 映射物理内存空间\外设内存空间到虚拟内存
void init_sys_mmu(void)
{
unsigned int pte;
unsigned int pte_addr;
int j;
// 异常向量表映射
for (j = 0; j < MEM_MAP_SIZE >> 20; j ++)
{
pte = gen_l1_pte(VECTOR_PHYSICAL_ADDR + (j << 20));
pte |= PTE_ALL_AP_L1_SECTION_DEFAULT;
pte |= PTE_L1_SECTION_NO_CACHE_AND_WB;
pte |= PTE_L1_SECTION_DOMAIN_DEFAULT;
pte_addr = gen_l1_pte_addr(L1_PTR_BASE_ADDR, VECTOR_VIRTUAL_ADDR + (j << 20));
*(volatile unsigned int *)pte_addr = pte;
}
// 物理内存大小为8M,一级页表的页大小为1M,一共8页
for(j = 0; j < MEM_MAP_SIZE >> 20; j ++)
{
pte = gen_l1_pte(PHYSICAL_MEM_ADDR + (j << 20));
pte |= PTE_ALL_AP_L1_SECTION_DEFAULT;
pte |= PTE_L1_SECTION_NO_CACHE_AND_WB;
pte |= PTE_L1_SECTION_DOMAIN_DEFAULT;
pte_addr = gen_l1_pte_addr(L1_PTR_BASE_ADDR, VIRTUAL_MEM_ADDR + (j << 20));
*(volatile unsigned int *)pte_addr = pte;
}
// 外设地址空间映射到虚拟内存,0x180页
for(j = 0; j < IO_MAP_SIZE >> 20; j ++)
{
pte = gen_l1_pte(PHYSICAL_IO_ADDR+(j << 20));
pte |= PTE_ALL_AP_L1_SECTION_DEFAULT;
pte |= PTE_L1_SECTION_NO_CACHE_AND_WB;
pte |= PTE_L1_SECTION_DOMAIN_DEFAULT;
pte_addr = gen_l1_pte_addr(L1_PTR_BASE_ADDR, VIRTUAL_IO_ADDR + (j << 20));
*(volatile unsigned int *)pte_addr = pte;
}
}
// 建立物理地址和虚拟地址bytes字节的映射关系
void mmu_remaping(unsigned int pAddr,unsigned int vAddr,unsigned int bytes)
{
unsigned int pte;
unsigned int pte_addr;
int j;
for(j = 0; j < (bytes >> 20); j ++)
{
pte = gen_l1_pte(pAddr + (j << 20));
pte_addr = gen_l1_pte_addr(L1_PTR_BASE_ADDR, vAddr + (j << 20));
*(volatile unsigned int *)pte_addr = pte;
}
}
void test_mmu(void)
{
const char *p = "test_mmu\n";
while (*p)
{
*(volatile unsigned int *)0xd0000020 = *p;
p ++;
};
}
printk.c
#define PRINTK_BYTE_IO_VIRTUAL_ADDR 0xd0000020
#define PRINTK_IS_PRINTABLE(c) ( ( (c >= 32) && (c <= 126) ) || (c == '\n') )
#define PRINTK_FMT_TYPE_FLAG '%'
#define PRINTK_FMT_TYPE_CHAR 'c'
#define PRINTK_FMT_TYPE_INT 'd'
#define PRINTK_FMT_TYPE_ADDR 'a'
#define PRINTK_FMT_TYPE_STRING 's'
#define PRINTK_PRINT_CHAR(c) do { \
if (PRINTK_IS_PRINTABLE(c)) \
{ \
*(volatile unsigned int *)(PRINTK_BYTE_IO_VIRTUAL_ADDR) = c; \
} \
}while(0);
#define PRINTK_STRUCT_BUF_SIZE 64
struct
{
char buf[PRINTK_STRUCT_BUF_SIZE];
unsigned int amount;
}printk_struct;
#define PRINTK_TEMP_STRUCT_BUF_SIZE 32
struct
{
char buf[PRINTK_TEMP_STRUCT_BUF_SIZE];
unsigned int amount;
}printk_temp_struct;
void printk_struct_buf_clear(void)
{
unsigned int i = 0;
for (i = 0; i < PRINTK_STRUCT_BUF_SIZE; i++)
{
printk_struct.buf[i] = '\0';
}
printk_struct.amount = 0;
}
void printk_temp_struct_buf_clear(void)
{
unsigned int i = 0;
for (i = 0; i < PRINTK_TEMP_STRUCT_BUF_SIZE; i++)
{
printk_temp_struct.buf[i] = '\0';
}
printk_temp_struct.amount = 0;
}
void printk_struct_buf_insert_tail(char c)
{
if (PRINTK_IS_PRINTABLE(c))
{
if (printk_struct.amount < PRINTK_STRUCT_BUF_SIZE)
{
printk_struct.buf[printk_struct.amount] = c;
printk_struct.amount++;
}
}
}
void printk_temp_struct_buf_insert_tail(char c)
{
if (PRINTK_IS_PRINTABLE(c))
{
if (printk_temp_struct.amount < PRINTK_TEMP_STRUCT_BUF_SIZE)
{
printk_temp_struct.buf[printk_temp_struct.amount] = c;
printk_temp_struct.amount++;
}
}
}
void printk_print_string(char *string)
{
char *p = string;
unsigned char i = 0;
for (;;)
{
if (PRINTK_IS_PRINTABLE(p[i]))
{
PRINTK_PRINT_CHAR(p[i]);
}
else
{
break;
}
i++;
}
}
unsigned int printk_get_string_length(char *string)
{
char *p = string;
unsigned int length = 0;
for (;;)
{
if (PRINTK_IS_PRINTABLE(p[length]))
{
length++;
continue;
}
else
{
return(length);
}
}
}
void printk_temp_struct_buf_reverse(void)
{
unsigned int i = 0;
char temp = '\0';
for (i = 0; i < printk_temp_struct.amount; i++)
{
if (i >= (printk_temp_struct.amount - 1 - i))
{
break;
}
temp = printk_temp_struct.buf[i];
printk_temp_struct.buf[i] = printk_temp_struct.buf[printk_temp_struct.amount - 1 - i];
printk_temp_struct.buf[printk_temp_struct.amount - 1 - i] = temp;
}
}
void printk_temp_struct_buf_fill_int(int num_int)
{
int num_int_positve = 0;
char result = '\0';
if (num_int == 0)
{
printk_temp_struct_buf_insert_tail('0');
return;
}
else if (num_int > 0)
{
num_int_positve = num_int;
}
else if (num_int < 0)
{
num_int_positve = -num_int;
}
for (;;)
{
if (num_int_positve == 0)
{
break;
}
result = (char)(num_int_positve % 10) + '0';
printk_temp_struct_buf_insert_tail(result);
num_int_positve = num_int_positve / 10;
}
if (num_int < 0)
{
printk_temp_struct_buf_insert_tail('-');
}
printk_temp_struct_buf_reverse();
}
void printk_struct_buf_append_temp_buf(void)
{
unsigned int i = 0;
char *p = printk_temp_struct.buf;
for (i = printk_struct.amount;i < PRINTK_STRUCT_BUF_SIZE; i++)
{
if (PRINTK_IS_PRINTABLE(*p))
{
printk_struct_buf_insert_tail(*p);
}
else
{
break;
}
p++;
}
}
void printk_temp_struct_buf_fill_addr(unsigned int num_addr)
{
unsigned int addr = num_addr;
char result = '\0';
if (num_addr == 0)
{
printk_temp_struct_buf_insert_tail('0');
return;
}
for (;;)
{
if (addr == 0)
{
break;
}
result = (char)(addr % 10) + '0';
printk_temp_struct_buf_insert_tail(result);
addr = addr / 10;
}
printk_temp_struct_buf_reverse();
}
void printk_temp_struct_buf_fill_string(unsigned int char_addr)
{
char *p = (char *)char_addr;
for (;;)
{
if (PRINTK_IS_PRINTABLE(*p))
{
printk_temp_struct_buf_insert_tail(*p);
}
else
{
break;
}
p++;
}
}
#define PRINTK_INIT_PARGV(pArgv,fmt) ( pArgv = (char *)&fmt )
#define PRINTK_REFRESH_PARGV(pArgv) ( pArgv = pArgv + 4 )
#define PRINTK_GET_ARGV(pArgv,type) ( *(type *)pArgv )
#define PRINTK_DEINIT_PARGV(pArgv) ( pArgv = (char*)0 )
void printk_struct_buf_format(char *pV,char *fmt)
{
char *pArgv = pV;
char *format = fmt;
unsigned int format_length = 0;
unsigned int i = 0;
format_length = printk_get_string_length(format);
for (i = 0; i < format_length; i++)
{
if (format[i] == PRINTK_FMT_TYPE_FLAG)
{
if (format[i + 1] == PRINTK_FMT_TYPE_CHAR)
{
PRINTK_REFRESH_PARGV(pArgv);
char c = PRINTK_GET_ARGV(pArgv,char);
printk_struct_buf_insert_tail(c);
i++;
}
else if (format[i + 1] == PRINTK_FMT_TYPE_INT)
{
printk_temp_struct_buf_clear();
PRINTK_REFRESH_PARGV(pArgv);
int num_int = PRINTK_GET_ARGV(pArgv,int);
printk_temp_struct_buf_fill_int(num_int);
printk_struct_buf_append_temp_buf();
i++;
}
else if (format[i + 1] == PRINTK_FMT_TYPE_ADDR)
{
printk_temp_struct_buf_clear();
PRINTK_REFRESH_PARGV(pArgv);
unsigned int num_addr = PRINTK_GET_ARGV(pArgv,unsigned int);
printk_temp_struct_buf_fill_addr(num_addr);
printk_struct_buf_append_temp_buf();
i++;
}
else if (format[i + 1] == PRINTK_FMT_TYPE_STRING)
{
printk_temp_struct_buf_clear();
PRINTK_REFRESH_PARGV(pArgv);
unsigned int char_addr = PRINTK_GET_ARGV(pArgv,unsigned int);
printk_temp_struct_buf_fill_string(char_addr);
printk_struct_buf_append_temp_buf();
i++;
}
else
{
printk_struct_buf_insert_tail(format[i]);
}
}
else
{
printk_struct_buf_insert_tail(format[i]);
}
}
}
void printk(char *fmt,...)
{
printk_struct_buf_clear();
char *pArgv;
PRINTK_INIT_PARGV(pArgv,fmt);
printk_struct_buf_format(pArgv,fmt);
printk_print_string(printk_struct.buf);
PRINTK_DEINIT_PARGV(pArgv);
}
void test_printk(void)
{
printk("test_printk start\n");
int x;
printk("[char:%c,int:%d,int:%d,int:%d,address:%a,address:%a,string:%s]\n",'a',123,-123,0,0,&x,"hello_printk");
printk("test_printk end\n");
}
string.h
#ifndef _STRING_H_
#define _STRING_H_
extern int memncpy(void *srcAddr,void *desAddr,unsigned int nBytes);
extern int memnset(void *addr,char c,unsigned int bytes);
extern int memncmp(void *p1,void *p2,unsigned int bytes);
extern unsigned int strlen(char *string);
// --------------------------------------------------
extern void memncpy_test(void);
extern void memnset_test(void);
extern void memncmp_test(void);
extern void strlen_test(void);
#endif // _STRING_H_
string.c
#include "string.h"
#include "types.h"
extern void printk(char *fmt,...);
int memncpy(void *srcAddr,void *desAddr,unsigned int nBytes)
{
if ((srcAddr == NULL) || (desAddr == NULL))
{
return(ERR_RET);
}
unsigned int i = 0;
for (i = 0; i < nBytes; i ++)
{
// printk("srcAddr[i]:%c\n",*((char *)srcAddr + i));
*((char *)(desAddr) + i) = *((char *)srcAddr + i);
}
return(SUC_RET);
}
int memnset(void *addr,char c,unsigned int bytes)
{
if ((addr == NULL) || (c < 0))
{
return(ERR_RET);
}
unsigned int i = 0;
for (i = 0; i < bytes; i ++)
{
*((char *)addr + i) = c;
}
return(SUC_RET);
}
int memncmp(void *p1,void *p2,unsigned int bytes)
{
if ((p1 == NULL) || (p2 == NULL))
{
return(ERR_RET);
}
unsigned int i = 0;
for (i = 0; i < bytes; i ++)
{
if ( (*((char *)p1 + i)) != (*((char *)p2 + i)) )
{
return(ERR_RET);
}
}
return(SUC_RET);
}
unsigned int strlen(char *string)
{
if (string == NULL)
{
return(ERR_RET);
}
unsigned int n = 0;
for (;;)
{
if (*((char *)(string + n)) == '\0')
{
return(n);
}
n ++;
}
}
// --------------------------------------------------
// buf2:hello
// pass
void memncpy_test(void)
{
char buf1[] = "hello";
char buf2[6];
int ret = ERR_RET;
ret = memncpy(buf1,buf2,5);
if (ret == ERR_RET)
{
printk("memncpy error\n");
return;
}
printk("buf2:%s\n",buf2);
}
// after memnset buf:aaaaaaa
// pass
void memnset_test(void)
{
char buf[8];
int ret = ERR_RET;
ret = memnset(buf,'a',7);
if (ret == ERR_RET)
{
printk("memnset error\n");
return;
}
printk("after memnset buf:%s\n",buf);
}
void memncmp_test(void)
{
}
interrupt.c
// 中断基址
#define INT_BASE (0xca000000)
// 中断屏蔽器
#define INT_MASK (INT_BASE + 0x8)
// timer4的偏移值
#define INTOFFSET (INT_BASE + 0x14)
// 通过屏蔽的中断寄存器
#define INTPND (INT_BASE + 0x10)
// 主中断源寄存器,标识哪个硬件产生了中断
#define SRCPND (INT_BASE + 0x0)
extern void printk(char *fmt,...);
// 中断公共处理函数
void common_irq_handler(void)
{
// unsigned int tmp = (1 << (*(volatile unsigned int *)INTOFFSET));
// printk("%d\n",*(volatile unsigned int *)INTOFFSET);
// *(volatile unsigned int *)SRCPND |= tmp;
// *(volatile unsigned int *)INTPND |= tmp;
// printk("timer alarming\n");
}
// 定时器基址
#define TIMER_BASE (0xd1000000)
// 一级分频器
#define TCFG0 ((volatile unsigned int *)(TIMER_BASE + 0x0))
// 二级分频器
#define TCFG1 ((volatile unsigned int *)(TIMER_BASE + 0x4))
// 定时控制器
#define TCON ((volatile unsigned int *)(TIMER_BASE + 0x8))
// timer4减数器
#define TCONB4 ((volatile unsigned int *)(TIMER_BASE + 0x3c))
// 使能中断
void enable_irq(void)
{
asm volatile
(
"mrs r4,cpsr\t\n"
"bic r4,r4,#0x80\t\n"
"msr cpsr,r4\t\n"
:
:
:"r4"
);
}
// 失能某个中断屏蔽位
void umask_int(unsigned int offset)
{
*(volatile unsigned int *)INT_MASK &= ~(1 << offset);
}
// 定时器初始化
void timer_init(void)
{
*TCFG0 |= 0x800;
*TCON &= (~(7 << 20));
*TCON |= (1 << 22);
*TCON |= (1 << 21);
*TCONB4 = 10000;
*TCON |= (1 << 20);
*TCON &= ~(1 << 21);
umask_int(14);
enable_irq();
}
memory.c
// 内存管理
#include "types.h"
extern void printk(char *fmt,...);
#define MEMORY_END_VIRTUAL_ADDR 0x30700000
#define MEMORY_START_VIRTUAL_ADDR 0x300f0000
// 待管理空间,6356992字节
#define MEMORY_BYTES ( MEMORY_END_VIRTUAL_ADDR - MEMORY_START_VIRTUAL_ADDR )
// 页表大小4k字节
#define MEMORY_PAGE_BYTES (4 * 1024)
#define MEMORY_PAGE_FLAG_IDLE 0x0
#define MEMORY_PAGE_FLAG_BUSY 0x1
#define MEMORY_PAGE_FLAG_DIRTY 0x2
// 页表描述体
struct memory_page
{
unsigned int vAddr;
unsigned int flag;
struct memory_page *pNextPage;
};
// 页表描述体大小
#define MEMORY_PAGE_DESCRIPTOR_BYTES ( sizeof(struct memory_page) )
// 页表描述体起始虚拟地址
#define MEMORY_PAGE_DESCRIPTOR_START_VIRTUAL_ADDR MEMORY_START_VIRTUAL_ADDR
// 页表总个数,6356992/(4*1024+12)=1547
#define MEMORY_PAGE_NUM ( (MEMORY_END_VIRTUAL_ADDR - MEMORY_START_VIRTUAL_ADDR) / (MEMORY_PAGE_BYTES +MEMORY_PAGE_DESCRIPTOR_BYTES ) )
// 页表起始地址
#define MEMORY_PAGE_START_VIRTUAL_ADDR ( MEMORY_START_VIRTUAL_ADDR + MEMORY_PAGE_DESCRIPTOR_BYTES * MEMORY_PAGE_NUM )
#define MEMORY_BUDDY_TYPE_64K (64 * 1024)
#define MEMORY_BUDDY_TYPE_128K (128 * 1024)
#define MEMORY_BUDDY_TYPE_256K (256 * 1024)
#define MEMORY_BUDDY_TYPE_512K (512 * 1024)
#define MEMORY_BUDDY_TYPE_1024K (1024 * 1024)
#define MEMORY_BUDDY_TYPE_NUM 5
#define MEMORY_IS_BUDDY_TYPE(type) ( \
(type == MEMORY_BUDDY_TYPE_64K) || \
(type == MEMORY_BUDDY_TYPE_128K) || \
(type == MEMORY_BUDDY_TYPE_256K) || \
(type == MEMORY_BUDDY_TYPE_512K) || \
(type == MEMORY_BUDDY_TYPE_1024K) \
)
// buddy描述体
struct memory_buddy
{
unsigned int type;
unsigned int num;
struct memory_page *pFirstPage;
};
// buddy池
static struct memory_buddy buddy[MEMORY_BUDDY_TYPE_NUM];
static inline void memory_init_all_page(void)
{
unsigned int i = 0;
struct memory_page *pPage = NULL;
for (i = 0; i < MEMORY_PAGE_NUM; i ++)
{
pPage = (struct memory_page *)MEMORY_PAGE_DESCRIPTOR_START_VIRTUAL_ADDR + i;
pPage->vAddr = MEMORY_PAGE_START_VIRTUAL_ADDR + i * MEMORY_PAGE_BYTES;
pPage->flag = MEMORY_PAGE_FLAG_IDLE;
pPage->pNextPage = NULL;
// printk("i:%a,vAddr:%a\n",i,pPage->vAddr);
}
}
static inline void memory_init_all_buddy(void)
{
unsigned int i = 0;
struct memory_page *pPage = NULL;
buddy[0].type = MEMORY_BUDDY_TYPE_64K;
buddy[0].num = 0;
buddy[0].pFirstPage = NULL;
buddy[1].type = MEMORY_BUDDY_TYPE_128K;
buddy[1].num = 0;
buddy[1].pFirstPage = NULL;
buddy[2].type = MEMORY_BUDDY_TYPE_256K;
buddy[2].num = 0;
buddy[2].pFirstPage = NULL;
buddy[3].type = MEMORY_BUDDY_TYPE_512K;
buddy[3].num = 0;
buddy[3].pFirstPage = NULL;
// 1547个4k的page可生成6个1024k的buddy
// 6个1024k的buddy利用了1536个4k的page
buddy[4].type = MEMORY_BUDDY_TYPE_1024K;
buddy[4].num = 6;
buddy[4].pFirstPage = (struct memory_page *)MEMORY_PAGE_DESCRIPTOR_START_VIRTUAL_ADDR;
pPage = buddy[4].pFirstPage;
for (i = 0; i < buddy[4].num * (buddy[4].type / MEMORY_PAGE_BYTES); i ++)
{
// printk("i:%a,page vAddr:%a\n",i,pPage->vAddr);
pPage->flag = MEMORY_PAGE_FLAG_BUSY;
if (i == buddy[4].num * (buddy[4].type / MEMORY_PAGE_BYTES) - 1)
{
pPage->pNextPage = NULL;
}
else
{
pPage->pNextPage = pPage + 1;
pPage = pPage->pNextPage;
}
}
}
// 分配指定的buddy
static inline struct memory_page *memory_malloc_buddy_p(struct memory_buddy *buddyAddr)
{
if (buddyAddr == NULL)
{
return(NULL);
}
struct memory_page *pPage = NULL;
struct memory_buddy *pBuddy = buddyAddr;
// 无指定的buddy
if (pBuddy->num < 1)
{
return(NULL);
}
// 有一个指定的buddy
else if (pBuddy->num == 1)
{
pPage = pBuddy->pFirstPage;
for (;;)
{
if (pPage == NULL)
{
break;
}
pPage->flag = MEMORY_PAGE_FLAG_DIRTY;
pPage = pPage->pNextPage;
}
pPage = pBuddy->pFirstPage;
pBuddy->pFirstPage = NULL;
pBuddy->num = 0;
return(pPage);
}
// 有多个指定的buddy
else if (pBuddy->num > 1)
{
pPage = (pBuddy->pFirstPage) + (pBuddy->num - 1) * (pBuddy->type / MEMORY_PAGE_BYTES) - 1;
pPage->pNextPage = NULL;
pPage = (pBuddy->pFirstPage) + (pBuddy->num - 1) * (pBuddy->type / MEMORY_PAGE_BYTES);
for (;;)
{
if (pPage == NULL)
{
break;
}
pPage->flag = MEMORY_PAGE_FLAG_DIRTY;
pPage = pPage->pNextPage;
}
pPage = (pBuddy->pFirstPage) + (pBuddy->num - 1) * (pBuddy->type / MEMORY_PAGE_BYTES);
pBuddy->num --;
return(pPage);
}
}
static inline struct memory_page *memory_malloc_buddy_recurse(struct memory_buddy *buddyAddr)
{
if (buddyAddr == NULL)
{
return(NULL);
}
struct memory_page *pFirstPage = NULL;
struct memory_buddy *pBuddy = buddyAddr;
// 若当前大小的buddy个数大于1
if (pBuddy->num >= 1)
{
pFirstPage = memory_malloc_buddy_p(pBuddy);
return(pFirstPage);
}
// 若当前大小的buddy个数等于0
else if (pBuddy->num == 0)
{
// 递归分配大小高一级的buddy
pFirstPage = memory_malloc_buddy_recurse(pBuddy + 1);
// 分配大小高一级的buddy失败
if (pFirstPage == NULL)
{
return(NULL);
}
// 分配大小高一级的buddy成功
else
{
pBuddy->pFirstPage = pFirstPage;
pBuddy->num = (pBuddy->num) + 2;
pFirstPage = memory_malloc_buddy_p(pBuddy);
return(pFirstPage);
}
}
}
static inline struct memory_page *memory_malloc_buddy(unsigned int type)
{
struct memory_page *pHeadPage = NULL;
switch (type)
{
case MEMORY_BUDDY_TYPE_64K:
pHeadPage = memory_malloc_buddy_recurse(&buddy[0]);
break;
case MEMORY_BUDDY_TYPE_128K:
pHeadPage = memory_malloc_buddy_recurse(&buddy[1]);
break;
case MEMORY_BUDDY_TYPE_256K:
pHeadPage = memory_malloc_buddy_recurse(&buddy[2]);
break;
case MEMORY_BUDDY_TYPE_512K:
pHeadPage = memory_malloc_buddy_recurse(&buddy[3]);
break;
case MEMORY_BUDDY_TYPE_1024K:
pHeadPage = memory_malloc_buddy_recurse(&buddy[4]);
break;
default:
break;
}
return(pHeadPage);
}
// 获取由pFirstPage指定的buddy的大小类型
static inline unsigned int memory_get_buddy_type(struct memory_page *pFirstPage)
{
if (pFirstPage == NULL)
{
return(0);
}
if (((pFirstPage + (MEMORY_BUDDY_TYPE_64K / MEMORY_PAGE_BYTES) - 1)->pNextPage) == NULL)
{
return(MEMORY_BUDDY_TYPE_64K);
}
if (((pFirstPage + (MEMORY_BUDDY_TYPE_128K / MEMORY_PAGE_BYTES) - 1)->pNextPage) == NULL)
{
return(MEMORY_BUDDY_TYPE_128K);
}
if (((pFirstPage + (MEMORY_BUDDY_TYPE_256K / MEMORY_PAGE_BYTES) - 1)->pNextPage) == NULL)
{
return(MEMORY_BUDDY_TYPE_256K);
}
if (((pFirstPage + (MEMORY_BUDDY_TYPE_512K / MEMORY_PAGE_BYTES) - 1)->pNextPage) == NULL)
{
return(MEMORY_BUDDY_TYPE_512K);
}
if (((pFirstPage + (MEMORY_BUDDY_TYPE_1024K / MEMORY_PAGE_BYTES) - 1)->pNextPage) == NULL)
{
return(MEMORY_BUDDY_TYPE_1024K);
}
}
// 将由pFirstPage指定的buddy追加到pBuddy尾部
static inline void memory_append_buddy(struct memory_buddy *pBuddy,struct memory_page *pFirstPage)
{
if ((pBuddy == NULL) || (pFirstPage == NULL))
{
return;
}
if (pBuddy->num == 0)
{
pBuddy->pFirstPage = pFirstPage;
pBuddy->num ++;
}
else if (pBuddy->num > 0)
{
(pBuddy->pFirstPage + ((pBuddy->num) * (pBuddy->type) / MEMORY_PAGE_BYTES - 1))->pNextPage = pFirstPage;
pBuddy->num ++;
}
}
// 释放由pFirstPage指定的buddy
static inline void memory_free_buddy(struct memory_page *pFirstPage)
{
if (pFirstPage == NULL)
{
return;
}
struct memory_page *pTmpPage = pFirstPage;
unsigned int buddyType = memory_get_buddy_type(pFirstPage);
if (!MEMORY_IS_BUDDY_TYPE(buddyType))
{
return;
}
// 设置每个待释放的page的flag
for (;;)
{
if (pTmpPage == NULL)
{
break;
}
pTmpPage->flag = MEMORY_PAGE_FLAG_BUSY;
pTmpPage = pTmpPage->pNextPage;
}
// 将待释放的page加到对应的buddy尾部
if (buddyType == MEMORY_BUDDY_TYPE_64K)
{
memory_append_buddy(&buddy[0],pFirstPage);
}
else if (buddyType == MEMORY_BUDDY_TYPE_128K)
{
memory_append_buddy(&buddy[1],pFirstPage);
}
else if (buddyType == MEMORY_BUDDY_TYPE_256K)
{
memory_append_buddy(&buddy[2],pFirstPage);
}
else if (buddyType == MEMORY_BUDDY_TYPE_512K)
{
memory_append_buddy(&buddy[3],pFirstPage);
}
else if (buddyType == MEMORY_BUDDY_TYPE_1024K)
{
memory_append_buddy(&buddy[4],pFirstPage);
}
// 较小的两块buddy合并为一块较大的buddy
unsigned int i = 0;
for (i = 0;i < MEMORY_BUDDY_TYPE_NUM - 1; i ++)
{
if (buddy[i].num == 2)
{
pTmpPage = buddy[i].pFirstPage;
buddy[i].pFirstPage = NULL;
buddy[i].num = 0;
memory_append_buddy(&buddy[i + 1],pTmpPage);
}
}
}
static inline void memory_print_buddy(void)
{
int i = 0;
for (i = 0; i < MEMORY_BUDDY_TYPE_NUM; i ++)
{
printk("type:%a,num:%a\n",buddy[i].type,buddy[i].num);
}
}
// 由指定字节数分配buddy,实际返回构成该buddy的第一个page的虚拟地址
void *memory_malloc(unsigned int bytes)
{
struct memory_page *pPage = NULL;
if ((bytes > 0) && (bytes <= MEMORY_BUDDY_TYPE_64K))
{
pPage = memory_malloc_buddy(MEMORY_BUDDY_TYPE_64K);
return((void *)(pPage->vAddr));
}
else if ((bytes > MEMORY_BUDDY_TYPE_64K) && (bytes <= MEMORY_BUDDY_TYPE_128K))
{
pPage = memory_malloc_buddy(MEMORY_BUDDY_TYPE_128K);
return((void *)(pPage->vAddr));
}
else if ((bytes > MEMORY_BUDDY_TYPE_128K) && (bytes <= MEMORY_BUDDY_TYPE_256K))
{
pPage = memory_malloc_buddy(MEMORY_BUDDY_TYPE_256K);
return((void *)(pPage->vAddr));
}
else if ((bytes > MEMORY_BUDDY_TYPE_256K) && (bytes <= MEMORY_BUDDY_TYPE_512K))
{
pPage = memory_malloc_buddy(MEMORY_BUDDY_TYPE_512K);
return((void *)(pPage->vAddr));
}
else if ((bytes > MEMORY_BUDDY_TYPE_512K) && (bytes <= MEMORY_BUDDY_TYPE_1024K))
{
pPage = memory_malloc_buddy(MEMORY_BUDDY_TYPE_1024K);
return((void *)(pPage->vAddr));
}
else
{
return(NULL);
}
}
// 根据page的虚拟地址释放buddy
void memory_free(void *vAddr)
{
// page的虚拟地址
unsigned int pageAddr = (unsigned int)vAddr;
// 对应的首个page描述体地址
struct memory_page *pPage;
unsigned int i = 0;
for (i = 0; i < MEMORY_PAGE_NUM; i ++)
{
pPage = (struct memory_page *)MEMORY_PAGE_DESCRIPTOR_START_VIRTUAL_ADDR + i;
if (pPage->vAddr == pageAddr)
{
break;
}
}
memory_free_buddy(pPage);
}
void memory_init(void)
{
memory_init_all_page();
memory_init_all_buddy();
}
void memory_test(void)
{
// printk("MEMORY_PAGE_NUM:%a\n",MEMORY_PAGE_NUM);
memory_init();
memory_print_buddy();
struct memory_page *pPage1 = NULL;
pPage1 = memory_malloc_buddy(MEMORY_BUDDY_TYPE_1024K);
memory_print_buddy();
struct memory_page *pPage2 = NULL;
pPage2 = memory_malloc_buddy(MEMORY_BUDDY_TYPE_64K);
memory_print_buddy();
struct memory_page *pPage3 = NULL;
pPage3 = memory_malloc_buddy(MEMORY_BUDDY_TYPE_256K);
memory_print_buddy();
struct memory_page *pPage4 = NULL;
pPage4 = memory_malloc_buddy(MEMORY_BUDDY_TYPE_256K);
memory_print_buddy();
char *p1 = (char *)memory_malloc(100 * 1024);
if (p1 == NULL)
{
printk("memory_malloc return NULL\n");
return;
}
memory_print_buddy();
memory_free(p1);
memory_print_buddy();
}
storage.h
#ifndef _STORAGE_H_
#define _STORAGE_H_
// 存储设备最大个数
#define STORAGE_DEVICE_NUM_MAX 1
// 存储设备描述体
typedef struct storage_device
{
// 存储设备的虚拟地址
unsigned int vAddr;
// 存储容量
unsigned int storageBytes;
// 触发读写的最小字节数
unsigned int baseBytes;
// 从存储设备读出数据的函数指针
int (*DoOut)(struct storage_device *pDevice,unsigned int offset,void *buf,unsigned int bytes);
// 往存储设备写入数据的函数指针
int (*DoIn)(struct storage_device *pDevice,unsigned int offset,void *buf,unsigned int bytes);
}sd_t;
// 注册存储设备函数
extern int StorageRegister(sd_t *pDevice,int no);
// 去注册存储设备函数(指定编号)
extern int StorageUnregister(int no);
// 外部可访问的存储设备指针数组
extern sd_t *pStorageDeviceArray[STORAGE_DEVICE_NUM_MAX];
#endif // _STORAGE_H_
storage.c
#include "types.h"
#include "storage.h"
// 外部可访问的存储设备指针数组
sd_t *pStorageDeviceArray[STORAGE_DEVICE_NUM_MAX];
// 注册存储设备函数
int StorageRegister(sd_t *pDevice,int no)
{
if ((pDevice == NULL) || (no < 0 ) || (no >= STORAGE_DEVICE_NUM_MAX))
{
return(ERR_RET);
}
pStorageDeviceArray[no] = pDevice;
return(SUC_RET);
}
// 去注册存储设备函数(指定编号)
int StorageUnregister(int no)
{
if ((no < 0 ) || (no >= STORAGE_DEVICE_NUM_MAX))
{
return(ERR_RET);
}
pStorageDeviceArray[no] = NULL;
return(SUC_RET);
}
ram_disk.c
#include "types.h"
#include "storage.h"
#include "string.h"
extern void printk(char *fmt,...);
extern void mmu_remaping(unsigned int pAddr,unsigned int vAddr,unsigned int bytes);
// 使用ram模拟的disk的在存储设备指针数组的编号
#define RAM_DISK_NO 0
// 使用ram模拟的disk描述体(外部可访问)
sd_t ramDisk;
static int RamDiskDoIn(sd_t *pRam,unsigned int offset,void *buf,unsigned int bytes)
{
if ((pRam == NULL) || (buf == NULL))
{
return(ERR_RET);
}
if (bytes < (pRam->baseBytes))
{
return(ERR_RET);
}
int ret = ERR_RET;
ret = memncpy(buf,(char *)(pRam->vAddr + offset),bytes);
return(ret);
}
static int RamDiskDoOut(sd_t *pRam,unsigned int offset,void *buf,unsigned int bytes)
{
if ((pRam == NULL) || (buf == NULL))
{
return(ERR_RET);
}
if (bytes < (pRam->baseBytes))
{
return(ERR_RET);
}
int ret = ERR_RET;
ret = memncpy((char *)(pRam->vAddr + offset),buf,bytes);
return(ret);
}
int RamDiskInit(void)
{
int ret = ERR_RET;
ramDisk.vAddr = 0x40800000;
ramDisk.storageBytes = 2 * 1024 * 1024;
ramDisk.baseBytes = 1;
ramDisk.DoIn = RamDiskDoIn;
ramDisk.DoOut = RamDiskDoOut;
// printk("ramDisk.vAddr:%a\n",ramDisk.vAddr);
mmu_remaping(0x30800000,0x40800000,ramDisk.storageBytes);
ret = StorageRegister(&ramDisk,RAM_DISK_NO);
return(ret);
}
int RamDiskRead(unsigned int offset,void *buf,unsigned int bytes)
{
if (buf == NULL)
{
return(ERR_RET);
}
int ret = ERR_RET;
ret = ramDisk.DoOut(&ramDisk,offset,buf,bytes);
return(ret);
}
int RamDiskWrite(unsigned int offset,void *buf,unsigned int bytes)
{
if (buf == NULL)
{
return(ERR_RET);
}
int ret = ERR_RET;
ret = ramDisk.DoIn(&ramDisk,offset,buf,bytes);
return(ret);
}
void RamDiskTest(void)
{
int ret = ERR_RET;
ret = RamDiskInit();
if (ret != SUC_RET)
{
printk("RamDiskInit error\n");
return;
}
printk("RamDiskInit success\n");
char buf[64];
ret = RamDiskRead(0,buf,64);
if (ret != SUC_RET)
{
printk("RamDiskRead error\n");
return;
}
printk("read buf:%s\n",buf);
// char *s = "hello_ramdisk";
// ret = memncpy(s,buf,13);
// if (ret != SUC_RET)
// {
// printk("memcpy error\n");
// return;
// }
// ret = RamDiskWrite(0,buf,64);
// if (ret != SUC_RET)
// {
// printk("RamDiskWrite error\n");
// return;
// }
// ret = RamDiskRead(0,buf,64);
// if (ret != SUC_RET)
// {
// printk("RamDiskRead error\n");
// return;
// }
// printk("read:%s\n",buf);
}
file_system.h
#ifndef _FILE_SYSTEM_H_
#define _FILE_SYSTEM_H_
#include "storage.h"
// 文件系统最大个数
#define FS_NUM_MAX 1
struct inode;
// 文件系统描述体
typedef struct super_block
{
// 文件系统名
char *name;
// 文件系统存储设备
struct storage_device *pDevice;
// 通过inode获取数据地址的函数指针
unsigned int (*GetDataAddr)(struct inode *pInode);
// 通过文件名获取inode的函数指针
struct inode *(*NameToInode)(char *name);
}fs_t;
// 文件描述体
typedef struct inode
{
// 文件名
char *name;
// 控制标识
unsigned int flags;
// 文件的数据大小
unsigned int size;
// 文件数据地址(相对设备地址)
unsigned int offset;
// 文件所属的文件系统的指针
struct super_block *pFs;
}file_t;
// 注册文件系统
int FsRegister(fs_t *pFs,int no);
// 去注册文件系统
int FsUnregister(int no);
// 打印文件系统名
void FsPrint(void);
// 外部可访问的文件系统指针数组
extern fs_t *pFsArray[FS_NUM_MAX];
#endif // _FILE_SYSTEM_H_
file_system.c
#include "types.h"
#include "file_system.h"
extern void printk(char *fmt,...);
fs_t *pFsArray[FS_NUM_MAX];
// 注册文件系统
int FsRegister(fs_t *pFs,int no)
{
if ((pFs == NULL) || (no < 0) || (no >= FS_NUM_MAX))
{
return(ERR_RET);
}
pFsArray[no] = pFs;
return(SUC_RET);
}
// 去注册文件系统
int FsUnregister(int no)
{
if ((no < 0) || (no >= FS_NUM_MAX))
{
return(ERR_RET);
}
pFsArray[no] = NULL;
return(SUC_RET);
}
// 打印文件系统名
void FsPrint(void)
{
unsigned int i = 0;
for (i = 0; i < FS_NUM_MAX; i ++)
{
if ((pFsArray[i]->name) == NULL)
{
printk("index:%a,file_system:NULL\n",i);
}
else
{
printk("index:%a,file_system:%s\n",i,pFsArray[i]->name);
}
}
}
vfs.c
#include "types.h"
#include "storage.h"
#include "file_system.h"
#include "string.h"
extern int RamDiskInit(void);
extern void memory_init(void);
extern void printk(char *fmt,...);
extern void *memory_malloc(unsigned int bytes);
extern void memory_free(void *p);
void vfs_print(void);
extern sd_t ramDisk;
// ----------------------------------------------
// vfs存储结构
// vfs文件系统头
// 文件:文件头,文件数据
#define VFS_FLAG "-vfsvfs-"
#define VFS_NAME_BYTES 8
// 文件系统头
typedef struct vfs_head
{
// 文件系统名
char name[VFS_NAME_BYTES];
// 磁盘存储的文件数
unsigned int fileNum;
}vfs_head_t;
#define VFS_FILE_NAME_BYTES 16
// 文件头
typedef struct vfs_file_head
{
// 文件名
char name[VFS_FILE_NAME_BYTES];
// 文件字节数
unsigned int bytes;
}vfs_file_head_t;
// ----------------------------------------------
fs_t vFS;
// LFS文件系统描述体在文件系统指针数组里的编号
#define VFS_NO 0
// LFS文件系统文件数量
static unsigned int vfsFileNum;
// LFS文件系统文件描述体指针
static file_t *pVFSInode;
static inline struct inode *VFSNameToInode(char *name)
{
if (name == NULL)
{
return(NULL);
}
unsigned int i = 0;
unsigned int n = 0;
for (i = 0; i < vfsFileNum; i ++)
{
n = strlen(name);
if (memncmp(name,pVFSInode[i].name,n) == SUC_RET)
{
return(&pVFSInode[i]);
}
}
return(NULL);
}
static inline unsigned int VFSGetDataAddr(struct inode *pInode)
{
if (pInode == NULL)
{
return(0);
}
return(pInode->offset + (vFS.pDevice)->vAddr);
}
// VFS文件系统初始化
int VFSInit(void)
{
int ret = ERR_RET;
unsigned int i = 0;
unsigned int j = 0;
// ramDisk盘初始化(VFS存放在ramDisk盘)
ret = RamDiskInit();
if (ret != SUC_RET)
{
printk("[VFSInit],RamDiskInit error\n");
return(ERR_RET);
}
printk("RamDiskInit success\n");
// 文件系统的文件依赖memory功能
memory_init();
printk("memory_init success\n");
// 初始化vFS
vFS.pDevice = &ramDisk;
vFS.NameToInode = VFSNameToInode;
vFS.GetDataAddr = VFSGetDataAddr;
vFS.name = (char *)memory_malloc(VFS_NAME_BYTES + 1);
if (vFS.name == NULL)
{
printk("[VFSInit],vFS.name memory_malloc error\n");
return(ERR_RET);
}
ret = memnset(vFS.name,'\0',VFS_NAME_BYTES + 1);
if (ret != SUC_RET)
{
printk("[VFSInit],vFS.name memnset error\n");
memory_free(vFS.name);
return(ERR_RET);
}
ret = memncpy("vfs",vFS.name,3);
if (ret != SUC_RET)
{
printk("[VFSInit],vFS.name memncpy error\n");
memory_free(vFS.name);
return(ERR_RET);
}
// printk("vFS.name:%s\n",vFS.name);
printk("init vFS success\n");
// 判断磁盘里是否为vfs
vfs_head_t *pVFSHead = (vfs_head_t *)((vFS.pDevice)->vAddr);
// printk("(vFS.pDevice)->vAddr:%a\n",(vFS.pDevice)->vAddr);
// printk("pVFSHead:%a\n",pVFSHead);
ret = memncmp(pVFSHead->name,VFS_FLAG,VFS_NAME_BYTES);
if (ret == ERR_RET)
{
printk("not vfs in disk\n");
memory_free(vFS.name);
return(ERR_RET);
}
printk("vfs in disk\n");
vfsFileNum = pVFSHead->fileNum;
printk("vfsFileNum:%a\n",vfsFileNum);
if (vfsFileNum >= 1)
{
pVFSInode = (file_t *)memory_malloc(sizeof(file_t) * vfsFileNum);
if (pVFSInode == NULL)
{
printk("memory_malloc error\n");
memory_free(vFS.name);
return(ERR_RET);
}
// printk("pVFSInode:%a\n",pVFSInode);
vfs_file_head_t *pVFSFileHead = (vfs_file_head_t *)((char *)pVFSHead + sizeof(vfs_head_t));
// printk("pVFSFileHead:%a\n",pVFSFileHead);
for (i = 0; i < vfsFileNum; i ++)
{
// 设置inode属于的文件系统
pVFSInode[i].pFs = &vFS;
// 为inode的文件名分配空间
pVFSInode[i].name = (char *)memory_malloc(VFS_FILE_NAME_BYTES + 1);
if (pVFSInode[i].name == NULL)
{
printk("memory_malloc error,i:%a\n",i);
// 释放已经分配的inode的名字内存
for (j = 0; j < i; j ++)
{
memory_free(pVFSInode[j].name);
}
memory_free(pVFSInode);
pVFSInode = NULL;
memory_free(vFS.name);
vFS.name = NULL;
return(ERR_RET);
}
printk("inode[%a] name malloc success\n",i);
ret = memnset(pVFSInode[i].name,'\0',VFS_FILE_NAME_BYTES + 1);
if (ret != SUC_RET)
{
printk("memnset error,i:%a\n",i);
// 释放已经分配的inode的名字内存
for (j = 0; j < i; j ++)
{
memory_free(pVFSInode[j].name);
}
memory_free(pVFSInode);
pVFSInode = NULL;
memory_free(vFS.name);
vFS.name = NULL;
return(ERR_RET);
}
printk("inode[%a] name memnset success\n",i);
// 获取文件名
ret = memncpy(pVFSFileHead->name,pVFSInode[i].name,VFS_FILE_NAME_BYTES);
if (ret != SUC_RET)
{
printk("memncpy error,i:%a\n",i);
// 释放已经分配的inode的名字内存
for (j = 0; j < i; j ++)
{
memory_free(pVFSInode[j].name);
}
memory_free(pVFSInode);
pVFSInode = NULL;
memory_free(vFS.name);
vFS.name = NULL;
return(ERR_RET);
}
printk("inode[%a] name memncpy success\n",i);
// printk("pVFSInode[%a].name:%s\n",i,pVFSInode[i].name);
// printk("pVFSFileHead->bytes:%a\n",pVFSFileHead->bytes);
pVFSInode[i].offset = (unsigned int)((char *)pVFSFileHead + sizeof(vfs_file_head_t) - (char *)pVFSHead);
pVFSInode[i].size = pVFSFileHead->bytes;
pVFSInode[i].flags = (unsigned int)0;
pVFSFileHead = (vfs_file_head_t *)((char *)pVFSFileHead + sizeof(vfs_file_head_t) + (pVFSFileHead->bytes));
}
}
// 注册LFS文件系统
ret = FsRegister(&vFS,VFS_NO);
if (ret != SUC_RET)
{
printk("FsRegister error\n");
for(i = 0; i < vfsFileNum; i ++)
{
memory_free(pVFSInode[i].name);
memory_free(&pVFSInode[i]);
}
memory_free(vFS.name);
}
printk("vfs registered\n");
vfs_print();
return(SUC_RET);
}
void vfs_print(void)
{
unsigned int i = 0;
for (i = 0; i < vfsFileNum; i ++)
{
printk("i:%a,name:%s,bytes:%a,offset:%a,addr:%a\n",i,pVFSInode[i].name,pVFSInode[i].size,pVFSInode[i].offset,vFS.GetDataAddr(&pVFSInode[i]));
}
}
void vfs_test(void)
{
int ret = ERR_RET;
ret = VFSInit();
if (ret != SUC_RET)
{
printk("VFSInit error\n");
return;
}
vfs_print();
}
excute.c
#include "types.h"
#include "file_system.h"
#include "elf.h"
extern fs_t vFS;
extern int VFSInit(void);
extern void printk(char *fmt,...);
extern int memncpy(void *srcAddr,void *desAddr,unsigned int nBytes);
#define EXCUTE_ADDR 0x30100000
int excute(unsigned int addr)
{
asm volatile
(
"mov pc,r0\n\t"
);
printk("main returned\n");
return(0);
}
void excute_test_bin(void)
{
int ret = -1;
file_t *pFile = NULL;
ret = VFSInit();
if (ret == ERR_RET)
{
printk("VFSInit error\n");
return;
}
printk("VFSInit success\n");
pFile = vFS.NameToInode("user_main.bin");
if (pFile == NULL)
{
printk("vFS.NameToInode error\n");
return;
}
printk("vFS.NameToInode sucess\n");
ret = memncpy((char *)(vFS.GetDataAddr(pFile)),(char *)EXCUTE_ADDR,pFile->size);
if (ret == ERR_RET)
{
printk("memncpy error\n");
return;
}
printk("memncpy success\n");
excute(EXCUTE_ADDR);
return;
}
void excute_test_elf(void)
{
int ret = -1;
file_t *pFile = NULL;
struct elf32_ehdr *pELF32Head = NULL;
struct elf32_phdr *pELF32ProgramHead = NULL;
unsigned int i = 0;
ret = VFSInit();
if (ret == ERR_RET)
{
printk("VFSInit error\n");
return;
}
printk("VFSInit success\n");
pFile = vFS.NameToInode("user_main.elf");
if (pFile == NULL)
{
printk("vFS.NameToInode error\n");
return;
}
printk("vFS.NameToInode sucess\n");
pELF32Head = (struct elf32_ehdr *)(vFS.GetDataAddr(pFile));
pELF32ProgramHead = (struct elf32_phdr *)((char *)pELF32Head + pELF32Head->e_phoff);
// printk("pELF32Head:%a\n",pELF32Head);
// printk("vFS.GetDataAddr(pFile):%a\n",vFS.GetDataAddr(pFile));
// printk("pELF32Head->e_phoff:%a\n",pELF32Head->e_phoff);
// printk("pELF32ProgramHead:%a\n",pELF32ProgramHead);
// printk("pELF32Head->e_phnum:%a\n",pELF32Head->e_phnum);
for (i = 0; i < pELF32Head->e_phnum; i ++)
{
// printk("i:%a\n",i);
// printk("pELF32ProgramHead->p_type:%d\n",pELF32ProgramHead->p_type);
if (pELF32ProgramHead->p_type == PT_LOAD)
{
ret = memncpy((char *)pELF32Head + pELF32ProgramHead->p_offset,(char *)(pELF32ProgramHead->p_vaddr),pELF32ProgramHead->p_filesz);
if (ret == ERR_RET)
{
printk("%a,memncpy error\n",i);
return;
}
printk("%a,memncpy success\n",i);
pELF32ProgramHead ++;
}
}
// printk("pELF32Head->e_entry:%a\n",pELF32Head->e_entry);
excute(pELF32Head->e_entry);
return;
}
os_system_call.c
// 内核系统调用调度
#include "types.h"
extern void printk(char *fmt,...);
#define SYSTEM_CALL_TYPE_PRINT 0 //系统调用类型:打印
#define SYSTEM_CALL_TYPE_IO 1 //系统调用类型:IO
#define SYSTEM_CALL_TYPE_NUM 2 //系统调用类型总数
#define SYSTEM_CALL_RET_ERE -1
#define SYSTEM_CALL_RET_SUC 0
// 内核系统调用执行函数的类型
// 返回值类型为:int
// num:传递给内核系统调用执行函数的参数个数
// args:传递内核系统调用执行函数的参数指针
typedef int (*system_call_fun_t)(int argc,int *args);
// ----------系统调用类型执行函数声明开始---------- //
int OSPrint(int argc,int *args);
int OSIO(int argc,int *args);
// ----------系统调用类型执行函数声明结束---------- //
// 系统调用执行函数表
system_call_fun_t systemCallTalbe[SYSTEM_CALL_TYPE_NUM] = {
(system_call_fun_t)OSPrint,
// (system_call_fun_t)OSIO,
NULL,
};
// 系统调用调度
// type:系统调用函数表的索引值,系统调用号
// argc:传递给系统调用执行函数的参数个数
// args:传递给系统调用执行函数的参数指针
int os_system_call(int type,int argc,int *args)
{
printk("[os_system_call],type:%d,argc:%d,args:%a\n",type,argc,args);
if (systemCallTalbe[type])
{
return((systemCallTalbe[type])(argc,args));
}
}
int OSPrint(int argc,int *args)
{
printk("this in OSPrint,argc:%d,args:%a\n",argc,args);
return(SYSTEM_CALL_RET_SUC);
}
leeos.lds
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
.text :
{
*(.startup)
*(.text)
}
. = ALIGN(32);
.data :
{
*(.data)
}
. = ALIGN(32);
__bss_start__ = .;
.bss :
{
*(.bss)
}
__bss_end__ = .;
}
makefile
CC = arm-none-eabi-gcc
LD = arm-none-eabi-ld
OBJCOPY = arm-none-eabi-objcopy
CFLAGS = -O0 -g
ASFLAGS = -O0 -g
LDFLAGS = -T leeos.lds -Ttext 30000000
OBJS = abnormal.o start.o init.o boot.o \
mmu.o \
printk.o \
string.o \
interrupt.o \
memory.o \
storage.o \
ram_disk.o \
file_system.o \
vfs.o \
excute.o \
os_system_call.o \
.c.o:
$(CC) $(CFLAGS) -c $<
.s.o:
$(CC) $(ASFLAGS) -c $<
leeos.elf:$(OBJS)
$(CC) -static -nostartfiles -nostdlib $(LDFLAGS) $? -o $@
$(OBJCOPY) -O binary $@ leeos.bin
clean:
rm -f *.o leeos.elf leeos.bin
skyeye.conf
cpu: arm920t
mach: s3c2410x
#physical memory
#memroy bar
mem_bank: map = M, type = RW, addr = 0x30000000, size = 0x00800000, file = ./leeos.bin, boot = yes
#ramdisk
mem_bank: map = M, type = RW, addr = 0x30800000, size = 0x00200000, file = ./ramdisk.img
#io
mem_bank: map = I, type = RW, addr = 0x48000000, size = 0x20000000