From fc6e6e6acf93d7bdbfede0a3c254c748467a4fb9 Mon Sep 17 00:00:00 2001 From: zhoujie Date: Wed, 27 Mar 2019 15:49:33 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E8=99=9A=E6=8B=9F=E5=B9=B3=E5=8F=B0?= =?UTF-8?q?=E4=B8=8B=E4=BD=BF=E7=94=A8APIC=E7=AE=A1=E7=90=86=E4=B8=AD?= =?UTF-8?q?=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/8259A.c | 50 ++++++ kernel/8259A.h | 11 ++ kernel/APIC.c | 410 +++++++++++++++++++++++++++++++++++++++++++++ kernel/APIC.h | 280 +++++++++++++++++++++++++++++++ kernel/interrupt.c | 85 +++++----- kernel/interrupt.h | 63 ++++++- 6 files changed, 854 insertions(+), 45 deletions(-) create mode 100644 kernel/8259A.c create mode 100644 kernel/8259A.h create mode 100755 kernel/APIC.c create mode 100755 kernel/APIC.h mode change 100644 => 100755 kernel/interrupt.c mode change 100644 => 100755 kernel/interrupt.h diff --git a/kernel/8259A.c b/kernel/8259A.c new file mode 100644 index 0000000..142570f --- /dev/null +++ b/kernel/8259A.c @@ -0,0 +1,50 @@ +#include "interrupt.h" +#include "linkage.h" +#include "lib.h" +#include "printk.h" +#include "memory.h" +#include "gate.h" +#include "ptrace.h" + +void init_8259A() +{ + int i; + for(i = 32;i < 56;i++) + { + set_intr_gate(i , 2 , interrupt[i - 32]); + } + + color_printk(RED,BLACK,"8259A init \n"); + + //8259A-master ICW1-4 + io_out8(0x20,0x11); + io_out8(0x21,0x20); + io_out8(0x21,0x04); + io_out8(0x21,0x01); + + //8259A-slave ICW1-4 + io_out8(0xa0,0x11); + io_out8(0xa1,0x28); + io_out8(0xa1,0x02); + io_out8(0xa1,0x01); + + //8259A-M/S OCW1 + io_out8(0x21,0xfd); + io_out8(0xa1,0xff); + + sti(); +} + +/* + +*/ + +void do_IRQ(struct pt_regs * regs,unsigned long nr) //regs,nr +{ + unsigned char x; + color_printk(RED,BLACK,"do_IRQ:%#018lx\t",nr); + x = io_in8(0x60); + color_printk(RED,BLACK,"key code:%#018lx\t",x); + io_out8(0x20,0x20); + color_printk(RED,BLACK,"regs:%#018lx\t\n",regs,regs->rip,regs->rsp); +} \ No newline at end of file diff --git a/kernel/8259A.h b/kernel/8259A.h new file mode 100644 index 0000000..ce29314 --- /dev/null +++ b/kernel/8259A.h @@ -0,0 +1,11 @@ +#ifndef __8259A_H__ +#define __8259A_H__ + +#include "linkage.h" +#include "ptrace.h" + +void init_8259A(); + +void do_IRQ(struct pt_regs * regs,unsigned long nr); + +#endif diff --git a/kernel/APIC.c b/kernel/APIC.c new file mode 100755 index 0000000..c36314b --- /dev/null +++ b/kernel/APIC.c @@ -0,0 +1,410 @@ +/*************************************************** +* 版权声明 +* +* 本操作系统名为:MINE +* 该操作系统未经授权不得以盈利或非盈利为目的进行开发, +* 只允许个人学习以及公开交流使用 +* +* 代码最终所有权及解释权归田宇所有; +* +* 本模块作者: 田宇 +* EMail: 345538255@qq.com +* +* +***************************************************/ + +#include "interrupt.h" +#include "linkage.h" +#include "lib.h" +#include "printk.h" +#include "memory.h" +#include "gate.h" +#include "ptrace.h" +#include "cpu.h" +#include "APIC.h" + +/* + +*/ + +void IOAPIC_enable(unsigned long irq) +{ + unsigned long value = 0; + value = ioapic_rte_read((irq - 32) * 2 + 0x10); + value = value & (~0x10000UL); + ioapic_rte_write((irq - 32) * 2 + 0x10,value); +} + +void IOAPIC_disable(unsigned long irq) +{ + unsigned long value = 0; + value = ioapic_rte_read((irq - 32) * 2 + 0x10); + value = value | 0x10000UL; + ioapic_rte_write((irq - 32) * 2 + 0x10,value); +} + +unsigned long IOAPIC_install(unsigned long irq,void * arg) +{ + struct IO_APIC_RET_entry *entry = (struct IO_APIC_RET_entry *)arg; + ioapic_rte_write((irq - 32) * 2 + 0x10,*(unsigned long *)entry); + + return 1; +} + +void IOAPIC_uninstall(unsigned long irq) +{ + ioapic_rte_write((irq - 32) * 2 + 0x10,0x10000UL); +} + +void IOAPIC_level_ack(unsigned long irq) +{ + __asm__ __volatile__( "movq $0x00, %%rdx \n\t" + "movq $0x00, %%rax \n\t" + "movq $0x80b, %%rcx \n\t" + "wrmsr \n\t" + :::"memory"); + + *ioapic_map.virtual_EOI_address = 0; +} + +void IOAPIC_edge_ack(unsigned long irq) +{ + __asm__ __volatile__( "movq $0x00, %%rdx \n\t" + "movq $0x00, %%rax \n\t" + "movq $0x80b, %%rcx \n\t" + "wrmsr \n\t" + :::"memory"); +} + +/* + +*/ + +unsigned long ioapic_rte_read(unsigned char index) +{ + unsigned long ret; + + *ioapic_map.virtual_index_address = index + 1; + io_mfence(); + ret = *ioapic_map.virtual_data_address; + ret <<= 32; + io_mfence(); + + *ioapic_map.virtual_index_address = index; + io_mfence(); + ret |= *ioapic_map.virtual_data_address; + io_mfence(); + + return ret; +} + +/* + +*/ + +void ioapic_rte_write(unsigned char index,unsigned long value) +{ + *ioapic_map.virtual_index_address = index; + io_mfence(); + *ioapic_map.virtual_data_address = value & 0xffffffff; + value >>= 32; + io_mfence(); + + *ioapic_map.virtual_index_address = index + 1; + io_mfence(); + *ioapic_map.virtual_data_address = value & 0xffffffff; + io_mfence(); +} + +/* + +*/ + +void IOAPIC_pagetable_remap() +{ + unsigned long * tmp; + unsigned char * IOAPIC_addr = (unsigned char *)Phy_To_Virt(0xfec00000); + + ioapic_map.physical_address = 0xfec00000; + ioapic_map.virtual_index_address = IOAPIC_addr; + ioapic_map.virtual_data_address = (unsigned int *)(IOAPIC_addr + 0x10); + ioapic_map.virtual_EOI_address = (unsigned int *)(IOAPIC_addr + 0x40); + + Global_CR3 = Get_gdt(); + + tmp = Phy_To_Virt(Global_CR3 + (((unsigned long)IOAPIC_addr >> PAGE_GDT_SHIFT) & 0x1ff)); + if (*tmp == 0) + { + unsigned long * virtual = kmalloc(PAGE_4K_SIZE,0); + set_mpl4t(tmp,mk_mpl4t(Virt_To_Phy(virtual),PAGE_KERNEL_GDT)); + } + + color_printk(YELLOW,BLACK,"1:%#018lx\t%#018lx\n",(unsigned long)tmp,(unsigned long)*tmp); + + tmp = Phy_To_Virt((unsigned long *)(*tmp & (~ 0xfffUL)) + (((unsigned long)IOAPIC_addr >> PAGE_1G_SHIFT) & 0x1ff)); + if(*tmp == 0) + { + unsigned long * virtual = kmalloc(PAGE_4K_SIZE,0); + set_pdpt(tmp,mk_pdpt(Virt_To_Phy(virtual),PAGE_KERNEL_Dir)); + } + + color_printk(YELLOW,BLACK,"2:%#018lx\t%#018lx\n",(unsigned long)tmp,(unsigned long)*tmp); + + tmp = Phy_To_Virt((unsigned long *)(*tmp & (~ 0xfffUL)) + (((unsigned long)IOAPIC_addr >> PAGE_2M_SHIFT) & 0x1ff)); + set_pdt(tmp,mk_pdt(ioapic_map.physical_address,PAGE_KERNEL_Page | PAGE_PWT | PAGE_PCD)); + + color_printk(BLUE,BLACK,"3:%#018lx\t%#018lx\n",(unsigned long)tmp,(unsigned long)*tmp); + + color_printk(BLUE,BLACK,"ioapic_map.physical_address:%#010x\t\t\n",ioapic_map.physical_address); + color_printk(BLUE,BLACK,"ioapic_map.virtual_address:%#018lx\t\t\n",(unsigned long)ioapic_map.virtual_index_address); + + flush_tlb(); +} + +/* + +*/ + +void Local_APIC_init() +{ + unsigned int x,y; + unsigned int a,b,c,d; + + //check APIC & x2APIC support + get_cpuid(1,0,&a,&b,&c,&d); + //void get_cpuid(unsigned int Mop,unsigned int Sop,unsigned int * a,unsigned int * b,unsigned int * c,unsigned int * d) + color_printk(WHITE,BLACK,"CPUID\t01,eax:%#010x,ebx:%#010x,ecx:%#010x,edx:%#010x\n",a,b,c,d); + + if((1<<9) & d) + color_printk(WHITE,BLACK,"HW support APIC&xAPIC\t"); + else + color_printk(WHITE,BLACK,"HW NO support APIC&xAPIC\t"); + + if((1<<21) & c) + color_printk(WHITE,BLACK,"HW support x2APIC\n"); + else + color_printk(WHITE,BLACK,"HW NO support x2APIC\n"); + + //enable xAPIC & x2APIC + __asm__ __volatile__( "movq $0x1b, %%rcx \n\t" + "rdmsr \n\t" + "bts $10, %%rax \n\t" + "bts $11, %%rax \n\t" + "wrmsr \n\t" + "movq $0x1b, %%rcx \n\t" + "rdmsr \n\t" + :"=a"(x),"=d"(y) + : + :"memory"); + + color_printk(WHITE,BLACK,"eax:%#010x,edx:%#010x\t",x,y); + + if(x&0xc00) + color_printk(WHITE,BLACK,"xAPIC & x2APIC enabled\n"); + + //enable SVR[8] + __asm__ __volatile__( "movq $0x80f, %%rcx \n\t" + "rdmsr \n\t" + "bts $8, %%rax \n\t" +// "bts $12, %%rax\n\t" + "wrmsr \n\t" + "movq $0x80f, %%rcx \n\t" + "rdmsr \n\t" + :"=a"(x),"=d"(y) + : + :"memory"); + + color_printk(WHITE,BLACK,"eax:%#010x,edx:%#010x\t",x,y); + + if(x&0x100) + color_printk(WHITE,BLACK,"SVR[8] enabled\n"); + if(x&0x1000) + color_printk(WHITE,BLACK,"SVR[12] enabled\n"); + + //get local APIC ID + __asm__ __volatile__( "movq $0x802, %%rcx \n\t" + "rdmsr \n\t" + :"=a"(x),"=d"(y) + : + :"memory"); + + color_printk(WHITE,BLACK,"eax:%#010x,edx:%#010x\tx2APIC ID:%#010x\n",x,y,x); + + //get local APIC version + __asm__ __volatile__( "movq $0x803, %%rcx \n\t" + "rdmsr \n\t" + :"=a"(x),"=d"(y) + : + :"memory"); + + color_printk(WHITE,BLACK,"local APIC Version:%#010x,Max LVT Entry:%#010x,SVR(Suppress EOI Broadcast):%#04x\t",x & 0xff,(x >> 16 & 0xff) + 1,x >> 24 & 0x1); + + if((x & 0xff) < 0x10) + color_printk(WHITE,BLACK,"82489DX discrete APIC\n"); + + else if( ((x & 0xff) >= 0x10) && ((x & 0xff) <= 0x15) ) + color_printk(WHITE,BLACK,"Integrated APIC\n"); + + //mask all LVT + __asm__ __volatile__( //"movq $0x82f, %%rcx \n\t" //CMCI + //"wrmsr \n\t" + "movq $0x832, %%rcx \n\t" //Timer + "wrmsr \n\t" + "movq $0x833, %%rcx \n\t" //Thermal Monitor + "wrmsr \n\t" + "movq $0x834, %%rcx \n\t" //Performance Counter + "wrmsr \n\t" + "movq $0x835, %%rcx \n\t" //LINT0 + "wrmsr \n\t" + "movq $0x836, %%rcx \n\t" //LINT1 + "wrmsr \n\t" + "movq $0x837, %%rcx \n\t" //Error + "wrmsr \n\t" + : + :"a"(0x10000),"d"(0x00) + :"memory"); + + color_printk(GREEN,BLACK,"Mask ALL LVT\n"); + + //TPR + __asm__ __volatile__( "movq $0x808, %%rcx \n\t" + "rdmsr \n\t" + :"=a"(x),"=d"(y) + : + :"memory"); + + color_printk(GREEN,BLACK,"Set LVT TPR:%#010x\t",x); + + //PPR + __asm__ __volatile__( "movq $0x80a, %%rcx \n\t" + "rdmsr \n\t" + :"=a"(x),"=d"(y) + : + :"memory"); + + color_printk(GREEN,BLACK,"Set LVT PPR:%#010x\n",x); +} + +/* + +*/ + +void IOAPIC_init() +{ + int i ; + // I/O APIC + // I/O APIC ID + *ioapic_map.virtual_index_address = 0x00; + io_mfence(); + *ioapic_map.virtual_data_address = 0x0f000000; + io_mfence(); + color_printk(GREEN,BLACK,"Get IOAPIC ID REG:%#010x,ID:%#010x\n",*ioapic_map.virtual_data_address, *ioapic_map.virtual_data_address >> 24 & 0xf); + io_mfence(); + + // I/O APIC Version + *ioapic_map.virtual_index_address = 0x01; + io_mfence(); + color_printk(GREEN,BLACK,"Get IOAPIC Version REG:%#010x,MAX redirection enties:%#08d\n",*ioapic_map.virtual_data_address ,((*ioapic_map.virtual_data_address >> 16) & 0xff) + 1); + + //RTE + for(i = 0x10;i < 0x40;i += 2) + ioapic_rte_write(i,0x10020 + ((i - 0x10) >> 1)); + + color_printk(GREEN,BLACK,"I/O APIC Redirection Table Entries Set Finished.\n"); +} + +/* + +*/ + +void APIC_IOAPIC_init() +{ + cli(); + // init trap abort fault + int i ; + unsigned int x; + unsigned int * p; + + IOAPIC_pagetable_remap(); + + for(i = 32;i < 56;i++) + { + set_intr_gate(i , 2 , interrupt[i - 32]); + } + + //8259A-master ICW1-4 + io_out8(0x20,0x11); + io_out8(0x21,0x20); + io_out8(0x21,0x04); + io_out8(0x21,0x01); + + //8259A-slave ICW1-4 + io_out8(0xa0,0x11); + io_out8(0xa1,0x28); + io_out8(0xa1,0x02); + io_out8(0xa1,0x01); + + // //复位主/从8259A中断控制器的中断屏蔽寄存器酌盟的全部中断屏蔽位 + // io_out8(0x21,0x00); + // io_out8(0xa1,0x00); + + // //8259A-M/S OCW1 + // io_out8(0x21,0xfd); + // io_out8(0xa1,0xff); + + //mask 8259A + color_printk(GREEN,BLACK,"MASK 8259A\n"); + io_out8(0x21,0xff); + io_out8(0xa1,0xff); + + //enable IMCR + io_out8(0x22,0x70); + io_out8(0x23,0x01); + + //init local apic + Local_APIC_init(); + + //init ioapic + IOAPIC_init(); + + // //get RCBA address + // io_out32(0xcf8,0x8000f8f0); + // x = io_in32(0xcfc); + // color_printk(RED,BLACK,"Get RCBA Address:%#010x\n",x); + // x = x & 0xffffc000; + // color_printk(RED,BLACK,"Get RCBA Address:%#010x\n",x); + + // x=0xfed1c000; + // //get OIC address + // if(x > 0xfec00000 && x < 0xfee00000) + // { + // p = (unsigned int *)Phy_To_Virt(x + 0x31feUL); + // } + + // //enable IOAPIC + // x = (*p & 0xffffff00) | 0x100; + // io_mfence(); + // *p = x; + // io_mfence(); + + memset(interrupt_desc,0,sizeof(irq_desc_T)*NR_IRQS); + + //open IF eflages + sti(); +} + +/* + +*/ + +void do_IRQ(struct pt_regs * regs,unsigned long nr) //regs:rsp,nr +{ + irq_desc_T * irq = &interrupt_desc[nr - 32]; + + if(irq->handler != NULL) + irq->handler(nr,irq->parameter,regs); + + if(irq->controller != NULL && irq->controller->ack != NULL) + irq->controller->ack(nr); +} + diff --git a/kernel/APIC.h b/kernel/APIC.h new file mode 100755 index 0000000..ff67485 --- /dev/null +++ b/kernel/APIC.h @@ -0,0 +1,280 @@ +/*************************************************** +* 版权声明 +* +* 本操作系统名为:MINE +* 该操作系统未经授权不得以盈利或非盈利为目的进行开发, +* 只允许个人学习以及公开交流使用 +* +* 代码最终所有权及解释权归田宇所有; +* +* 本模块作者: 田宇 +* EMail: 345538255@qq.com +* +* +***************************************************/ + +#ifndef __APIC_H__ +#define __APIC_H__ + +#include "linkage.h" +#include "ptrace.h" +#include "interrupt.h" + +/* + +0~255 IDT + +0 ~ 31 trap fault abort for system + 0 devide error + 1 debug + 2 NMI + 3 breakpoint + 4 overflow + 5 bound range + 6 undefined opcode + 7 device not available + 8 double fault + 9 coprocessor segment overrun + 10 invalid TSS + 11 segment not present + 12 stack segment fault + 13 general protection + 14 page fault + 15 + 16 x87 FPU error + 17 alignment check + 18 machine check + 19 SIMD exception + 20 virtualization exception +21 ~ 31 Do not use + +32 ~ 55 I/O APIC + 32 8259A + 33 keyboard + 34 HPET timer 0,8254 counter 0 + 35 serial port A + 36 serial port B + 37 parallel port + 38 floppy + 39 parallel port + 40 RTC,HPET timer 1 + 41 Generic + 42 Generic + 43 HPET timer 2 + 44 HPET timer 3 + 45 FERR# + 46 SATA primary + 47 SATA secondary + 48 PIRQA + 49 PIRQB + 50 PIRQC + 51 PIRQD + 52 PIRQE + 53 PIRQF + 54 PIRQG + 55 PIRQH + + +0x80 system call + +150 ~ 200 Local APIC + 150 CMCI + 151 Timer + 152 Thermal Monitor + 153 Performance Counter + 154 LINT0 + 155 LINT1 + 156 Error + +200 ~ 255 MP IPI + +*/ + +/* + +1: LVT CMCI +2: LVT Timer +3: LVT Thermal Monitor +4: LVT Performace Counter +5: LVT LINT0 +6: LVT LINT1 +7: LVT Error + +*/ + +/* + LVT +*/ + +struct APIC_LVT +{ + unsigned int vector :8, //0~7 ALL + deliver_mode :3, //8~10 CMCI LINT0 LINT1 PerformCounter ThermalSensor + res_1 :1, //11 + deliver_status :1, //12 ALL + polarity:1, //13 LINT0 LINT1 + irr :1, //14 LINT0 LINT1 + trigger :1, //15 LINT0 LINT1 + mask :1, //16 ALL + timer_mode :2, //17~18 Timer + res_2 :13; //19~31 +}__attribute__((packed)); //disable align in struct + +/* + ICR +*/ + +struct INT_CMD_REG +{ + unsigned int vector :8, //0~7 + deliver_mode :3, //8~10 + dest_mode :1, //11 + deliver_status :1, //12 + res_1 :1, //13 + level :1, //14 + trigger :1, //15 + res_2 :2, //16~17 + dest_shorthand :2, //18~19 + res_3 :12; //20~31 + + union { + struct { + unsigned int res_4 :24, //32~55 + dest_field :8; //56~63 + }apic_destination; + + unsigned int x2apic_destination; //32~63 + }destination; + +}__attribute__((packed)); + +/* + RTE +*/ + +struct IO_APIC_RET_entry +{ + unsigned int vector :8, //0~7 + deliver_mode :3, //8~10 + dest_mode :1, //11 + deliver_status :1, //12 + polarity:1, //13 + irr :1, //14 + trigger :1, //15 + mask :1, //16 + reserved:15; //17~31 + + union{ + struct { + unsigned int reserved1 :24, //32~55 + phy_dest :4, //56~59 + reserved2 :4; //60~63 + }physical; + + struct { + unsigned int reserved1 :24, //32~55 + logical_dest :8; //56~63 + }logical; + }destination; +}__attribute__((packed)); + +/* + +*/ + +//delivery mode +#define APIC_ICR_IOAPIC_Fixed 0 //LAPIC IOAPIC ICR +#define IOAPIC_ICR_Lowest_Priority 1 // IOAPIC ICR +#define APIC_ICR_IOAPIC_SMI 2 //LAPIC IOAPIC ICR + +#define APIC_ICR_IOAPIC_NMI 4 //LAPIC IOAPIC ICR +#define APIC_ICR_IOAPIC_INIT 5 //LAPIC IOAPIC ICR +#define ICR_Start_up 6 // ICR +#define IOAPIC_ExtINT 7 // IOAPIC + + +/* + +*/ +//timer mode +#define APIC_LVT_Timer_One_Shot 0 +#define APIC_LVT_Timer_Periodic 1 +#define APIC_LVT_Timer_TSC_Deadline 2 + +//mask +#define APIC_ICR_IOAPIC_Masked 1 +#define APIC_ICR_IOAPIC_UN_Masked 0 + +//trigger mode +#define APIC_ICR_IOAPIC_Edge 0 +#define APIC_ICR_IOAPIC_Level 1 + +//delivery status +#define APIC_ICR_IOAPIC_Idle 0 +#define APIC_ICR_IOAPIC_Send_Pending 1 + +//destination shorthand +#define ICR_No_Shorthand 0 +#define ICR_Self 1 +#define ICR_ALL_INCLUDE_Self 2 +#define ICR_ALL_EXCLUDE_Self 3 + +//destination mode +#define ICR_IOAPIC_DELV_PHYSICAL 0 +#define ICR_IOAPIC_DELV_LOGIC 1 + +//level +#define ICR_LEVEL_DE_ASSERT 0 +#define ICR_LEVLE_ASSERT 1 + +//remote irr +#define APIC_IOAPIC_IRR_RESET 0 +#define APIC_IOAPIC_IRR_ACCEPT 1 + +//pin polarity +#define APIC_IOAPIC_POLARITY_HIGH 0 +#define APIC_IOAPIC_POLARITY_LOW 1 + +/* + +*/ + +struct IOAPIC_map +{ + unsigned int physical_address; + unsigned char * virtual_index_address; + unsigned int * virtual_data_address; + unsigned int * virtual_EOI_address; +}ioapic_map; + +unsigned long ioapic_rte_read(unsigned char index); +void ioapic_rte_write(unsigned char index,unsigned long value); + +/* + +*/ + +void IOAPIC_pagetable_remap(); + +/* + +*/ + +void do_IRQ(struct pt_regs * regs,unsigned long nr); + +/* + +*/ + +void APIC_IOAPIC_init(); +void Local_APIC_init(); +void IOAPIC_init(); + +void IOAPIC_enable(unsigned long irq); +void IOAPIC_disable(unsigned long irq); +unsigned long IOAPIC_install(unsigned long irq,void * arg); +void IOAPIC_uninstall(unsigned long irq); +void IOAPIC_level_ack(unsigned long irq); +void IOAPIC_edge_ack(unsigned long irq); + +#endif diff --git a/kernel/interrupt.c b/kernel/interrupt.c old mode 100644 new mode 100755 index 904f6e7..2ed3f3b --- a/kernel/interrupt.c +++ b/kernel/interrupt.c @@ -1,9 +1,15 @@ /*************************************************** -* Copyright (c) 2018 MINE 田宇 +* 版权声明 +* +* 本操作系统名为:MINE +* 该操作系统未经授权不得以盈利或非盈利为目的进行开发, +* 只允许个人学习以及公开交流使用 +* +* 代码最终所有权及解释权归田宇所有; +* +* 本模块作者: 田宇 +* EMail: 345538255@qq.com * -* This program is free software; you can redistribute it and/or -* modify it under the terms of version 2 of the GNU General Public -* License as published by the Free Software Foundation. * ***************************************************/ @@ -130,47 +136,48 @@ void (* interrupt[24])(void)= IRQ0x37_interrupt, }; -void init_interrupt() -{ - int i; - for(i = 32;i < 56;i++) - { - set_intr_gate(i , 2 , interrupt[i - 32]); - } - - color_printk(RED,BLACK,"8259A init \n"); - - //8259A-master ICW1-4 - io_out8(0x20,0x11); - io_out8(0x21,0x20); - io_out8(0x21,0x04); - io_out8(0x21,0x01); - - //8259A-slave ICW1-4 - io_out8(0xa0,0x11); - io_out8(0xa1,0x28); - io_out8(0xa1,0x02); - io_out8(0xa1,0x01); - - //8259A-M/S OCW1 - io_out8(0x21,0xfd); - io_out8(0xa1,0xff); - - sti(); + +/* + +*/ + +int register_irq(unsigned long irq, + void * arg, + void (*handler)(unsigned long nr, unsigned long parameter, struct pt_regs * regs), + unsigned long parameter, + hw_int_controller * controller, + char * irq_name) +{ + irq_desc_T * p = &interrupt_desc[irq - 32]; + + p->controller = controller; + p->irq_name = irq_name; + p->parameter = parameter; + p->flags = 0; + p->handler = handler; + + p->controller->install(irq,arg); + p->controller->enable(irq); + + return 1; } /* */ -void do_IRQ(struct pt_regs * regs,unsigned long nr) //regs,nr +int unregister_irq(unsigned long irq) { - unsigned char x; - color_printk(RED,BLACK,"do_IRQ:%#018lx\t",nr); - x = io_in8(0x60); - color_printk(RED,BLACK,"key code:%#018lx\t",x); - io_out8(0x20,0x20); - color_printk(RED,BLACK,"regs:%#018lx\t\n",regs,regs->rip,regs->rsp); -} + irq_desc_T * p = &interrupt_desc[irq - 32]; + + p->controller->disable(irq); + p->controller->uninstall(irq); + p->controller = NULL; + p->irq_name = NULL; + p->parameter = NULL; + p->flags = 0; + p->handler = NULL; + return 1; +} diff --git a/kernel/interrupt.h b/kernel/interrupt.h old mode 100644 new mode 100755 index 06ac07f..5340d2c --- a/kernel/interrupt.h +++ b/kernel/interrupt.h @@ -1,9 +1,15 @@ /*************************************************** -* Copyright (c) 2018 MINE 田宇 +* 版权声明 +* +* 本操作系统名为:MINE +* 该操作系统未经授权不得以盈利或非盈利为目的进行开发, +* 只允许个人学习以及公开交流使用 +* +* 代码最终所有权及解释权归田宇所有; +* +* 本模块作者: 田宇 +* EMail: 345538255@qq.com * -* This program is free software; you can redistribute it and/or -* modify it under the terms of version 2 of the GNU General Public -* License as published by the Free Software Foundation. * ***************************************************/ #ifndef __INTERRUPT_H__ @@ -15,12 +21,57 @@ */ -void init_interrupt(); +typedef struct hw_int_type +{ + void (*enable)(unsigned long irq); + void (*disable)(unsigned long irq); + + unsigned long (*install)(unsigned long irq,void * arg); + void (*uninstall)(unsigned long irq); + + void (*ack)(unsigned long irq); +}hw_int_controller; + +/* + +*/ + +typedef struct { + hw_int_controller * controller; + + char * irq_name; + unsigned long parameter; + void (*handler)(unsigned long nr, unsigned long parameter, struct pt_regs * regs); + unsigned long flags; +}irq_desc_T; + +/* + +*/ + +#define NR_IRQS 24 + +irq_desc_T interrupt_desc[NR_IRQS] = {0}; + +/* + +*/ + +int register_irq(unsigned long irq, + void * arg, + void (*handler)(unsigned long nr, unsigned long parameter, struct pt_regs * regs), + unsigned long parameter, + hw_int_controller * controller, + char * irq_name); /* */ -void do_IRQ(struct pt_regs * regs,unsigned long nr); +int unregister_irq(unsigned long irq); + +extern void (* interrupt[24])(void); + +extern void do_IRQ(struct pt_regs * regs,unsigned long nr); #endif -- Gitee From de540c52254671e0efdb999d0d8716be6f36af06 Mon Sep 17 00:00:00 2001 From: zhoujie Date: Wed, 27 Mar 2019 19:09:33 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E4=BD=BF=E7=94=A8APIC=E4=BD=9C=E4=B8=BA?= =?UTF-8?q?=E4=B8=AD=E6=96=AD=E5=A4=84=E7=90=86=E5=8D=95=E5=85=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/8259A.c | 8 + kernel/8259A.h | 8 + kernel/APIC.c | 15 +- kernel/APIC.h | 14 +- kernel/Makefile | 12 +- kernel/cpu.h | 8 + kernel/head.S | 56 ++- kernel/interrupt.c | 15 +- kernel/interrupt.h | 14 +- kernel/keyboard.c | 255 +++++++++++++ kernel/keyboard.h | 218 +++++++++++ kernel/main.c | 28 +- kernel/memory.c | 909 ++++++++++++++++++++++++++++++++++++++++----- kernel/memory.h | 221 ++++++++--- kernel/printk.c | 36 +- kernel/printk.h | 3 + 16 files changed, 1609 insertions(+), 211 deletions(-) create mode 100755 kernel/keyboard.c create mode 100755 kernel/keyboard.h mode change 100644 => 100755 kernel/memory.c mode change 100644 => 100755 kernel/memory.h diff --git a/kernel/8259A.c b/kernel/8259A.c index 142570f..f448796 100644 --- a/kernel/8259A.c +++ b/kernel/8259A.c @@ -1,3 +1,11 @@ +/*************************************************** +* Copyright (c) 2018 MINE 田宇 +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of version 2 of the GNU General Public +* License as published by the Free Software Foundation. +* +***************************************************/ #include "interrupt.h" #include "linkage.h" #include "lib.h" diff --git a/kernel/8259A.h b/kernel/8259A.h index ce29314..17b3335 100644 --- a/kernel/8259A.h +++ b/kernel/8259A.h @@ -1,3 +1,11 @@ +/*************************************************** +* Copyright (c) 2018 MINE 田宇 +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of version 2 of the GNU General Public +* License as published by the Free Software Foundation. +* +***************************************************/ #ifndef __8259A_H__ #define __8259A_H__ diff --git a/kernel/APIC.c b/kernel/APIC.c index c36314b..6d8ef1f 100755 --- a/kernel/APIC.c +++ b/kernel/APIC.c @@ -1,18 +1,11 @@ /*************************************************** -* 版权声明 -* -* 本操作系统名为:MINE -* 该操作系统未经授权不得以盈利或非盈利为目的进行开发, -* 只允许个人学习以及公开交流使用 -* -* 代码最终所有权及解释权归田宇所有; -* -* 本模块作者: 田宇 -* EMail: 345538255@qq.com +* Copyright (c) 2018 MINE 田宇 * +* This program is free software; you can redistribute it and/or +* modify it under the terms of version 2 of the GNU General Public +* License as published by the Free Software Foundation. * ***************************************************/ - #include "interrupt.h" #include "linkage.h" #include "lib.h" diff --git a/kernel/APIC.h b/kernel/APIC.h index ff67485..1bb4ed4 100755 --- a/kernel/APIC.h +++ b/kernel/APIC.h @@ -1,15 +1,9 @@ /*************************************************** -* 版权声明 -* -* 本操作系统名为:MINE -* 该操作系统未经授权不得以盈利或非盈利为目的进行开发, -* 只允许个人学习以及公开交流使用 -* -* 代码最终所有权及解释权归田宇所有; -* -* 本模块作者: 田宇 -* EMail: 345538255@qq.com +* Copyright (c) 2018 MINE 田宇 * +* This program is free software; you can redistribute it and/or +* modify it under the terms of version 2 of the GNU General Public +* License as published by the Free Software Foundation. * ***************************************************/ diff --git a/kernel/Makefile b/kernel/Makefile index 247ec41..5f78632 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -10,8 +10,8 @@ all: system objcopy -I elf64-x86-64 -S -R ".eh_frame" -R ".comment" -O binary system kernel.bin -system: head.o entry.o main.o printk.o trap.o memory.o interrupt.o task.o sys.o syscalls.o - ld -b elf64-x86-64 -z muldefs -o system head.o entry.o main.o printk.o trap.o memory.o interrupt.o task.o sys.o syscalls.o -T Kernel.lds +system: head.o entry.o main.o printk.o trap.o memory.o interrupt.o APIC.o task.o keyboard.o sys.o syscalls.o + ld -b elf64-x86-64 -z muldefs -o system head.o entry.o main.o printk.o trap.o memory.o interrupt.o APIC.o keyboard.o task.o sys.o syscalls.o -T Kernel.lds head.o: head.S gcc -E head.S > head.s @@ -35,7 +35,13 @@ memory.o: memory.c interrupt.o: interrupt.c gcc -mcmodel=large -fno-builtin -m64 -c interrupt.c - + +APIC.o: APIC.c + gcc -mcmodel=large -fno-builtin -m64 -c APIC.c + +keyboard.o: keyboard.c + gcc -mcmodel=large -fno-builtin -m64 -c keyboard.c + task.o: task.c gcc -mcmodel=large -fno-builtin -m64 -c task.c diff --git a/kernel/cpu.h b/kernel/cpu.h index 0d73044..6cfb6d0 100644 --- a/kernel/cpu.h +++ b/kernel/cpu.h @@ -11,6 +11,14 @@ #define __CPU_H__ +inline void get_cpuid(unsigned int Mop,unsigned int Sop,unsigned int * a,unsigned int * b,unsigned int * c,unsigned int * d) +{ + __asm__ __volatile__ ( "cpuid \n\t" + :"=a"(*a),"=b"(*b),"=c"(*c),"=d"(*d) + :"0"(Mop),"2"(Sop) + ); +} + #define NR_CPUS 8 diff --git a/kernel/head.S b/kernel/head.S index 4b69058..4ba7364 100644 --- a/kernel/head.S +++ b/kernel/head.S @@ -192,36 +192,58 @@ ENTRY(_stack_start) __PML4E: - .quad 0x102007 + .quad 0x102003 .fill 255,8,0 - .quad 0x102007 + .quad 0x102003 .fill 255,8,0 .org 0x2000 __PDPTE: - .quad 0x103007 /* 0x103003 */ + .quad 0x103003 /* 0x103003 */ .fill 511,8,0 .org 0x3000 __PDE: - .quad 0x000087 - .quad 0x200087 - .quad 0x400087 - .quad 0x600087 - .quad 0x800087 /* 0x800083 */ - .quad 0xe0000087 /*0x a00000*/ - .quad 0xe0200087 - .quad 0xe0400087 - .quad 0xe0600087 - .quad 0xe0800087 /*0x1000000*/ - .quad 0xe0a00087 - .quad 0xe0c00087 - .quad 0xe0e00087 - .fill 499,8,0 + .quad 0x000083 + .quad 0x200083 + .quad 0x400083 + .quad 0x600083 + .quad 0x800083 /* 0x800083 */ + .quad 0xa00083 + .quad 0xc00083 + .quad 0xe00083 + .quad 0x1000083 + .quad 0x1200083 + .quad 0x1400083 + .quad 0x1600083 + .quad 0x1800083 + .quad 0x1a00083 + .quad 0x1c00083 + .quad 0x1e00083 + .quad 0x2000083 + .quad 0x2200083 + .quad 0x2400083 + .quad 0x2600083 + .quad 0x2800083 + .quad 0x2a00083 + .quad 0x2c00083 + .quad 0x2e00083 + + + + .quad 0xe0000083 /*0x 3000000*/ + .quad 0xe0200083 + .quad 0xe0400083 + .quad 0xe0600083 + .quad 0xe0800083 + .quad 0xe0a00083 + .quad 0xe0c00083 + .quad 0xe0e00083 + .fill 480,8,0 //======= GDT_Table diff --git a/kernel/interrupt.c b/kernel/interrupt.c index 2ed3f3b..ab5b4f1 100755 --- a/kernel/interrupt.c +++ b/kernel/interrupt.c @@ -1,18 +1,11 @@ /*************************************************** -* 版权声明 -* -* 本操作系统名为:MINE -* 该操作系统未经授权不得以盈利或非盈利为目的进行开发, -* 只允许个人学习以及公开交流使用 -* -* 代码最终所有权及解释权归田宇所有; -* -* 本模块作者: 田宇 -* EMail: 345538255@qq.com +* Copyright (c) 2018 MINE 田宇 * +* This program is free software; you can redistribute it and/or +* modify it under the terms of version 2 of the GNU General Public +* License as published by the Free Software Foundation. * ***************************************************/ - #include "interrupt.h" #include "linkage.h" #include "lib.h" diff --git a/kernel/interrupt.h b/kernel/interrupt.h index 5340d2c..9397ee9 100755 --- a/kernel/interrupt.h +++ b/kernel/interrupt.h @@ -1,15 +1,9 @@ /*************************************************** -* 版权声明 -* -* 本操作系统名为:MINE -* 该操作系统未经授权不得以盈利或非盈利为目的进行开发, -* 只允许个人学习以及公开交流使用 -* -* 代码最终所有权及解释权归田宇所有; -* -* 本模块作者: 田宇 -* EMail: 345538255@qq.com +* Copyright (c) 2018 MINE 田宇 * +* This program is free software; you can redistribute it and/or +* modify it under the terms of version 2 of the GNU General Public +* License as published by the Free Software Foundation. * ***************************************************/ #ifndef __INTERRUPT_H__ diff --git a/kernel/keyboard.c b/kernel/keyboard.c new file mode 100755 index 0000000..9d73813 --- /dev/null +++ b/kernel/keyboard.c @@ -0,0 +1,255 @@ +/*************************************************** +* Copyright (c) 2018 MINE 田宇 +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of version 2 of the GNU General Public +* License as published by the Free Software Foundation. +* +***************************************************/ + +#include "keyboard.h" +#include "lib.h" +#include "interrupt.h" +#include "APIC.h" +#include "memory.h" +#include "printk.h" + +/* + +*/ + +struct keyboard_inputbuffer * p_kb = NULL; +static int shift_l,shift_r,ctrl_l,ctrl_r,alt_l,alt_r; + +void keyboard_handler(unsigned long nr, unsigned long parameter, struct pt_regs * regs) +{ + unsigned char x; + x = io_in8(0x60); + color_printk(WHITE,BLACK,"(K:%02x)",x); + + if(p_kb->p_head == p_kb->buf + KB_BUF_SIZE) + p_kb->p_head = p_kb->buf; + + *p_kb->p_head = x; + p_kb->count++; + p_kb->p_head ++; +} + +/* + +*/ + +unsigned char get_scancode() +{ + unsigned char ret = 0; + + if(p_kb->count == 0) + while(!p_kb->count) + nop(); + + if(p_kb->p_tail == p_kb->buf + KB_BUF_SIZE) + p_kb->p_tail = p_kb->buf; + + ret = *p_kb->p_tail; + p_kb->count--; + p_kb->p_tail++; + + return ret; +} + +/* + +*/ + +void analysis_keycode() +{ + unsigned char x = 0; + int i; + int key = 0; + int make = 0; + + x = get_scancode(); + + if(x == 0xE1) //pause break; + { + key = PAUSEBREAK; + for(i = 1;i<6;i++) + if(get_scancode() != pausebreak_scode[i]) + { + key = 0; + break; + } + } + else if(x == 0xE0) //print screen + { + x = get_scancode(); + + switch(x) + { + case 0x2A: // press printscreen + + if(get_scancode() == 0xE0) + if(get_scancode() == 0x37) + { + key = PRINTSCREEN; + make = 1; + } + break; + + case 0xB7: // UNpress printscreen + + if(get_scancode() == 0xE0) + if(get_scancode() == 0xAA) + { + key = PRINTSCREEN; + make = 0; + } + break; + + case 0x1d: // press right ctrl + + ctrl_r = 1; + key = OTHERKEY; + break; + + case 0x9d: // UNpress right ctrl + + ctrl_r = 0; + key = OTHERKEY; + break; + + case 0x38: // press right alt + + alt_r = 1; + key = OTHERKEY; + break; + + case 0xb8: // UNpress right alt + + alt_r = 0; + key = OTHERKEY; + break; + + default: + key = OTHERKEY; + break; + } + + } + + if(key == 0) + { + unsigned int * keyrow = NULL; + int column = 0; + + make = (x & FLAG_BREAK ? 0:1); + + keyrow = &keycode_map_normal[(x & 0x7F) * MAP_COLS]; + + if(shift_l || shift_r) + column = 1; + + key = keyrow[column]; + + switch(x & 0x7F) + { + case 0x2a: //SHIFT_L: + shift_l = make; + key = 0; + break; + + case 0x36: //SHIFT_R: + shift_r = make; + key = 0; + break; + + case 0x1d: //CTRL_L: + ctrl_l = make; + key = 0; + break; + + case 0x38: //ALT_L: + alt_l = make; + key = 0; + break; + + default: + if(!make) + key = 0; + break; + } + + if(key) + color_printk(RED,YELLOW,"(K:%c)\t",key); + } +} + + +hw_int_controller keyboard_int_controller = +{ + .enable = IOAPIC_enable, + .disable = IOAPIC_disable, + .install = IOAPIC_install, + .uninstall = IOAPIC_uninstall, + .ack = IOAPIC_edge_ack, +}; + +/* + +*/ + + +void keyboard_init() +{ + struct IO_APIC_RET_entry entry; + unsigned long i,j; + + p_kb = (struct keyboard_inputbuffer *)kmalloc(sizeof(struct keyboard_inputbuffer),0); + + p_kb->p_head = p_kb->buf; + p_kb->p_tail = p_kb->buf; + p_kb->count = 0; + memset(p_kb->buf,0,KB_BUF_SIZE); + + entry.vector = 0x21; + entry.deliver_mode = APIC_ICR_IOAPIC_Fixed ; + entry.dest_mode = ICR_IOAPIC_DELV_PHYSICAL; + entry.deliver_status = APIC_ICR_IOAPIC_Idle; + entry.polarity = APIC_IOAPIC_POLARITY_HIGH; + entry.irr = APIC_IOAPIC_IRR_RESET; + entry.trigger = APIC_ICR_IOAPIC_Edge; + entry.mask = APIC_ICR_IOAPIC_Masked; + entry.reserved = 0; + + entry.destination.physical.reserved1 = 0; + entry.destination.physical.phy_dest = 0; + entry.destination.physical.reserved2 = 0; + + wait_KB_write(); + io_out8(PORT_KB_CMD,KBCMD_WRITE_CMD); + wait_KB_write(); + io_out8(PORT_KB_DATA,KB_INIT_MODE); + + for(i = 0;i<1000;i++) + for(j = 0;j<1000;j++) + nop(); + + shift_l = 0; + shift_r = 0; + ctrl_l = 0; + ctrl_r = 0; + alt_l = 0; + alt_r = 0; + + register_irq(0x21, &entry , &keyboard_handler, (unsigned long)p_kb, &keyboard_int_controller, "ps/2 keyboard"); +} + +/* + +*/ + +void keyboard_exit() +{ + unregister_irq(0x21); + kfree((unsigned long *)p_kb); +} diff --git a/kernel/keyboard.h b/kernel/keyboard.h new file mode 100755 index 0000000..153d440 --- /dev/null +++ b/kernel/keyboard.h @@ -0,0 +1,218 @@ +/*************************************************** +* Copyright (c) 2018 MINE 田宇 +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of version 2 of the GNU General Public +* License as published by the Free Software Foundation. +* +***************************************************/ + +#ifndef __KEYBOARD_H__ + +#define __KEYBOARD_H__ + +extern struct keyboard_inputbuffer * p_kb; + +#define NR_SCAN_CODES 0x80 +#define MAP_COLS 2 + +#define KB_BUF_SIZE 100 + +struct keyboard_inputbuffer +{ + unsigned char * p_head; + unsigned char * p_tail; + int count; + unsigned char buf[KB_BUF_SIZE]; +}; + +/* + +*/ + +#define PAUSEBREAK 1 +#define PRINTSCREEN 2 +#define OTHERKEY 4 +#define FLAG_BREAK 0x80 + +#define PORT_KB_DATA 0x60 +#define PORT_KB_STATUS 0x64 +#define PORT_KB_CMD 0x64 + +#define KBSTATUS_IBF 0x02 +#define KBSTATUS_OBF 0x01 + +#define KBCMD_WRITE_CMD 0x60 +#define KBCMD_READ_CMD 0x20 + +#define KB_INIT_MODE 0x47 + + +/* + +*/ + +unsigned char pausebreak_scode[]={0xE1,0x1D,0x45,0xE1,0x9D,0xC5}; + +unsigned int keycode_map_normal[NR_SCAN_CODES * MAP_COLS] = // +{ +/*scan-code unShift Shift */ +/*--------------------------------------------------------------*/ +/*0x00*/ 0, 0, +/*0x01*/ 0, 0, //ESC +/*0x02*/ '1', '!', +/*0x03*/ '2', '@', +/*0x04*/ '3', '#', +/*0x05*/ '4', '$', +/*0x06*/ '5', '%', +/*0x07*/ '6', '^', +/*0x08*/ '7', '&', +/*0x09*/ '8', '*', +/*0x0a*/ '9', '(', +/*0x0b*/ '0', ')', +/*0x0c*/ '-', '_', +/*0x0d*/ '=', '+', +/*0x0e*/ 0, 0, //BACKSPACE +/*0x0f*/ 0, 0, //TAB + +/*0x10*/ 'q', 'Q', +/*0x11*/ 'w', 'W', +/*0x12*/ 'e', 'E', +/*0x13*/ 'r', 'R', +/*0x14*/ 't', 'T', +/*0x15*/ 'y', 'Y', +/*0x16*/ 'u', 'U', +/*0x17*/ 'i', 'I', +/*0x18*/ 'o', 'O', +/*0x19*/ 'p', 'P', +/*0x1a*/ '[', '{', +/*0x1b*/ ']', '}', +/*0x1c*/ 0, 0, //ENTER +/*0x1d*/ 0x1d, 0x1d, //CTRL Left +/*0x1e*/ 'a', 'A', +/*0x1f*/ 's', 'S', + +/*0x20*/ 'd', 'D', +/*0x21*/ 'f', 'F', +/*0x22*/ 'g', 'G', +/*0x23*/ 'h', 'H', +/*0x24*/ 'j', 'J', +/*0x25*/ 'k', 'K', +/*0x26*/ 'l', 'L', +/*0x27*/ ';', ':', +/*0x28*/ '\'', '"', +/*0x29*/ '`', '~', +/*0x2a*/ 0x2a, 0x2a, //SHIFT Left +/*0x2b*/ '\\', '|', +/*0x2c*/ 'z', 'Z', +/*0x2d*/ 'x', 'X', +/*0x2e*/ 'c', 'C', +/*0x2f*/ 'v', 'V', + +/*0x30*/ 'b', 'B', +/*0x31*/ 'n', 'N', +/*0x32*/ 'm', 'M', +/*0x33*/ ',', '<', +/*0x34*/ '.', '>', +/*0x35*/ '/', '?', +/*0x36*/ 0x36, 0x36, //SHIFT Right +/*0x37*/ '*', '*', +/*0x38*/ 0x38, 0x38, //ALT Left +/*0x39*/ ' ', ' ', +/*0x3a*/ 0, 0, //CAPS LOCK +/*0x3b*/ 0, 0, //F1 +/*0x3c*/ 0, 0, //F2 +/*0x3d*/ 0, 0, //F3 +/*0x3e*/ 0, 0, //F4 +/*0x3f*/ 0, 0, //F5 + +/*0x40*/ 0, 0, //F6 +/*0x41*/ 0, 0, //F7 +/*0x42*/ 0, 0, //F8 +/*0x43*/ 0, 0, //F9 +/*0x44*/ 0, 0, //F10 +/*0x45*/ 0, 0, //NUM LOCK +/*0x46*/ 0, 0, //SCROLL LOCK +/*0x47*/ '7', 0, /*PAD HONE*/ +/*0x48*/ '8', 0, /*PAD UP*/ +/*0x49*/ '9', 0, /*PAD PAGEUP*/ +/*0x4a*/ '-', 0, /*PAD MINUS*/ +/*0x4b*/ '4', 0, /*PAD LEFT*/ +/*0x4c*/ '5', 0, /*PAD MID*/ +/*0x4d*/ '6', 0, /*PAD RIGHT*/ +/*0x4e*/ '+', 0, /*PAD PLUS*/ +/*0x4f*/ '1', 0, /*PAD END*/ + +/*0x50*/ '2', 0, /*PAD DOWN*/ +/*0x51*/ '3', 0, /*PAD PAGEDOWN*/ +/*0x52*/ '0', 0, /*PAD INS*/ +/*0x53*/ '.', 0, /*PAD DOT*/ +/*0x54*/ 0, 0, +/*0x55*/ 0, 0, +/*0x56*/ 0, 0, +/*0x57*/ 0, 0, //F11 +/*0x58*/ 0, 0, //F12 +/*0x59*/ 0, 0, +/*0x5a*/ 0, 0, +/*0x5b*/ 0, 0, +/*0x5c*/ 0, 0, +/*0x5d*/ 0, 0, +/*0x5e*/ 0, 0, +/*0x5f*/ 0, 0, + +/*0x60*/ 0, 0, +/*0x61*/ 0, 0, +/*0x62*/ 0, 0, +/*0x63*/ 0, 0, +/*0x64*/ 0, 0, +/*0x65*/ 0, 0, +/*0x66*/ 0, 0, +/*0x67*/ 0, 0, +/*0x68*/ 0, 0, +/*0x69*/ 0, 0, +/*0x6a*/ 0, 0, +/*0x6b*/ 0, 0, +/*0x6c*/ 0, 0, +/*0x6d*/ 0, 0, +/*0x6e*/ 0, 0, +/*0x6f*/ 0, 0, + +/*0x70*/ 0, 0, +/*0x71*/ 0, 0, +/*0x72*/ 0, 0, +/*0x73*/ 0, 0, +/*0x74*/ 0, 0, +/*0x75*/ 0, 0, +/*0x76*/ 0, 0, +/*0x77*/ 0, 0, +/*0x78*/ 0, 0, +/*0x79*/ 0, 0, +/*0x7a*/ 0, 0, +/*0x7b*/ 0, 0, +/*0x7c*/ 0, 0, +/*0x7d*/ 0, 0, +/*0x7e*/ 0, 0, +/*0x7f*/ 0, 0, +}; + +/* + +*/ + +#define wait_KB_write() while(io_in8(PORT_KB_STATUS) & KBSTATUS_IBF) +#define wait_KB_read() while(io_in8(PORT_KB_STATUS) & KBSTATUS_OBF) + +/* + +*/ + +void keyboard_init(); +void keyboard_exit(); + +/* + +*/ + +void analysis_keycode(); + +#endif diff --git a/kernel/main.c b/kernel/main.c index b46fae8..86cda90 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -13,7 +13,8 @@ #include "trap.h" #include "memory.h" #include "task.h" - +#include "APIC.h" +#include "keyboard.h" /* static var */ @@ -22,7 +23,7 @@ struct Global_Memory_Descriptor memory_management_struct = {{0},0}; void Start_Kernel(void) { - int *addr = (int *)0xffff800000a00000; + int *addr = (int *)0xffff800003000000; int i; Pos.XResolution = 1440; @@ -34,7 +35,7 @@ void Start_Kernel(void) Pos.XCharSize = 8; Pos.YCharSize = 16; - Pos.FB_addr = (int *)0xffff800000a00000; + Pos.FB_addr = (int *)0xffff800003000000; Pos.FB_length = (Pos.XResolution * Pos.YResolution * 4 + PAGE_4K_SIZE - 1) & PAGE_4K_MASK; load_TR(10); @@ -51,13 +52,26 @@ void Start_Kernel(void) color_printk(RED,BLACK,"memory init \n"); init_memory(); + color_printk(RED,BLACK,"slab init \n"); + slab_init(); + + color_printk(RED,BLACK,"frame buffer init \n"); + frame_buffer_init(); + color_printk(WHITE,BLACK,"frame_buffer_init() is OK \n"); + + color_printk(RED,BLACK,"pagetable init \n"); + pagetable_init(); + color_printk(RED,BLACK,"interrupt init \n"); - init_interrupt(); + APIC_IOAPIC_init(); + + color_printk(RED,BLACK,"keyboard init \n"); + keyboard_init(); - color_printk(RED,BLACK,"task_init \n"); - task_init(); + // color_printk(RED,BLACK,"task_init \n"); + // task_init(); while(1) - ; + analysis_keycode(); } diff --git a/kernel/memory.c b/kernel/memory.c old mode 100644 new mode 100755 index 06941a0..1985c1e --- a/kernel/memory.c +++ b/kernel/memory.c @@ -13,80 +13,76 @@ unsigned long page_init(struct Page * page,unsigned long flags) { - if(!page->attribute) + page->attribute |= flags; + + if(!page->reference_count || (page->attribute & PG_Shared)) { - *(memory_management_struct.bits_map + ((page->PHY_address >> PAGE_2M_SHIFT) >> 6)) |= 1UL << (page->PHY_address >> PAGE_2M_SHIFT) % 64; - page->attribute = flags; page->reference_count++; - page->zone_struct->page_using_count++; - page->zone_struct->page_free_count--; - page->zone_struct->total_pages_link++; - } - else if((page->attribute & PG_Referenced) || (page->attribute & PG_K_Share_To_U) || (flags & PG_Referenced) || (flags & PG_K_Share_To_U)) + page->zone_struct->total_pages_link++; + } + + return 1; +} + + +unsigned long page_clean(struct Page * page) +{ + page->reference_count--; + page->zone_struct->total_pages_link--; + + if(!page->reference_count) { - page->attribute |= flags; - page->reference_count++; - page->zone_struct->total_pages_link++; + page->attribute &= PG_PTable_Maped; } - else + + return 1; +} + +unsigned long get_page_attribute(struct Page * page) +{ + if(page == NULL) { - *(memory_management_struct.bits_map + ((page->PHY_address >> PAGE_2M_SHIFT) >> 6)) |= 1UL << (page->PHY_address >> PAGE_2M_SHIFT) % 64; - page->attribute |= flags; + color_printk(RED,BLACK,"get_page_attribute() ERROR: page == NULL\n"); + return 0; } - return 0; + else + return page->attribute; } - -unsigned long page_clean(struct Page * page) +unsigned long set_page_attribute(struct Page * page,unsigned long flags) { - if(!page->attribute) + if(page == NULL) { - page->attribute = 0; - } - else if((page->attribute & PG_Referenced) || (page->attribute & PG_K_Share_To_U)) - { - page->reference_count--; - page->zone_struct->total_pages_link--; - if(!page->reference_count) - { - page->attribute = 0; - page->zone_struct->page_using_count--; - page->zone_struct->page_free_count++; - } + color_printk(RED,BLACK,"set_page_attribute() ERROR: page == NULL\n"); + return 0; } else { - *(memory_management_struct.bits_map + ((page->PHY_address >> PAGE_2M_SHIFT) >> 6)) &= ~(1UL << (page->PHY_address >> PAGE_2M_SHIFT) % 64); - - page->attribute = 0; - page->reference_count = 0; - page->zone_struct->page_using_count--; - page->zone_struct->page_free_count++; - page->zone_struct->total_pages_link--; + page->attribute = flags; + return 1; } - return 0; } - void init_memory() { int i,j; unsigned long TotalMem = 0 ; struct E820 *p = NULL; -// color_printk(BLUE,BLACK,"Display Physics Address MAP,Type(1:RAM,2:ROM or Reserved,3:ACPI Reclaim Memory,4:ACPI NVS Memory,Others:Undefine)\n"); + color_printk(BLUE,BLACK,"Display Physics Address MAP,Type(1:RAM,2:ROM or Reserved,3:ACPI Reclaim Memory,4:ACPI NVS Memory,Others:Undefine)\n"); p = (struct E820 *)0xffff800000007e00; for(i = 0;i < 32;i++) { -// color_printk(ORANGE,BLACK,"Address:%#018lx\tLength:%#018lx\tType:%#010x\n",p->address,p->length,p->type); + if(p->type == 1) + color_printk(ORANGE,BLACK,"Address:%#018lx\tLength:%#018lx\tType:%#010x\n",p->address,p->length,p->type); unsigned long tmp = 0; if(p->type == 1) TotalMem += p->length; - memory_management_struct.e820[i].address += p->address; + memory_management_struct.e820[i].address = p->address; - memory_management_struct.e820[i].length += p->length; + memory_management_struct.e820[i].length = p->length; memory_management_struct.e820[i].type = p->type; @@ -113,7 +109,7 @@ void init_memory() TotalMem += (end - start) >> PAGE_2M_SHIFT; } - color_printk(ORANGE,BLACK,"OS Can Used Total 2M PAGEs:%#010x=%010d\n",TotalMem,TotalMem); + color_printk(ORANGE,BLACK,"OS Can Used Total 2M PAGEs:%#018lx=%018ld\n",TotalMem,TotalMem); TotalMem = memory_management_struct.e820[memory_management_struct.e820_length].address + memory_management_struct.e820[memory_management_struct.e820_length].length; @@ -147,8 +143,6 @@ void init_memory() memset(memory_management_struct.zones_struct,0x00,memory_management_struct.zones_length); //init zones memory - - for(i = 0;i <= memory_management_struct.e820_length;i++) { unsigned long start,end; @@ -196,9 +190,7 @@ void init_memory() p->age = 0; *(memory_management_struct.bits_map + ((p->PHY_address >> PAGE_2M_SHIFT) >> 6)) ^= 1UL << (p->PHY_address >> PAGE_2M_SHIFT) % 64; - - } - + } } /////////////init address 0 to page struct 0; because the memory_management_struct.e820[0].type != 1 @@ -206,54 +198,61 @@ void init_memory() memory_management_struct.pages_struct->zone_struct = memory_management_struct.zones_struct; memory_management_struct.pages_struct->PHY_address = 0UL; - memory_management_struct.pages_struct->attribute = 0; - memory_management_struct.pages_struct->reference_count = 0; - memory_management_struct.pages_struct->age = 0; + set_page_attribute(memory_management_struct.pages_struct,PG_PTable_Maped | PG_Kernel_Init | PG_Kernel); + memory_management_struct.pages_struct->reference_count = 1; + memory_management_struct.pages_struct->age = 0; + ///////////// memory_management_struct.zones_length = (memory_management_struct.zones_size * sizeof(struct Zone) + sizeof(long) - 1) & ( ~ (sizeof(long) - 1)); -// color_printk(ORANGE,BLACK,"bits_map:%#018lx,bits_size:%#018lx,bits_length:%#018lx\n",memory_management_struct.bits_map,memory_management_struct.bits_size,memory_management_struct.bits_length); + color_printk(ORANGE,BLACK,"bits_map:%#018lx,bits_size:%#018lx,bits_length:%#018lx\n",memory_management_struct.bits_map,memory_management_struct.bits_size,memory_management_struct.bits_length); -// color_printk(ORANGE,BLACK,"pages_struct:%#018lx,pages_size:%#018lx,pages_length:%#018lx\n",memory_management_struct.pages_struct,memory_management_struct.pages_size,memory_management_struct.pages_length); + color_printk(ORANGE,BLACK,"pages_struct:%#018lx,pages_size:%#018lx,pages_length:%#018lx\n",memory_management_struct.pages_struct,memory_management_struct.pages_size,memory_management_struct.pages_length); -// color_printk(ORANGE,BLACK,"zones_struct:%#018lx,zones_size:%#018lx,zones_length:%#018lx\n",memory_management_struct.zones_struct,memory_management_struct.zones_size,memory_management_struct.zones_length); + color_printk(ORANGE,BLACK,"zones_struct:%#018lx,zones_size:%#018lx,zones_length:%#018lx\n",memory_management_struct.zones_struct,memory_management_struct.zones_size,memory_management_struct.zones_length); - ZONE_DMA_INDEX = 0; //need rewrite in the future - ZONE_NORMAL_INDEX = 0; //need rewrite in the future - - for(i = 0;i < memory_management_struct.zones_size;i++) //need rewrite in the future + ZONE_DMA_INDEX = 0; + ZONE_NORMAL_INDEX = 0; + ZONE_UNMAPED_INDEX = 0; + + for(i = 0;i < memory_management_struct.zones_size;i++) { struct Zone * z = memory_management_struct.zones_struct + i; -// color_printk(ORANGE,BLACK,"zone_start_address:%#018lx,zone_end_address:%#018lx,zone_length:%#018lx,pages_group:%#018lx,pages_length:%#018lx\n",z->zone_start_address,z->zone_end_address,z->zone_length,z->pages_group,z->pages_length); + color_printk(ORANGE,BLACK,"zone_start_address:%#018lx,zone_end_address:%#018lx,zone_length:%#018lx,pages_group:%#018lx,pages_length:%#018lx\n",z->zone_start_address,z->zone_end_address,z->zone_length,z->pages_group,z->pages_length); - if(z->zone_start_address == 0x100000000) + if(z->zone_start_address >= 0x100000000 && !ZONE_UNMAPED_INDEX) ZONE_UNMAPED_INDEX = i; } + color_printk(ORANGE,BLACK,"ZONE_DMA_INDEX:%d\tZONE_NORMAL_INDEX:%d\tZONE_UNMAPED_INDEX:%d\n",ZONE_DMA_INDEX,ZONE_NORMAL_INDEX,ZONE_UNMAPED_INDEX); + memory_management_struct.end_of_struct = (unsigned long)((unsigned long)memory_management_struct.zones_struct + memory_management_struct.zones_length + sizeof(long) * 32) & ( ~ (sizeof(long) - 1)); ////need a blank to separate memory_management_struct color_printk(ORANGE,BLACK,"start_code:%#018lx,end_code:%#018lx,end_data:%#018lx,end_brk:%#018lx,end_of_struct:%#018lx\n",memory_management_struct.start_code,memory_management_struct.end_code,memory_management_struct.end_data,memory_management_struct.end_brk, memory_management_struct.end_of_struct); - i = Virt_To_Phy(memory_management_struct.end_of_struct) >> PAGE_2M_SHIFT; - for(j = 0;j <= i;j++) + for(j = 1;j <= i;j++) { - page_init(memory_management_struct.pages_struct + j,PG_PTable_Maped | PG_Kernel_Init | PG_Active | PG_Kernel); + struct Page * tmp_page = memory_management_struct.pages_struct + j; + page_init(tmp_page,PG_PTable_Maped | PG_Kernel_Init | PG_Kernel); + *(memory_management_struct.bits_map + ((tmp_page->PHY_address >> PAGE_2M_SHIFT) >> 6)) |= 1UL << (tmp_page->PHY_address >> PAGE_2M_SHIFT) % 64; + tmp_page->zone_struct->page_using_count++; + tmp_page->zone_struct->page_free_count--; } - Global_CR3 = Get_gdt(); -// color_printk(INDIGO,BLACK,"Global_CR3\t:%#018lx\n",Global_CR3); -// color_printk(INDIGO,BLACK,"*Global_CR3\t:%#018lx\n",*Phy_To_Virt(Global_CR3) & (~0xff)); -// color_printk(PURPLE,BLACK,"**Global_CR3\t:%#018lx\n",*Phy_To_Virt(*Phy_To_Virt(Global_CR3) & (~0xff)) & (~0xff)); + color_printk(INDIGO,BLACK,"Global_CR3\t:%#018lx\n",Global_CR3); + color_printk(INDIGO,BLACK,"*Global_CR3\t:%#018lx\n",*Phy_To_Virt(Global_CR3) & (~0xff)); + color_printk(PURPLE,BLACK,"**Global_CR3\t:%#018lx\n",*Phy_To_Virt(*Phy_To_Virt(Global_CR3) & (~0xff)) & (~0xff)); + color_printk(ORANGE,BLACK,"1.memory_management_struct.bits_map:%#018lx\tzone_struct->page_using_count:%d\tzone_struct->page_free_count:%d\n",*memory_management_struct.bits_map,memory_management_struct.zones_struct->page_using_count,memory_management_struct.zones_struct->page_free_count); -// for(i = 0;i < 10;i++) -// *(Phy_To_Virt(Global_CR3) + i) = 0UL; + for(i = 0;i < 10;i++) + *(Phy_To_Virt(Global_CR3) + i) = 0UL; flush_tlb(); } @@ -261,9 +260,7 @@ void init_memory() /* number: number < 64 - zone_select: zone select from dma , mapped in pagetable , unmapped in pagetable - page_flags: struct Page flages */ @@ -272,41 +269,48 @@ struct Page * alloc_pages(int zone_select,int number,unsigned long page_flags) { int i; unsigned long page = 0; + unsigned long attribute = 0; int zone_start = 0; int zone_end = 0; + + if(number >= 64 || number <= 0) + { + color_printk(RED,BLACK,"alloc_pages() ERROR: number is invalid\n"); + return NULL; + } switch(zone_select) { case ZONE_DMA: zone_start = 0; zone_end = ZONE_DMA_INDEX; - + attribute = PG_PTable_Maped; break; case ZONE_NORMAL: zone_start = ZONE_DMA_INDEX; zone_end = ZONE_NORMAL_INDEX; - + attribute = PG_PTable_Maped; break; case ZONE_UNMAPED: zone_start = ZONE_UNMAPED_INDEX; zone_end = memory_management_struct.zones_size - 1; - + attribute = 0; break; default: - color_printk(RED,BLACK,"alloc_pages error zone_select index\n"); + color_printk(RED,BLACK,"alloc_pages() ERROR: zone_select index is invalid\n"); return NULL; break; } - for(i = zone_start;i <= zone_end; i++) + for(i = zone_start; i <= zone_end; i++) { struct Zone * z; unsigned long j; - unsigned long start,end,length; + unsigned long start,end; unsigned long tmp; if((memory_management_struct.zones_struct + i)->page_free_count < number) @@ -315,33 +319,39 @@ struct Page * alloc_pages(int zone_select,int number,unsigned long page_flags) z = memory_management_struct.zones_struct + i; start = z->zone_start_address >> PAGE_2M_SHIFT; end = z->zone_end_address >> PAGE_2M_SHIFT; - length = z->zone_length >> PAGE_2M_SHIFT; tmp = 64 - start % 64; - for(j = start;j <= end;j += j % 64 ? tmp : 64) + for(j = start;j < end;j += j % 64 ? tmp : 64) { unsigned long * p = memory_management_struct.bits_map + (j >> 6); + unsigned long k = 0; unsigned long shift = j % 64; - unsigned long k; - for(k = shift;k < 64 - shift;k++) + + unsigned long num = (1UL << number) - 1; + + for(k = shift;k < 64;k++) { - if( !(((*p >> k) | (*(p + 1) << (64 - k))) & (number == 64 ? 0xffffffffffffffffUL : ((1UL << number) - 1))) ) + if( !( (k ? ((*p >> k) | (*(p + 1) << (64 - k))) : *p) & (num) ) ) { unsigned long l; - page = j + k - 1; + page = j + k - shift; for(l = 0;l < number;l++) { - struct Page * x = memory_management_struct.pages_struct + page + l; - page_init(x,page_flags); + struct Page * pageptr = memory_management_struct.pages_struct + page + l; + + *(memory_management_struct.bits_map + ((pageptr->PHY_address >> PAGE_2M_SHIFT) >> 6)) |= 1UL << (pageptr->PHY_address >> PAGE_2M_SHIFT) % 64; + z->page_using_count++; + z->page_free_count--; + pageptr->attribute = attribute; } goto find_free_pages; } } - } } + color_printk(RED,BLACK,"alloc_pages() ERROR: no page can alloc\n"); return NULL; find_free_pages: @@ -349,3 +359,728 @@ find_free_pages: return (struct Page *)(memory_management_struct.pages_struct + page); } +/* + + page: free page start from this pointer + number: number < 64 + +*/ + +void free_pages(struct Page * page,int number) +{ + int i = 0; + + if(page == NULL) + { + color_printk(RED,BLACK,"free_pages() ERROR: page is invalid\n"); + return ; + } + + if(number >= 64 || number <= 0) + { + color_printk(RED,BLACK,"free_pages() ERROR: number is invalid\n"); + return ; + } + + for(i = 0;iPHY_address >> PAGE_2M_SHIFT) >> 6)) &= ~(1UL << (page->PHY_address >> PAGE_2M_SHIFT) % 64); + page->zone_struct->page_using_count--; + page->zone_struct->page_free_count++; + page->attribute = 0; + } +} + +/* + return virtual kernel address + gfp_flages: the condition of get memory +*/ + +void * kmalloc(unsigned long size,unsigned long gfp_flages) +{ + int i,j; + struct Slab * slab = NULL; + if(size > 1048576) + { + color_printk(RED,BLACK,"kmalloc() ERROR: kmalloc size too long:%08d\n",size); + return NULL; + } + for(i = 0;i < 16;i++) + if(kmalloc_cache_size[i].size >= size) + break; + slab = kmalloc_cache_size[i].cache_pool; + + if(kmalloc_cache_size[i].total_free != 0) + { + do + { + if(slab->free_count == 0) + slab = container_of(list_next(&slab->list),struct Slab,list); + else + break; + }while(slab != kmalloc_cache_size[i].cache_pool); + } + else + { + slab = kmalloc_create(kmalloc_cache_size[i].size); + + if(slab == NULL) + { + color_printk(BLUE,BLACK,"kmalloc()->kmalloc_create()=>slab == NULL\n"); + return NULL; + } + + kmalloc_cache_size[i].total_free += slab->color_count; + + color_printk(BLUE,BLACK,"kmalloc()->kmalloc_create()<=size:%#010x\n",kmalloc_cache_size[i].size);/////// + + list_add_to_before(&kmalloc_cache_size[i].cache_pool->list,&slab->list); + } + + for(j = 0;j < slab->color_count;j++) + { + if(*(slab->color_map + (j >> 6)) == 0xffffffffffffffffUL) + { + j += 63; + continue; + } + + if( (*(slab->color_map + (j >> 6)) & (1UL << (j % 64))) == 0 ) + { + *(slab->color_map + (j >> 6)) |= 1UL << (j % 64); + slab->using_count++; + slab->free_count--; + + kmalloc_cache_size[i].total_free--; + kmalloc_cache_size[i].total_using++; + + return (void *)((char *)slab->Vaddress + kmalloc_cache_size[i].size * j); + } + } + + color_printk(BLUE,BLACK,"kmalloc() ERROR: no memory can alloc\n"); + return NULL; +} + +/* + +*/ + +struct Slab * kmalloc_create(unsigned long size) +{ + int i; + struct Slab * slab = NULL; + struct Page * page = NULL; + unsigned long * vaddresss = NULL; + long structsize = 0; + + page = alloc_pages(ZONE_NORMAL,1, 0); + + if(page == NULL) + { + color_printk(RED,BLACK,"kmalloc_create()->alloc_pages()=>page == NULL\n"); + return NULL; + } + + page_init(page,PG_Kernel); + + switch(size) + { + ////////////////////slab + map in 2M page + + case 32: + case 64: + case 128: + case 256: + case 512: + + vaddresss = Phy_To_Virt(page->PHY_address); + structsize = sizeof(struct Slab) + PAGE_2M_SIZE / size / 8; + + slab = (struct Slab *)((unsigned char *)vaddresss + PAGE_2M_SIZE - structsize); + slab->color_map = (unsigned long *)((unsigned char *)slab + sizeof(struct Slab)); + + slab->free_count = (PAGE_2M_SIZE - (PAGE_2M_SIZE / size / 8) - sizeof(struct Slab)) / size; + slab->using_count = 0; + slab->color_count = slab->free_count; + slab->Vaddress = vaddresss; + slab->page = page; + list_init(&slab->list); + + slab->color_length = ((slab->color_count + sizeof(unsigned long) * 8 - 1) >> 6) << 3; + memset(slab->color_map,0xff,slab->color_length); + + for(i = 0;i < slab->color_count;i++) + *(slab->color_map + (i >> 6)) ^= 1UL << i % 64; + + break; + + ///////////////////kmalloc slab and map,not in 2M page anymore + + case 1024: //1KB + case 2048: + case 4096: //4KB + case 8192: + case 16384: + + //////////////////color_map is a very short buffer. + + case 32768: + case 65536: + case 131072: //128KB + case 262144: + case 524288: + case 1048576: //1MB + + slab = (struct Slab *)kmalloc(sizeof(struct Slab),0); + + slab->free_count = PAGE_2M_SIZE / size; + slab->using_count = 0; + slab->color_count = slab->free_count; + + slab->color_length = ((slab->color_count + sizeof(unsigned long) * 8 - 1) >> 6) << 3; + + slab->color_map = (unsigned long *)kmalloc(slab->color_length,0); + memset(slab->color_map,0xff,slab->color_length); + + slab->Vaddress = Phy_To_Virt(page->PHY_address); + slab->page = page; + list_init(&slab->list); + + for(i = 0;i < slab->color_count;i++) + *(slab->color_map + (i >> 6)) ^= 1UL << i % 64; + + break; + + default: + + color_printk(RED,BLACK,"kmalloc_create() ERROR: wrong size:%08d\n",size); + free_pages(page,1); + + return NULL; + } + + return slab; +} + +/* + +*/ + +unsigned long kfree(void * address) +{ + int i; + int index; + struct Slab * slab = NULL; + void * page_base_address = (void *)((unsigned long)address & PAGE_2M_MASK); + + for(i = 0;i < 16;i++) + { + slab = kmalloc_cache_size[i].cache_pool; + do + { + if(slab->Vaddress == page_base_address) + { + index = (address - slab->Vaddress) / kmalloc_cache_size[i].size; + + *(slab->color_map + (index >> 6)) ^= 1UL << index % 64; + + slab->free_count++; + slab->using_count--; + + kmalloc_cache_size[i].total_free++; + kmalloc_cache_size[i].total_using--; + + if((slab->using_count == 0) && (kmalloc_cache_size[i].total_free >= slab->color_count * 3 / 2) && (kmalloc_cache_size[i].cache_pool != slab)) + { + switch(kmalloc_cache_size[i].size) + { + ////////////////////slab + map in 2M page + + case 32: + case 64: + case 128: + case 256: + case 512: + list_del(&slab->list); + kmalloc_cache_size[i].total_free -= slab->color_count; + + page_clean(slab->page); + free_pages(slab->page,1); + break; + + default: + list_del(&slab->list); + kmalloc_cache_size[i].total_free -= slab->color_count; + + kfree(slab->color_map); + + page_clean(slab->page); + free_pages(slab->page,1); + kfree(slab); + break; + } + + } + + return 1; + } + else + slab = container_of(list_next(&slab->list),struct Slab,list); + + }while(slab != kmalloc_cache_size[i].cache_pool); + + } + + color_printk(RED,BLACK,"kfree() ERROR: can`t free memory\n"); + + return 0; +} + +/* + +*/ + +struct Slab_cache * slab_create(unsigned long size,void *(* constructor)(void * Vaddress,unsigned long arg),void *(* destructor)(void * Vaddress,unsigned long arg),unsigned long arg) +{ + struct Slab_cache * slab_cache = NULL; + + slab_cache = (struct Slab_cache *)kmalloc(sizeof(struct Slab_cache),0); + + if(slab_cache == NULL) + { + color_printk(RED,BLACK,"slab_create()->kmalloc()=>slab_cache == NULL\n"); + return NULL; + } + + memset(slab_cache,0,sizeof(struct Slab_cache)); + + slab_cache->size = SIZEOF_LONG_ALIGN(size); + slab_cache->total_using = 0; + slab_cache->total_free = 0; + slab_cache->cache_pool = (struct Slab *)kmalloc(sizeof(struct Slab),0); + + if(slab_cache->cache_pool == NULL) + { + color_printk(RED,BLACK,"slab_create()->kmalloc()=>slab_cache->cache_pool == NULL\n"); + kfree(slab_cache); + return NULL; + } + + memset(slab_cache->cache_pool,0,sizeof(struct Slab)); + + slab_cache->cache_dma_pool = NULL; + slab_cache->constructor = constructor; + slab_cache->destructor = destructor; + + list_init(&slab_cache->cache_pool->list); + + slab_cache->cache_pool->page = alloc_pages(ZONE_NORMAL,1,0); + + if(slab_cache->cache_pool->page == NULL) + { + color_printk(RED,BLACK,"slab_create()->alloc_pages()=>slab_cache->cache_pool->page == NULL\n"); + kfree(slab_cache->cache_pool); + kfree(slab_cache); + return NULL; + } + + page_init(slab_cache->cache_pool->page,PG_Kernel); + + slab_cache->cache_pool->using_count = PAGE_2M_SIZE/slab_cache->size; + + slab_cache->cache_pool->free_count = slab_cache->cache_pool->using_count; + + slab_cache->total_free = slab_cache->cache_pool->free_count; + + slab_cache->cache_pool->Vaddress = Phy_To_Virt(slab_cache->cache_pool->page->PHY_address); + + slab_cache->cache_pool->color_count = slab_cache->cache_pool->free_count; + + slab_cache->cache_pool->color_length = ((slab_cache->cache_pool->color_count + sizeof(unsigned long) * 8 - 1) >> 6) << 3; + + slab_cache->cache_pool->color_map = (unsigned long *)kmalloc(slab_cache->cache_pool->color_length,0); + + if(slab_cache->cache_pool->color_map == NULL) + { + color_printk(RED,BLACK,"slab_create()->kmalloc()=>slab_cache->cache_pool->color_map == NULL\n"); + + free_pages(slab_cache->cache_pool->page,1); + kfree(slab_cache->cache_pool); + kfree(slab_cache); + return NULL; + } + + memset(slab_cache->cache_pool->color_map,0,slab_cache->cache_pool->color_length); + + return slab_cache; +} + +/* + +*/ + +unsigned long slab_destroy(struct Slab_cache * slab_cache) +{ + struct Slab * slab_p = slab_cache->cache_pool; + struct Slab * tmp_slab = NULL; + + if(slab_cache->total_using != 0) + { + color_printk(RED,BLACK,"slab_cache->total_using != 0\n"); + return 0; + } + + while(!list_is_empty(&slab_p->list)) + { + tmp_slab = slab_p; + slab_p = container_of(list_next(&slab_p->list),struct Slab,list); + + list_del(&tmp_slab->list); + kfree(tmp_slab->color_map); + + page_clean(tmp_slab->page); + free_pages(tmp_slab->page,1); + kfree(tmp_slab); + } + + kfree(slab_p->color_map); + + page_clean(slab_p->page); + free_pages(slab_p->page,1); + kfree(slab_p); + + kfree(slab_cache); + + return 1; +} + +/* + +*/ + +void * slab_malloc(struct Slab_cache * slab_cache,unsigned long arg) +{ + struct Slab * slab_p = slab_cache->cache_pool; + struct Slab * tmp_slab = NULL; + int j = 0; + + if(slab_cache->total_free == 0) + { + tmp_slab = (struct Slab *)kmalloc(sizeof(struct Slab),0); + + if(tmp_slab == NULL) + { + color_printk(RED,BLACK,"slab_malloc()->kmalloc()=>tmp_slab == NULL\n"); + return NULL; + } + + memset(tmp_slab,0,sizeof(struct Slab)); + + list_init(&tmp_slab->list); + + tmp_slab->page = alloc_pages(ZONE_NORMAL,1,0); + + if(tmp_slab->page == NULL) + { + color_printk(RED,BLACK,"slab_malloc()->alloc_pages()=>tmp_slab->page == NULL\n"); + kfree(tmp_slab); + return NULL; + } + + page_init(tmp_slab->page,PG_Kernel); + + tmp_slab->using_count = PAGE_2M_SIZE/slab_cache->size; + tmp_slab->free_count = tmp_slab->using_count; + tmp_slab->Vaddress = Phy_To_Virt(tmp_slab->page->PHY_address); + + tmp_slab->color_count = tmp_slab->free_count; + tmp_slab->color_length = ((tmp_slab->color_count + sizeof(unsigned long) * 8 - 1) >> 6) << 3; + tmp_slab->color_map = (unsigned long *)kmalloc(tmp_slab->color_length,0); + + if(tmp_slab->color_map == NULL) + { + color_printk(RED,BLACK,"slab_malloc()->kmalloc()=>tmp_slab->color_map == NULL\n"); + free_pages(tmp_slab->page,1); + kfree(tmp_slab); + return NULL; + } + + memset(tmp_slab->color_map,0,tmp_slab->color_length); + + list_add_to_behind(&slab_cache->cache_pool->list,&tmp_slab->list); + + slab_cache->total_free += tmp_slab->color_count; + + for(j = 0;j < tmp_slab->color_count;j++) + { + if( (*(tmp_slab->color_map + (j >> 6)) & (1UL << (j % 64))) == 0 ) + { + *(tmp_slab->color_map + (j >> 6)) |= 1UL << (j % 64); + + tmp_slab->using_count++; + tmp_slab->free_count--; + + slab_cache->total_using++; + slab_cache->total_free--; + + if(slab_cache->constructor != NULL) + { + return slab_cache->constructor((char *)tmp_slab->Vaddress + slab_cache->size * j,arg); + } + else + { + return (void *)((char *)tmp_slab->Vaddress + slab_cache->size * j); + } + } + } + } + else + { + do + { + if(slab_p->free_count == 0) + { + slab_p = container_of(list_next(&slab_p->list),struct Slab,list); + continue; + } + + for(j = 0;j < slab_p->color_count;j++) + { + + if(*(slab_p->color_map + (j >> 6)) == 0xffffffffffffffffUL) + { + j += 63; + continue; + } + + if( (*(slab_p->color_map + (j >> 6)) & (1UL << (j % 64))) == 0 ) + { + *(slab_p->color_map + (j >> 6)) |= 1UL << (j % 64); + + slab_p->using_count++; + slab_p->free_count--; + + slab_cache->total_using++; + slab_cache->total_free--; + + if(slab_cache->constructor != NULL) + { + return slab_cache->constructor((char *)slab_p->Vaddress + slab_cache->size * j,arg); + } + else + { + return (void *)((char *)slab_p->Vaddress + slab_cache->size * j); + } + } + } + }while(slab_p != slab_cache->cache_pool); + } + + color_printk(RED,BLACK,"slab_malloc() ERROR: can`t alloc\n"); + if(tmp_slab != NULL) + { + list_del(&tmp_slab->list); + kfree(tmp_slab->color_map); + page_clean(tmp_slab->page); + free_pages(tmp_slab->page,1); + kfree(tmp_slab); + } + + return NULL; +} + +/* + +*/ + +unsigned long slab_free(struct Slab_cache * slab_cache,void * address,unsigned long arg) +{ + + struct Slab * slab_p = slab_cache->cache_pool; + int index = 0; + + do + { + if(slab_p->Vaddress <= address && address < slab_p->Vaddress + PAGE_2M_SIZE) + { + index = (address - slab_p->Vaddress) / slab_cache->size; + *(slab_p->color_map + (index >> 6)) ^= 1UL << index % 64; + slab_p->free_count++; + slab_p->using_count--; + + slab_cache->total_using--; + slab_cache->total_free++; + + if(slab_cache->destructor != NULL) + { + slab_cache->destructor((char *)slab_p->Vaddress + slab_cache->size * index,arg); + } + + if((slab_p->using_count == 0) && (slab_cache->total_free >= slab_p->color_count * 3 / 2)) + { + list_del(&slab_p->list); + slab_cache->total_free -= slab_p->color_count; + + kfree(slab_p->color_map); + + page_clean(slab_p->page); + free_pages(slab_p->page,1); + kfree(slab_p); + } + + return 1; + } + else + { + slab_p = container_of(list_next(&slab_p->list),struct Slab,list); + continue; + } + + }while(slab_p != slab_cache->cache_pool); + + color_printk(RED,BLACK,"slab_free() ERROR: address not in slab\n"); + + return 0; +} + +/* + +*/ + +unsigned long slab_init() +{ + struct Page * page = NULL; + unsigned long * virtual = NULL; // get a free page and set to empty page table and return the virtual address + unsigned long i,j; + + unsigned long tmp_address = memory_management_struct.end_of_struct; + + for(i = 0;i < 16;i++) + { + kmalloc_cache_size[i].cache_pool = (struct Slab *)memory_management_struct.end_of_struct; + memory_management_struct.end_of_struct = memory_management_struct.end_of_struct + sizeof(struct Slab) + sizeof(long) * 10; + + list_init(&kmalloc_cache_size[i].cache_pool->list); + + //////////// init sizeof struct Slab of cache size + + kmalloc_cache_size[i].cache_pool->using_count = 0; + kmalloc_cache_size[i].cache_pool->free_count = PAGE_2M_SIZE / kmalloc_cache_size[i].size; + + kmalloc_cache_size[i].cache_pool->color_length =((PAGE_2M_SIZE / kmalloc_cache_size[i].size + sizeof(unsigned long) * 8 - 1) >> 6) << 3; + + kmalloc_cache_size[i].cache_pool->color_count = kmalloc_cache_size[i].cache_pool->free_count; + + kmalloc_cache_size[i].cache_pool->color_map = (unsigned long *)memory_management_struct.end_of_struct; + + memory_management_struct.end_of_struct = (unsigned long)(memory_management_struct.end_of_struct + kmalloc_cache_size[i].cache_pool->color_length + sizeof(long) * 10) & ( ~ (sizeof(long) - 1)); + + memset(kmalloc_cache_size[i].cache_pool->color_map,0xff,kmalloc_cache_size[i].cache_pool->color_length); + + for(j = 0;j < kmalloc_cache_size[i].cache_pool->color_count;j++) + *(kmalloc_cache_size[i].cache_pool->color_map + (j >> 6)) ^= 1UL << j % 64; + + kmalloc_cache_size[i].total_free = kmalloc_cache_size[i].cache_pool->color_count; + kmalloc_cache_size[i].total_using = 0; + + } + + //////////// init page for kernel code and memory management struct + + i = Virt_To_Phy(memory_management_struct.end_of_struct) >> PAGE_2M_SHIFT; + + for(j = PAGE_2M_ALIGN(Virt_To_Phy(tmp_address)) >> PAGE_2M_SHIFT;j <= i;j++) + { + page = memory_management_struct.pages_struct + j; + *(memory_management_struct.bits_map + ((page->PHY_address >> PAGE_2M_SHIFT) >> 6)) |= 1UL << (page->PHY_address >> PAGE_2M_SHIFT) % 64; + page->zone_struct->page_using_count++; + page->zone_struct->page_free_count--; + page_init(page,PG_PTable_Maped | PG_Kernel_Init | PG_Kernel); + } + + color_printk(ORANGE,BLACK,"2.memory_management_struct.bits_map:%#018lx\tzone_struct->page_using_count:%d\tzone_struct->page_free_count:%d\n",*memory_management_struct.bits_map,memory_management_struct.zones_struct->page_using_count,memory_management_struct.zones_struct->page_free_count); + + for(i = 0;i < 16;i++) + { + virtual = (unsigned long *)((memory_management_struct.end_of_struct + PAGE_2M_SIZE * i + PAGE_2M_SIZE - 1) & PAGE_2M_MASK); + page = Virt_To_2M_Page(virtual); + + *(memory_management_struct.bits_map + ((page->PHY_address >> PAGE_2M_SHIFT) >> 6)) |= 1UL << (page->PHY_address >> PAGE_2M_SHIFT) % 64; + page->zone_struct->page_using_count++; + page->zone_struct->page_free_count--; + + page_init(page,PG_PTable_Maped | PG_Kernel_Init | PG_Kernel); + + kmalloc_cache_size[i].cache_pool->page = page; + kmalloc_cache_size[i].cache_pool->Vaddress = virtual; + } + + color_printk(ORANGE,BLACK,"3.memory_management_struct.bits_map:%#018lx\tzone_struct->page_using_count:%d\tzone_struct->page_free_count:%d\n",*memory_management_struct.bits_map,memory_management_struct.zones_struct->page_using_count,memory_management_struct.zones_struct->page_free_count); + + color_printk(ORANGE,BLACK,"start_code:%#018lx,end_code:%#018lx,end_data:%#018lx,end_brk:%#018lx,end_of_struct:%#018lx\n",memory_management_struct.start_code,memory_management_struct.end_code,memory_management_struct.end_data,memory_management_struct.end_brk, memory_management_struct.end_of_struct); + + return 1; +} + +/* + +*/ + +void pagetable_init() +{ + unsigned long i,j; + unsigned long * tmp = NULL; + + Global_CR3 = Get_gdt(); + + tmp = (unsigned long *)(((unsigned long)Phy_To_Virt((unsigned long)Global_CR3 & (~ 0xfffUL))) + 8 * 256); + +// color_printk(YELLOW,BLACK,"1:%#018lx,%#018lx\t\t\n",(unsigned long)tmp,*tmp); + + tmp = Phy_To_Virt(*tmp & (~0xfffUL)); + +// color_printk(YELLOW,BLACK,"2:%#018lx,%#018lx\t\t\n",(unsigned long)tmp,*tmp); + + tmp = Phy_To_Virt(*tmp & (~0xfffUL)); + +// color_printk(YELLOW,BLACK,"3:%#018lx,%#018lx\t\t\n",(unsigned long)tmp,*tmp); + + for(i = 0;i < memory_management_struct.zones_size;i++) + { + struct Zone * z = memory_management_struct.zones_struct + i; + struct Page * p = z->pages_group; + + if(ZONE_UNMAPED_INDEX && i == ZONE_UNMAPED_INDEX) + break; + + for(j = 0;j < z->pages_length ; j++,p++) + { + + tmp = (unsigned long *)(((unsigned long)Phy_To_Virt((unsigned long)Global_CR3 & (~ 0xfffUL))) + (((unsigned long)Phy_To_Virt(p->PHY_address) >> PAGE_GDT_SHIFT) & 0x1ff) * 8); + + if(*tmp == 0) + { + unsigned long * virtual = kmalloc(PAGE_4K_SIZE,0); + set_mpl4t(tmp,mk_mpl4t(Virt_To_Phy(virtual),PAGE_KERNEL_GDT)); + } + + tmp = (unsigned long *)((unsigned long)Phy_To_Virt(*tmp & (~ 0xfffUL)) + (((unsigned long)Phy_To_Virt(p->PHY_address) >> PAGE_1G_SHIFT) & 0x1ff) * 8); + + if(*tmp == 0) + { + unsigned long * virtual = kmalloc(PAGE_4K_SIZE,0); + set_pdpt(tmp,mk_pdpt(Virt_To_Phy(virtual),PAGE_KERNEL_Dir)); + } + + tmp = (unsigned long *)((unsigned long)Phy_To_Virt(*tmp & (~ 0xfffUL)) + (((unsigned long)Phy_To_Virt(p->PHY_address) >> PAGE_2M_SHIFT) & 0x1ff) * 8); + + set_pdt(tmp,mk_pdt(p->PHY_address,PAGE_KERNEL_Page)); + +// if(j % 50 == 0) +// color_printk(GREEN,BLACK,"@:%#018lx,%#018lx\t\n",(unsigned long)tmp,*tmp); + } + } + + flush_tlb(); +} diff --git a/kernel/memory.h b/kernel/memory.h old mode 100644 new mode 100755 index bf00e98..88cd830 --- a/kernel/memory.h +++ b/kernel/memory.h @@ -5,14 +5,14 @@ * modify it under the terms of version 2 of the GNU General Public * License as published by the Free Software Foundation. * -***************************************************/ - -#ifndef __MEMORY_H__ -#define __MEMORY_H__ - +***************************************************/ + +#ifndef __MEMORY_H__ +#define __MEMORY_H__ + #include "printk.h" -#include "lib.h" - +#include "lib.h" + // 8Bytes per cell #define PTRS_PER_PAGE 512 @@ -42,41 +42,40 @@ #define Virt_To_2M_Page(kaddr) (memory_management_struct.pages_struct + (Virt_To_Phy(kaddr) >> PAGE_2M_SHIFT)) #define Phy_to_2M_Page(kaddr) (memory_management_struct.pages_struct + ((unsigned long)(kaddr) >> PAGE_2M_SHIFT)) - ////page table attribute // bit 63 Execution Disable: -#define PAGE_XD (unsigned long)0x1000000000000000 +#define PAGE_XD (1UL << 63) // bit 12 Page Attribute Table -#define PAGE_PAT (unsigned long)0x1000 +#define PAGE_PAT (1UL << 12) // bit 8 Global Page:1,global;0,part -#define PAGE_Global (unsigned long)0x0100 +#define PAGE_Global (1UL << 8) // bit 7 Page Size:1,big page;0,small page; -#define PAGE_PS (unsigned long)0x0080 +#define PAGE_PS (1UL << 7) // bit 6 Dirty:1,dirty;0,clean; -#define PAGE_Dirty (unsigned long)0x0040 +#define PAGE_Dirty (1UL << 6) // bit 5 Accessed:1,visited;0,unvisited; -#define PAGE_Accessed (unsigned long)0x0020 +#define PAGE_Accessed (1UL << 5) // bit 4 Page Level Cache Disable -#define PAGE_PCD (unsigned long)0x0010 +#define PAGE_PCD (1UL << 4) // bit 3 Page Level Write Through -#define PAGE_PWT (unsigned long)0x0008 +#define PAGE_PWT (1UL << 3) // bit 2 User Supervisor:1,user and supervisor;0,supervisor; -#define PAGE_U_S (unsigned long)0x0004 +#define PAGE_U_S (1UL << 2) // bit 1 Read Write:1,read and write;0,read; -#define PAGE_R_W (unsigned long)0x0002 +#define PAGE_R_W (1UL << 1) // bit 0 Present:1,present;0,no present; -#define PAGE_Present (unsigned long)0x0001 +#define PAGE_Present (1UL << 0) //1,0 #define PAGE_KERNEL_GDT (PAGE_R_W | PAGE_Present) @@ -101,22 +100,18 @@ typedef struct {unsigned long pml4t;} pml4t_t; #define mk_mpl4t(addr,attr) ((unsigned long)(addr) | (unsigned long)(attr)) #define set_mpl4t(mpl4tptr,mpl4tval) (*(mpl4tptr) = (mpl4tval)) - typedef struct {unsigned long pdpt;} pdpt_t; #define mk_pdpt(addr,attr) ((unsigned long)(addr) | (unsigned long)(attr)) #define set_pdpt(pdptptr,pdptval) (*(pdptptr) = (pdptval)) - typedef struct {unsigned long pdt;} pdt_t; #define mk_pdt(addr,attr) ((unsigned long)(addr) | (unsigned long)(attr)) #define set_pdt(pdtptr,pdtval) (*(pdtptr) = (pdtval)) - typedef struct {unsigned long pt;} pt_t; #define mk_pt(addr,attr) ((unsigned long)(addr) | (unsigned long)(attr)) #define set_pt(ptptr,ptval) (*(ptptr) = (ptval)) - unsigned long * Global_CR3 = NULL; struct E820 @@ -126,7 +121,6 @@ struct E820 unsigned int type; }__attribute__((packed)); - /* */ @@ -164,37 +158,25 @@ struct Global_Memory_Descriptor // #define ZONE_UNMAPED (1 << 2) -////struct page attribute (alloc_pages flags) +////struct page attribute -// +// mapped=1 or un-mapped=0 #define PG_PTable_Maped (1 << 0) -// +// init-code=1 or normal-code/data=0 #define PG_Kernel_Init (1 << 1) -// -#define PG_Referenced (1 << 2) - -// -#define PG_Dirty (1 << 3) - -// -#define PG_Active (1 << 4) - -// -#define PG_Up_To_Date (1 << 5) +// device=1 or memory=0 +#define PG_Device (1 << 2) -// -#define PG_Device (1 << 6) - -// -#define PG_Kernel (1 << 7) +// kernel=1 or user=0 +#define PG_Kernel (1 << 3) -// -#define PG_K_Share_To_U (1 << 8) +// shared=1 or single-use=0 +#define PG_Shared (1 << 4) // -#define PG_Slab (1 << 9) +#define PG_Active (1 << 4) struct Page { @@ -207,7 +189,6 @@ struct Page unsigned long age; }; - //// each zone index int ZONE_DMA_INDEX = 0; @@ -238,16 +219,65 @@ struct Zone unsigned long total_pages_link; }; - extern struct Global_Memory_Descriptor memory_management_struct; -unsigned long page_init(struct Page * page,unsigned long flags); +/* -unsigned long page_clean(struct Page * page); +*/ -void init_memory(); +struct Slab +{ + struct List list; + struct Page * page; -struct Page * alloc_pages(int zone_select,int number,unsigned long page_flags); + unsigned long using_count; + unsigned long free_count; + + void * Vaddress; + + unsigned long color_length; + unsigned long color_count; + + unsigned long * color_map; +}; + +struct Slab_cache +{ + unsigned long size; + unsigned long total_using; + unsigned long total_free; + struct Slab * cache_pool; + struct Slab * cache_dma_pool; + void *(* constructor)(void * Vaddress,unsigned long arg); + void *(* destructor)(void * Vaddress,unsigned long arg); +}; + +/* + kmalloc`s struct +*/ + +struct Slab_cache kmalloc_cache_size[16] = +{ + {32 ,0 ,0 ,NULL ,NULL ,NULL ,NULL}, + {64 ,0 ,0 ,NULL ,NULL ,NULL ,NULL}, + {128 ,0 ,0 ,NULL ,NULL ,NULL ,NULL}, + {256 ,0 ,0 ,NULL ,NULL ,NULL ,NULL}, + {512 ,0 ,0 ,NULL ,NULL ,NULL ,NULL}, + {1024 ,0 ,0 ,NULL ,NULL ,NULL ,NULL}, //1KB + {2048 ,0 ,0 ,NULL ,NULL ,NULL ,NULL}, + {4096 ,0 ,0 ,NULL ,NULL ,NULL ,NULL}, //4KB + {8192 ,0 ,0 ,NULL ,NULL ,NULL ,NULL}, + {16384 ,0 ,0 ,NULL ,NULL ,NULL ,NULL}, + {32768 ,0 ,0 ,NULL ,NULL ,NULL ,NULL}, + {65536 ,0 ,0 ,NULL ,NULL ,NULL ,NULL}, //64KB + {131072 ,0 ,0 ,NULL ,NULL ,NULL ,NULL}, //128KB + {262144 ,0 ,0 ,NULL ,NULL ,NULL ,NULL}, + {524288 ,0 ,0 ,NULL ,NULL ,NULL ,NULL}, + {1048576,0 ,0 ,NULL ,NULL ,NULL ,NULL}, //1MB +}; + +#define SIZEOF_LONG_ALIGN(size) ((size + sizeof(long) - 1) & ~(sizeof(long) - 1) ) +#define SIZEOF_INT_ALIGN(size) ((size + sizeof(int) - 1) & ~(sizeof(int) - 1) ) /* @@ -287,6 +317,89 @@ inline unsigned long * Get_gdt() ); return tmp; } - - + +/* + +*/ + +unsigned long page_init(struct Page * page,unsigned long flags); + +unsigned long page_clean(struct Page * page); + +/* + +*/ + +unsigned long get_page_attribute(struct Page * page); + +unsigned long set_page_attribute(struct Page * page,unsigned long flags); + +/* + +*/ + +void init_memory(); + +/* + +*/ + +struct Page * alloc_pages(int zone_select,int number,unsigned long page_flags); + +void free_pages(struct Page * page,int number); + +/* + return virtual kernel address +*/ + +void * kmalloc(unsigned long size,unsigned long flags); + +/* + +*/ + +struct Slab * kmalloc_create(unsigned long size); + +/* + +*/ + +unsigned long kfree(void * address); + +/* + +*/ + +struct Slab_cache * slab_create(unsigned long size,void *(* constructor)(void * Vaddress,unsigned long arg),void *(* destructor)(void * Vaddress,unsigned long arg),unsigned long arg); + +/* + +*/ + +unsigned long slab_destroy(struct Slab_cache * slab_cache); + +/* + +*/ + +void * slab_malloc(struct Slab_cache * slab_cache,unsigned long arg); + +/* + +*/ + +unsigned long slab_free(struct Slab_cache * slab_cache,void * address,unsigned long arg); + +/* + +*/ + +unsigned long slab_init(); + +/* + +*/ + +void pagetable_init(); + #endif diff --git a/kernel/printk.c b/kernel/printk.c index c7098d5..db18190 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -12,11 +12,45 @@ #include "lib.h" #include "linkage.h" - /* */ +void frame_buffer_init() +{ + ////re init frame buffer; + unsigned long i; + unsigned long * tmp; + unsigned long * tmp1; + unsigned int * FB_addr = (unsigned int *)Phy_To_Virt(0xe0000000); + Global_CR3 = Get_gdt(); + + tmp = Phy_To_Virt((unsigned long *)((unsigned long)Global_CR3 & (~ 0xfffUL)) + (((unsigned long)FB_addr >> PAGE_GDT_SHIFT) & 0x1ff)); + if (*tmp == 0) + { + unsigned long * virtual = kmalloc(PAGE_4K_SIZE,0); + set_mpl4t(tmp,mk_mpl4t(Virt_To_Phy(virtual),PAGE_KERNEL_GDT)); + } + + tmp = Phy_To_Virt((unsigned long *)(*tmp & (~ 0xfffUL)) + (((unsigned long)FB_addr >> PAGE_1G_SHIFT) & 0x1ff)); + if(*tmp == 0) + { + unsigned long * virtual = kmalloc(PAGE_4K_SIZE,0); + set_pdpt(tmp,mk_pdpt(Virt_To_Phy(virtual),PAGE_KERNEL_Dir)); + } + + for(i = 0;i < Pos.FB_length;i += PAGE_2M_SIZE) + { + tmp1 = Phy_To_Virt((unsigned long *)(*tmp & (~ 0xfffUL)) + (((unsigned long)((unsigned long)FB_addr + i) >> PAGE_2M_SHIFT) & 0x1ff)); + + unsigned long phy = 0xe0000000 + i; + set_pdt(tmp1,mk_pdt(phy,PAGE_KERNEL_Page | PAGE_PWT | PAGE_PCD)); + } + + Pos.FB_addr = (unsigned int *)Phy_To_Virt(0xe0000000); + + flush_tlb(); +} void putchar(unsigned int * fb,int Xsize,int x,int y,unsigned int FRcolor,unsigned int BKcolor,unsigned char font) { int i = 0,j = 0; diff --git a/kernel/printk.h b/kernel/printk.h index acd0d94..e6ddb5e 100644 --- a/kernel/printk.h +++ b/kernel/printk.h @@ -13,6 +13,7 @@ #include #include "font.h" #include "linkage.h" +#include "memory.h" #define ZEROPAD 1 /* pad with zero */ #define SIGN 2 /* unsigned/signed long */ @@ -97,5 +98,7 @@ int vsprintf(char * buf,const char *fmt, va_list args); int color_printk(unsigned int FRcolor,unsigned int BKcolor,const char * fmt,...); +void frame_buffer_init(); + #endif -- Gitee