----
+# 指定格式化语言为C
+Language: C
+
+# 基于Google的代码风格规范
BasedOnStyle: Google
+
+# 每行最大字符数为120,超过会自动换行
ColumnLimit: 120
+
+# 缩进宽度为4个空格
IndentWidth: 4
+
+# Tab键宽度为4个空格
TabWidth: 4
+# 不使用Tab键,全部用空格
+UseTab: Never
+
+# 左大括号不换行,保持与上一行在同一行
+BreakBeforeBraces: Attach
+
+# 预处理指令整体与代码块一起缩进
+# IndentPPDirectives: BeforeHash
+IndentPPDirectives: None
+
+# 不自动排序头文件,保持原有顺序
+SortIncludes: false
+
+# case标签不额外缩进(相对于switch语句)
IndentCaseLabels: false
-# 行注释 "//" 前增加两个空格
+# 行尾注释前添加2个空格
SpacesBeforeTrailingComments: 2
+
+# 不自动断行
+AllowAllParametersOfDeclarationOnNextLine: false
+
+# 禁止短代码块放在一行
+AllowShortBlocksOnASingleLine: false
+
+# 禁止短case标签放在一行
+AllowShortCaseLabelsOnASingleLine: false
+
+# 禁止短函数放在一行
+AllowShortFunctionsOnASingleLine: false
+
+# 禁止短if语句放在一行
+AllowShortIfStatementsOnASingleLine: false
+
+# 禁止短循环放在一行
+AllowShortLoopsOnASingleLine: false
#include <unistd.h>
int main() {
- while(1) {
+ while (1) {
asm("nop;");
}
- //printf("hello world\n");
+ // printf("hello world\n");
return 0;
}
nop;
movl %esp,%ebp;
nop;
- movl $123,%ebx
+ movl $123,%ebx
movl $5,%eax # SYSC_WAIT
sysenter;
1:
read(0, cmd, 256);
int len = strlen(cmd);
- if (len > 0) cmd[len - 1] = 0;
+ if (len > 0) {
+ cmd[len - 1] = 0;
+ }
int pid = fork();
if (pid > 0) {
#include <page.h>
typedef struct {
- char signature[8]; // "RSD PTR "
- uint8_t checksum; // 校验和
- char oemid[6]; // OEM厂商ID
- uint8_t revision; // ACPI版本(0=1.0,2=2.0)
- uint32_t rsdt_addr; // 指向RSDT的物理地址
+ char signature[8]; // "RSD PTR "
+ uint8_t checksum; // 校验和
+ char oemid[6]; // OEM厂商ID
+ uint8_t revision; // ACPI版本(0=1.0,2=2.0)
+ uint32_t rsdt_addr; // 指向RSDT的物理地址
} __attribute__((packed)) rsdp_v1_t;
// ACPI标准表头(所有表都有)
// RSDT(Root System Description Table)结构
typedef struct {
acpi_sdt_header_t header;
- uint32_t table_ptrs[]; // 指向其他ACPI表的物理地址数组
+ uint32_t table_ptrs[]; // 指向其他ACPI表的物理地址数组
} __attribute__((packed)) rsdt_t;
-
typedef struct {
acpi_sdt_header_t header;
- uint32_t lapic_addr; // 本地APIC地址
+ uint32_t lapic_addr; // 本地APIC地址
uint32_t flags;
// 后面跟着可变长度的结构
} __attribute__((packed)) madt_t;
-
void parse_madt(paddr_t addr) {
- if(0 == addr) {
+ if (0 == addr) {
printk("MADT addr is null\n");
return;
}
page_map(addr, addr, PAGE_P | PAGE_WR);
- madt_t *madt = (madt_t *)addr;
+ madt_t* madt = (madt_t*)addr;
printk("MADT LAPIC addr %08x flags %08x\n", madt->lapic_addr, madt->flags);
- uint8_t *ptr = (uint8_t *)(madt + 1); // 跳过表头
- uint8_t *end = (uint8_t *)madt + madt->header.length;
+ uint8_t* ptr = (uint8_t*)(madt + 1); // 跳过表头
+ uint8_t* end = (uint8_t*)madt + madt->header.length;
uint32_t ioapic_cnt = 0;
uint32_t lapic_cnt = 0;
- while(ptr < end) {
- uint8_t type = ptr[0]; // 条目类型
- uint8_t length = ptr[1]; // 条目长度
+ while (ptr < end) {
+ uint8_t type = ptr[0]; // 条目类型
+ uint8_t length = ptr[1]; // 条目长度
- if(0 == length) {
+ if (0 == length) {
printk("invalid madt entry\n");
break;
}
- switch(type) {
- case 0: { // 本地APIC
- uint8_t cpu_id = ptr[2];
- uint8_t apic_id = ptr[3];
- uint32_t flags = *(uint32_t *)(ptr+4);
- if(1 == flags) {
- lapic_cnt++;
- printk("LAPIC cpu %u apic %u flags %08x\n", cpu_id, apic_id, flags);
- } else {
- printk("LAPIC cpu %u apic %u flags %08x [disabled]\n", cpu_id, apic_id, flags);
- }
- }
- break;
- case 1: { // IO APIC
- uint8_t ioapic_id = ptr[2];
- uint8_t reserved = ptr[3];
- uint32_t ioapic_addr = *(uint32_t *)(ptr+4);
- uint32_t global_irq_base = *(uint32_t *)(ptr+8);
- ioapic_cnt++;
- printk("IOAPIC id %u addr %08x global_irq_base %u\n", ioapic_id, ioapic_addr, global_irq_base);
- }
- break;
- case 2: { // IO APIC 中断源重映射
- uint8_t bus = ptr[2];
- uint8_t irq = ptr[3];
- uint32_t global_irq = *(uint32_t *)(ptr+4);
- uint16_t flags = *(uint16_t *)(ptr+8);
- printk("IOAPIC irq %u global_irq %u flags %04x bus %u\n", irq, global_irq, flags, bus);
+ switch (type) {
+ case 0: { // 本地APIC
+ uint8_t cpu_id = ptr[2];
+ uint8_t apic_id = ptr[3];
+ uint32_t flags = *(uint32_t*)(ptr + 4);
+ if (1 == flags) {
+ lapic_cnt++;
+ printk("LAPIC cpu %u apic %u flags %08x\n", cpu_id, apic_id, flags);
+ } else {
+ printk("LAPIC cpu %u apic %u flags %08x [disabled]\n", cpu_id, apic_id, flags);
}
+ } break;
+ case 1: { // IO APIC
+ uint8_t ioapic_id = ptr[2];
+ uint8_t reserved = ptr[3];
+ uint32_t ioapic_addr = *(uint32_t*)(ptr + 4);
+ uint32_t global_irq_base = *(uint32_t*)(ptr + 8);
+ ioapic_cnt++;
+ printk("IOAPIC id %u addr %08x global_irq_base %u\n", ioapic_id, ioapic_addr, global_irq_base);
+ } break;
+ case 2: { // IO APIC 中断源重映射
+ uint8_t bus = ptr[2];
+ uint8_t irq = ptr[3];
+ uint32_t global_irq = *(uint32_t*)(ptr + 4);
+ uint16_t flags = *(uint16_t*)(ptr + 8);
+ printk("IOAPIC irq %u global_irq %u flags %04x bus %u\n", irq, global_irq, flags, bus);
+ } break;
+ case 3: { // 本地APIC非统一中断
+ uint8_t cpu_id = ptr[2];
+ uint8_t apic_id = ptr[3];
+ uint8_t flags = ptr[4];
+ printk("LAPIC non-uniform cpu %u apic %u flags %02x\n", cpu_id, apic_id, flags);
+ } break;
+ case 4: { // 虚拟化APIC
+ uint16_t reserved = *(uint16_t*)(ptr + 2);
+ uint32_t apic_addr = *(uint32_t*)(ptr + 4);
+ printk("Virtual APIC addr %08x\n", apic_addr);
+ } break;
+ default:
+ printk("unknown madt entry type %u\n", type);
break;
- case 3: { // 本地APIC非统一中断
- uint8_t cpu_id = ptr[2];
- uint8_t apic_id = ptr[3];
- uint8_t flags = ptr[4];
- printk("LAPIC non-uniform cpu %u apic %u flags %02x\n", cpu_id, apic_id, flags);
- }
- break;
- case 4: { // 虚拟化APIC
- uint16_t reserved = *(uint16_t *)(ptr+2);
- uint32_t apic_addr = *(uint32_t *)(ptr+4);
- printk("Virtual APIC addr %08x\n", apic_addr);
- }
- break;
- default:
- printk("unknown madt entry type %u\n", type);
- break;
}
ptr += length;
}
}
void parse_rsdt(paddr_t addr) {
- if(0 == addr) {
+ if (0 == addr) {
printk("RSDT addr is null\n");
return;
}
page_map(addr, addr, PAGE_P | PAGE_WR);
- rsdt_t *rsdt = (rsdt_t *)addr;
+ rsdt_t* rsdt = (rsdt_t*)addr;
// 验证签名
- if(memcmp(rsdt->header.signature, "RSDT", 4) != 0) {
+ if (memcmp(rsdt->header.signature, "RSDT", 4) != 0) {
panic("ACPI RSDT invalid\n");
}
printk("RSDT have %u ACPI tables\n", table_count);
- for(int i=0; i<table_count; i++) {
+ for (int i = 0; i < table_count; i++) {
uint32_t table_phys_addr = rsdt->table_ptrs[i];
page_map((vaddr_t)table_phys_addr, (paddr_t)table_phys_addr, PAGE_P | PAGE_WR);
- acpi_sdt_header_t *table = (acpi_sdt_header_t *)table_phys_addr;
- if(table == 0) {
+ acpi_sdt_header_t* table = (acpi_sdt_header_t*)table_phys_addr;
+ if (table == 0) {
printk("ACPI table %u:%x is null\n", i, table_phys_addr);
continue;
}
char sig[5] = {0};
memcpy(sig, table->signature, 4);
- if(sig[0] == 0) {
+ if (sig[0] == 0) {
continue;
}
printk("ACPI table %u signature %s addr %08x len %u\n", i, sig, table_phys_addr, table->length);
- if(memcmp(sig, "APIC", 4) == 0) {
+ if (memcmp(sig, "APIC", 4) == 0) {
parse_madt((paddr_t)table);
}
}
-
}
-
-void parse_acpi(void *tag) {
+void parse_acpi(void* tag) {
printk("ACPI[old].RSDP ");
- struct multiboot_tag_old_acpi *acpi_tag = (struct multiboot_tag_old_acpi *)tag;
- uint8_t *rsdp = (uint8_t *)acpi_tag->rsdp;
- for(int i =0; i<acpi_tag->size; i++){
+ struct multiboot_tag_old_acpi* acpi_tag = (struct multiboot_tag_old_acpi*)tag;
+ uint8_t* rsdp = (uint8_t*)acpi_tag->rsdp;
+ for (int i = 0; i < acpi_tag->size; i++) {
printk("%02x ", rsdp[i]);
}
printk("\n");
- if(memcmp(rsdp, "RSD PTR ", 8) != 0) {
+ if (memcmp(rsdp, "RSD PTR ", 8) != 0) {
panic("ACPI[old] RSDP invalid\n");
}
- rsdp_v1_t *rsdp_v1 = (rsdp_v1_t *)rsdp;
+ rsdp_v1_t* rsdp_v1 = (rsdp_v1_t*)rsdp;
printk("ACPI[old] RSDP checksum %02x\n", rsdp_v1->checksum);
printk("ACPI[old] RSDP OEM ID %6s\n", rsdp_v1->oemid);
printk("ACPI[old] RSDP revision %u\n", rsdp_v1->revision);
printk("ACPI[old] RSDP RSDT addr %08x\n", rsdp_v1->rsdt_addr);
- system.rsdt_addr = (void *)rsdp_v1->rsdt_addr;
+ system.rsdt_addr = (void*)rsdp_v1->rsdt_addr;
}
struct boot_params boot_params __attribute__((aligned(32)));
-void parse_cmdline(const char *cmdline);
-void init_vbe(void *, void *);
+void parse_cmdline(const char* cmdline);
+void init_vbe(void*, void*);
// ticks < 0 代表永远等待
void boot_delay(int ticks) {
void setup_i8254(uint16_t);
void setup_boot_irqs();
-void parse_framebuffer(void *addr) {
- struct multiboot_tag_framebuffer *fb = (struct multiboot_tag_framebuffer *)addr;
- if(0 == fb) {
+void parse_framebuffer(void* addr) {
+ struct multiboot_tag_framebuffer* fb = (struct multiboot_tag_framebuffer*)addr;
+ if (0 == fb) {
printk("no framebuffer info\n");
}
uint8_t fb_bpp = fb->common.framebuffer_bpp;
uint8_t fb_type = fb->common.framebuffer_type;
-
system.vbe_phys_addr = fb_addr;
system.x_resolution = fb_width;
system.y_resolution = fb_height;
- printk("type %u size %u addr %lx pitch %u width %u height %u bpp %u type %u\n",
- type, size, fb_addr, fb_pitch, fb_width, fb_height, fb_bpp, fb_type);
+ printk("type %u size %u addr %lx pitch %u width %u height %u bpp %u type %u\n", type, size, fb_addr, fb_pitch,
+ fb_width, fb_height, fb_bpp, fb_type);
// 直接就不打算支持32位以外的色深
// assert(fb_bpp == 32);
}
-
void check_kernel(unsigned long addr, unsigned long magic) {
init_serial();
printk("Your boot loader does not support multiboot.\n");
boot_delay(-1);
}
- unsigned long total_size = *((unsigned long *)addr);
- struct multiboot_tag *tag = (struct multiboot_tag *)(addr + 8); // 跳过中间的 reserved 字段
+ unsigned long total_size = *((unsigned long*)addr);
+ struct multiboot_tag* tag = (struct multiboot_tag*)(addr + 8); // 跳过中间的 reserved 字段
printk("total size: %d tags: %x\n", total_size, tag);
boot_delay(DEFAULT_BOOT_DELAY_TICKS);
- struct multiboot_tag_basic_meminfo *mminfo = 0;
- struct multiboot_tag_bootdev *bootdev = 0;
- struct multiboot_tag_mmap *mmap_tag = 0;
- struct multiboot_tag_vbe *vbe = 0;
- struct multiboot_tag_framebuffer *fb = 0;
- struct multiboot_tag_elf_sections *elf = 0;
+ struct multiboot_tag_basic_meminfo* mminfo = 0;
+ struct multiboot_tag_bootdev* bootdev = 0;
+ struct multiboot_tag_mmap* mmap_tag = 0;
+ struct multiboot_tag_vbe* vbe = 0;
+ struct multiboot_tag_framebuffer* fb = 0;
+ struct multiboot_tag_elf_sections* elf = 0;
boot_params.e820map.map_cnt = 0;
bool support = true;
switch (tag->type) {
case MULTIBOOT_TAG_TYPE_CMDLINE:
- strlcpy(boot_params.cmdline, ((struct multiboot_tag_string *)tag)->string, sizeof(boot_params.cmdline));
+ strlcpy(boot_params.cmdline, ((struct multiboot_tag_string*)tag)->string, sizeof(boot_params.cmdline));
parse_cmdline(boot_params.cmdline);
break;
case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME:
- strlcpy(boot_params.bootloader, ((struct multiboot_tag_string *)tag)->string,
+ strlcpy(boot_params.bootloader, ((struct multiboot_tag_string*)tag)->string,
sizeof(boot_params.bootloader));
break;
case MULTIBOOT_TAG_TYPE_MODULE:
- struct multiboot_tag_module *m = (struct multiboot_tag_module *)tag;
- void *mod_start = (void *)m->mod_start;
+ struct multiboot_tag_module* m = (struct multiboot_tag_module*)tag;
+ void* mod_start = (void*)m->mod_start;
printk("module 0x%08x - 0x%08x size %u cmdline %s\n", m->mod_start, m->mod_end, m->size, m->cmdline);
- boot_params.boot_module_begin = (void *)m->mod_start;
- boot_params.boot_module_end = (void *)m->mod_end;
+ boot_params.boot_module_begin = (void*)m->mod_start;
+ boot_params.boot_module_end = (void*)m->mod_end;
#if 1
- const uint32_t mod_magic = *(uint32_t *)(mod_start + 0);
- const uint32_t mod_head_size = *(uint32_t *)(mod_start + 4);
- const uint32_t mod_timestamp = *(uint32_t *)(mod_start + 8);
- const uint32_t mod_file_entry_cnt = *(uint32_t *)(mod_start + 12);
- const char *mod_name = (const char *)mod_start + 16;
+ const uint32_t mod_magic = *(uint32_t*)(mod_start + 0);
+ const uint32_t mod_head_size = *(uint32_t*)(mod_start + 4);
+ const uint32_t mod_timestamp = *(uint32_t*)(mod_start + 8);
+ const uint32_t mod_file_entry_cnt = *(uint32_t*)(mod_start + 12);
+ const char* mod_name = (const char*)mod_start + 16;
printk("module magic %08x header size %u timestamp %u file entry cnt %u name %s \n", mod_magic,
mod_head_size, mod_timestamp, mod_file_entry_cnt, mod_name);
void timestamp_to_date(uint32_t ts);
int file_entry_offset = mod_head_size;
for (int i = 0; i < mod_file_entry_cnt; i++) {
- void *fe = mod_start + file_entry_offset;
+ void* fe = mod_start + file_entry_offset;
- const uint32_t fe_size = *(uint32_t *)(fe + 0);
- const uint32_t fe_type = *(uint32_t *)(fe + 4);
- const uint32_t fe_filesz = *(uint32_t *)(fe + 8);
- const uint32_t fe_offset = *(uint32_t *)(fe + 12);
- const char *fe_name = (const char *)(fe + 16);
+ const uint32_t fe_size = *(uint32_t*)(fe + 0);
+ const uint32_t fe_type = *(uint32_t*)(fe + 4);
+ const uint32_t fe_filesz = *(uint32_t*)(fe + 8);
+ const uint32_t fe_offset = *(uint32_t*)(fe + 12);
+ const char* fe_name = (const char*)(fe + 16);
file_entry_offset += fe_size;
- void *fc = mod_start + fe_offset;
+ void* fc = mod_start + fe_offset;
printk("[fe:%u:%u] file size %u type %u name %s\n", i, fe_size, fe_filesz, fe_type, fe_name);
for (int k = 0; k < 16; k++) {
- uint8_t c = *(uint8_t *)(fc + k);
+ uint8_t c = *(uint8_t*)(fc + k);
printk("%02X ", c);
}
printk("\n");
#endif
break;
case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO:
- mminfo = (struct multiboot_tag_basic_meminfo *)tag;
+ mminfo = (struct multiboot_tag_basic_meminfo*)tag;
// KB to Bytes
// no need to concern about 64bit
boot_params.mem_lower = mminfo->mem_lower << 10;
boot_params.mem_upper = mminfo->mem_upper << 10;
break;
case MULTIBOOT_TAG_TYPE_BOOTDEV:
- bootdev = (struct multiboot_tag_bootdev *)tag;
+ bootdev = (struct multiboot_tag_bootdev*)tag;
boot_params.biosdev = bootdev->biosdev;
boot_params.partition = bootdev->slice;
boot_params.sub_partition = bootdev->part;
break;
case MULTIBOOT_TAG_TYPE_MMAP:
- mmap_tag = (struct multiboot_tag_mmap *)tag;
- multiboot_memory_map_t *mmap = mmap_tag->entries;
+ mmap_tag = (struct multiboot_tag_mmap*)tag;
+ multiboot_memory_map_t* mmap = mmap_tag->entries;
while (((multiboot_uint32_t)mmap) < (((multiboot_uint32_t)mmap_tag) + mmap_tag->size)) {
boot_params.e820map.map[boot_params.e820map.map_cnt].addr = mmap->addr;
boot_params.e820map.map[boot_params.e820map.map_cnt].size = mmap->len;
boot_params.e820map.map[boot_params.e820map.map_cnt].type = mmap->type;
boot_params.e820map.map_cnt++;
- mmap = (multiboot_memory_map_t *)(((unsigned long)mmap) + mmap_tag->entry_size);
+ mmap = (multiboot_memory_map_t*)(((unsigned long)mmap) + mmap_tag->entry_size);
}
break;
case MULTIBOOT_TAG_TYPE_VBE:
- vbe = (struct multiboot_tag_vbe *)tag;
- void *vci = (void *)vbe->vbe_control_info.external_specification;
- void *vmi = (void *)vbe->vbe_mode_info.external_specification;
+ vbe = (struct multiboot_tag_vbe*)tag;
+ void* vci = (void*)vbe->vbe_control_info.external_specification;
+ void* vmi = (void*)vbe->vbe_mode_info.external_specification;
printk("VBE[deprecated] mode %04x\n", vbe->vbe_mode);
init_vbe(vci, vmi);
break;
printk("frame buffer\n");
parse_framebuffer(tag);
break;
- case MULTIBOOT_TAG_TYPE_ELF_SECTIONS:
- {
- elf = (struct multiboot_tag_elf_sections *)tag;
- Elf32_Shdr *sections = (Elf32_Shdr *)elf->sections;
- int sections_cnt = elf->num;
-
- const char *strtab = 0;
- Elf32_Shdr *strtab_section = 0;
-
- for(int i=0; i<sections_cnt; i++) {
- Elf32_Shdr *section = sections + i;
- if (section->sh_type == 3/*SHT_STRTAB*/) {
- if (i == elf->shndx) {
- strtab_section = section;
- strtab = (const char *)pa2va(section->sh_addr);
- break;
- }
+ case MULTIBOOT_TAG_TYPE_ELF_SECTIONS: {
+ elf = (struct multiboot_tag_elf_sections*)tag;
+ Elf32_Shdr* sections = (Elf32_Shdr*)elf->sections;
+ int sections_cnt = elf->num;
+
+ const char* strtab = 0;
+ Elf32_Shdr* strtab_section = 0;
+
+ for (int i = 0; i < sections_cnt; i++) {
+ Elf32_Shdr* section = sections + i;
+ if (section->sh_type == 3 /*SHT_STRTAB*/) {
+ if (i == elf->shndx) {
+ strtab_section = section;
+ strtab = (const char*)pa2va(section->sh_addr);
+ break;
}
}
+ }
- for (int i=0; i<sections_cnt; i++) {
- Elf32_Shdr *section = sections + i;
+ for (int i = 0; i < sections_cnt; i++) {
+ Elf32_Shdr* section = sections + i;
- const char *name = 0;
- if(strtab && section->sh_name < strtab_section->sh_size) {
- name = strtab + section->sh_name;
- }
-
- uint32_t addr = section->sh_addr;
- uint32_t size = section->sh_size;
- uint32_t type = section->sh_type;
- uint32_t flags = section->sh_flags;
- printk("%20s addr %08x size %08x type %08x flags %08x\n", name ? name : "(unnamed)", addr, size, type, flags);
+ const char* name = 0;
+ if (strtab && section->sh_name < strtab_section->sh_size) {
+ name = strtab + section->sh_name;
}
+
+ uint32_t addr = section->sh_addr;
+ uint32_t size = section->sh_size;
+ uint32_t type = section->sh_type;
+ uint32_t flags = section->sh_flags;
+ printk("%20s addr %08x size %08x type %08x flags %08x\n", name ? name : "(unnamed)", addr, size, type,
+ flags);
}
- break;
+ } break;
case MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR:
- printk("load base addr %08x\n", ((struct multiboot_tag_load_base_addr *)tag)->load_base_addr);
+ printk("load base addr %08x\n", ((struct multiboot_tag_load_base_addr*)tag)->load_base_addr);
break;
case MULTIBOOT_TAG_TYPE_ACPI_OLD:
- extern void parse_acpi(void *);
+ extern void parse_acpi(void*);
parse_acpi(tag);
break;
case MULTIBOOT_TAG_TYPE_ACPI_NEW:
printk("tag %x size %x\t[%ssupport]\n", tag->type, tag->size, support ? "" : "un");
// next tag
unsigned long size = (tag->size + 7) & (~7UL);
- tag = (struct multiboot_tag *)(((unsigned long)tag) + size);
+ tag = (struct multiboot_tag*)(((unsigned long)tag) + size);
}
boot_delay(DEFAULT_BOOT_DELAY_TICKS);
#endif
}
-extern void *kernel_begin;
-extern void *kernel_end;
-extern void *bootmem_bitmap_begin;
+extern void* kernel_begin;
+extern void* kernel_end;
+extern void* bootmem_bitmap_begin;
void init_system_info() {
system.kernel_begin = &kernel_begin;
unsigned long mem_lower; // in bytes
unsigned long mem_upper;
- void *boot_module_begin;
- void *boot_module_end;
+ void* boot_module_begin;
+ void* boot_module_end;
unsigned long biosdev;
unsigned long partition;
// 准备分配的超始pfn
unsigned long prepare_alloc_pfn;
- void *bitmap;
+ void* bitmap;
unsigned long mapsize;
} bootmem_data_t;
#include <string.h>
#include <system.h>
-static void get_value(const char *name, char *value) {
- const char *p;
+static void get_value(const char* name, char* value) {
+ const char* p;
if (0 != (p = strstr(system.cmdline, name))) {
if (0 != (p = strstr(p, "="))) {
p++;
- while (*p != ' ' && *p != 0) *value++ = *p++;
+ while (*p != ' ' && *p != 0) {
+ *value++ = *p++;
+ }
}
}
*value = 0;
}
-void parse_cmdline(const char *cmdline) {
+void parse_cmdline(const char* cmdline) {
char value[128];
system.cmdline = cmdline;
printk("cmdline: %s\n", system.cmdline);
* ------------------------------------------------------------------------
*/
-
-
#include <multiboot2.h>
-
// 启用FB这个功能,需要修改grub.cfg,添加如下内容
// load_video
// set gfxmode=auto
ALIGN8 struct multiboot_header_tag end;
} multiboot2_bin_header_t;
-
-
-__attribute__((section(".multiboot2_header"), used))
-const multiboot2_bin_header_t multiboot2_elf_header = {
- .header = {
- .magic = MULTIBOOT2_HEADER_MAGIC,
- .architecture = MULTIBOOT_ARCHITECTURE_I386,
- .header_length = sizeof(multiboot2_bin_header_t),
- .checksum = -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE_I386 + sizeof(multiboot2_bin_header_t)),
- },
+__attribute__((section(".multiboot2_header"), used)) const multiboot2_bin_header_t multiboot2_elf_header = {
+ .header =
+ {
+ .magic = MULTIBOOT2_HEADER_MAGIC,
+ .architecture = MULTIBOOT_ARCHITECTURE_I386,
+ .header_length = sizeof(multiboot2_bin_header_t),
+ .checksum = -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE_I386 + sizeof(multiboot2_bin_header_t)),
+ },
#if ENABLE_FB
- .fb = {
- .type = MULTIBOOT_HEADER_TAG_FRAMEBUFFER,
- .flags = MULTIBOOT_HEADER_TAG_OPTIONAL,
- .size = sizeof(struct multiboot_header_tag_framebuffer),
- .width = 1024,
- .height = 768,
- .depth = 32,
- },
+ .fb =
+ {
+ .type = MULTIBOOT_HEADER_TAG_FRAMEBUFFER,
+ .flags = MULTIBOOT_HEADER_TAG_OPTIONAL,
+ .size = sizeof(struct multiboot_header_tag_framebuffer),
+ .width = 1024,
+ .height = 768,
+ .depth = 32,
+ },
#endif
- .end = {
- // tags are terminated by a tag of type ‘0’ and size ‘8’.
- // MULTIBOOT_HEADER_TAG_END == 0
- // sizeof(struct multiboot_header_tag) == 8
- .type = MULTIBOOT_HEADER_TAG_END,
- .flags = 0,
- .size = sizeof(struct multiboot_header_tag),
- },
+ .end =
+ {
+ // tags are terminated by a tag of type ‘0’ and size ‘8’.
+ // MULTIBOOT_HEADER_TAG_END == 0
+ // sizeof(struct multiboot_header_tag) == 8
+ .type = MULTIBOOT_HEADER_TAG_END,
+ .flags = 0,
+ .size = sizeof(struct multiboot_header_tag),
+ },
};
/*
*--------------------------------------------------------------------------
* File Name: reboot.S
- *
+ *
* Description: none
- *
- *
+ *
+ *
* Author: Zhao Yanbai [zhaoyanbai@126.com]
- *
+ *
* Version: 1.0
* Create Date: Sat Jul 11 19:16:42 2009
* Last Update: Sat Jul 11 19:16:42 2009
- *
+ *
*--------------------------------------------------------------------------
*/
#define ASM
outb %al,%dx
- # Prepare Paging For Reboot
+ # Prepare Paging For Reboot
movl $256,%ecx
movl $0x100C00,%esi
movl $0x100000,%edi
* ------------------------------------------------------------------------
*/
-#include <types.h>
+#include <boot.h>
+#include <linkage.h>
#include <msr.h>
#include <page.h>
-#include <linkage.h>
-#include <boot.h>
-
-
+#include <types.h>
extern unsigned long kernel_virtual_addr_start;
extern pde_t __initdata init_pgd[PDECNT_PER_PAGE] __attribute__((__aligned__(PAGE_SIZE)));
unsigned long init_pgt_paddr = va2pa(init_pgt);
// 清空页目录
- pde_t *dir =(pde_t *)init_pgd_paddr;
- for(int i=0; i<PDECNT_PER_PAGE; i++) {
+ pde_t* dir = (pde_t*)init_pgd_paddr;
+ for (int i = 0; i < PDECNT_PER_PAGE; i++) {
dir[i] = 0;
}
// 初始化页目录
unsigned long kpde_base = get_npde((unsigned long)(&kernel_virtual_addr_start));
pde_t pd_entry = init_pgt_paddr | PAGE_WR | PAGE_P;
- for(int i=0; i<BOOT_INIT_PAGETBL_CNT; i++) {
- dir[i] = pd_entry; // 设置低端线性地址空间的页表项
- dir[kpde_base+i] = pd_entry; // 设置内核线性地址空间的页表项
+ for (int i = 0; i < BOOT_INIT_PAGETBL_CNT; i++) {
+ dir[i] = pd_entry; // 设置低端线性地址空间的页表项
+ dir[kpde_base + i] = pd_entry; // 设置内核线性地址空间的页表项
pd_entry += PAGE_SIZE;
}
-
- pte_t *table = (pte_t *)init_pgt_paddr;
+ pte_t* table = (pte_t*)init_pgt_paddr;
pte_t pt_entry = PAGE_WR | PAGE_P;
- for(int i=0; i<BOOT_INIT_PAGETBL_CNT*PTECNT_PER_PAGE; i++) {
+ for (int i = 0; i < BOOT_INIT_PAGETBL_CNT * PTECNT_PER_PAGE; i++) {
table[i] = pt_entry;
pt_entry += PAGE_SIZE;
}
// 设置页目录
- asm volatile("mov %0, %%cr3"::"r"(init_pgd_paddr));
+ asm volatile("mov %0, %%cr3" ::"r"(init_pgd_paddr));
}
// pte_t vbe_pte[PTECNT_PER_PAGE] __attribute__((__aligned__(PAGE_SIZE)));
-uint32_t segoff_to_addr(segoff_t sg) { return 0xC0000000 + (sg.segment << 4) + sg.offset; }
+uint32_t segoff_to_addr(segoff_t sg) {
+ return 0xC0000000 + (sg.segment << 4) + sg.offset;
+}
-vbe_mode_info_t *get_vbe_mode_info(uint16_t) {
+vbe_mode_info_t* get_vbe_mode_info(uint16_t) {
// 设置并执行实模式代码以调用 VBE 函数 0x4F01
// 返回指向 VBE 模式信息的指针
return NULL;
}
// extern pde_t init_pgd[];
-void init_vbe(void *vciptr, void *vmiptr) {
+void init_vbe(void* vciptr, void* vmiptr) {
// VBE是传统BIOS接口,在现代系统上可能没有被正确初始化
// 也无法在保护模式下调用VBE BIOS功能
// 因此这里只是打印VBE信息
// 更可靠的数据是 MULTIBOOT_TAG_TYPE_FRAMEBUFFER 的数据
- vbe_controller_info_t *vci = vciptr;
- vbe_mode_info_t *vmi = (vbe_mode_info_t *)vmiptr;
+ vbe_controller_info_t* vci = vciptr;
+ vbe_mode_info_t* vmi = (vbe_mode_info_t*)vmiptr;
printk("VBE[deprecated]:\n");
printk("Signature %c%c%c%c\n", vci->signature[0], vci->signature[1], vci->signature[2], vci->signature[3]);
printk("OEM product rev: %s\n", segoff_to_addr(vci->oem_product_rev_ptr));
printk("SEG %04X OFFSET %04X\n", vci->video_mode_ptr.segment, vci->video_mode_ptr.offset);
- uint16_t *modes = (uint16_t *)segoff_to_addr(vci->video_mode_ptr);
+ uint16_t* modes = (uint16_t*)segoff_to_addr(vci->video_mode_ptr);
printk("vbe modes:");
while (*modes != VBE_MODE_END) {
printk(" %04x", *modes);
- vbe_mode_info_t *mi = get_vbe_mode_info(*modes);
+ vbe_mode_info_t* mi = get_vbe_mode_info(*modes);
// 目前以下判断不会生效
if ((mi != 0) && (mi->mode_attributes & 0x01)) {
}
printk("\n");
- printk("vbe[deprecated] phys addr %08x resolution %u x %u\n", vmi->phys_base_ptr, vmi->x_resolution, vmi->y_resolution);
+ printk("vbe[deprecated] phys addr %08x resolution %u x %u\n", vmi->phys_base_ptr, vmi->x_resolution,
+ vmi->y_resolution);
#if 0
system.vbe_phys_addr = vmi->phys_base_ptr;
system.x_resolution = vmi->x_resolution;
+++ /dev/null
-# 开发日志
-
-这个文件主要用来记录特定版本的代码存在的主要问题,及修改方向。
-
-## 18cf417585b83e74d413f247fd578f2654e8c177 版本问题
-
-目前中断下半部处理有一个问题:就是第一个中断正在进行下半部分开中断处理的情况下,被第二个中断处理中断后,如果第二个中断处理有下半部处理需求,是无法得到调用的。因为第二个中断处理会直接返回不会调用下半部处理逻辑。
-
-## 92ca4828ee74f800ba3bdd132f162a739075d9f2 版本问题
-
-这个版本的问题表现是运行一段时间后,会在`clock_bh_handler`的`assert(p->state == TASK_WAIT);`处断言失败。经分析问题出在`sysc_wait`处。
-
-需要指明的前提是,目前版本代码在系统调用中上下文中还没有添加抢占相关的逻辑。
-
-
-```c
-128 int sysc_wait(unsigned long cnt) {
-129 unsigned long flags;
-130 irq_save(flags);
-131 current->state = TASK_WAIT;
-132 current->delay_jiffies = jiffies + cnt;
-133 list_add(¤t->pend, &delay_tasks);
-134 irq_restore(flags);
-135
-136 schedule();
-137 }
-```
-
-```c
-182 void schedule() {
- ......
-193 unsigned long iflags;
-194 irq_save(iflags);
-195
-196 if (0 == current->ticks) {
-197 current->turn++;
-198 current->ticks = current->priority;
-199 current->state = TASK_READY;
-200 }
-```
-
-这段代码在第`sysc_wait:134`行开中断,在`schedule:193`处再关中断。那么中断程序完全可能在这两个点之间中断这个逻辑,再叠加上ticks被减到`0`需要重新调度的条件就会出现该问题。
-
-问题路径:
-
-1. `current->ticks == 1`
-2. 程序执行到`sysc_wait:134`和`schedule:193`之间
-3. 时钟中断到达且时钟中断没有嵌套在其它中断的下半部分逻辑中
-4. 时钟中断将`current-ticks`减`1`至`0`
-5. 在时钟中断退出前调用`schedule`,
-6. `schedule`在判断到`current->ticks == 0`时无视其`TASK_WAIT`的状态,将其设置为`TASK_READY`
-7. 再次时钟中断到达,判断到睡眠队列里出现了`TASK_READY`状态的任务。
-
-### 修改方案1
-
-修改逻辑为在`schedule`完成前,不允许中断。
-
-```c
-int sysc_wait(unsigned long cnt) {
- unsigned long flags;
- irq_save(flags);
- current->state = TASK_WAIT;
- current->delay_jiffies = jiffies + cnt;
- list_add(¤t->pend, &delay_tasks);
-
- schedule();
-
- irq_restore(flags);
-}
-```
-
-### 修改方案2
-
-在`schedule`的逻辑加入只对`TASK_RUNNING`改成`TASK_READY`。
-
-```c
- if (0 == current->ticks) {
- current->turn++;
- current->ticks = current->priority;
- }
-
- if (current->state == TASK_RUNNING) {
- current->state = TASK_READY;
- }
-```
-
-目前准备采用方案2修复。
-
-## 001073af2176de114d8588124d665aad2b4f2995 版本问题
-
-### 问题表现
-
-虽然在`kernel/sched.c:schedule`里如果`0 == current->ticks`则会将其重置的逻辑,但在`clock_handler`里的`current->ticks-`代码任有可能将其值减到0后继续再减进而溢出。就算是`schedule`代码里的处理逻辑已经是在关中断的情况下进行的也无济于事。
-
-将`qemu`的速度调至10%比较容易复现这个问题。
-
-### 问题原因
-
-在这个版本中,由于在`clock_handler`里塞了过多的调试代码,导致其耗时很长。这就可能会出现如下处理序列:
-
-1. 处理器进入硬盘`14`号中断的处理逻辑
-2. 如果硬盘中断逻辑已经到达开中断的部分
-3. 这时时钟中断到达,则会中断当前硬盘中断转而执行时钟中断。
-4. 时钟中断执行`current->ticks--`,其值有可能从`1`变为`0`
-5. 时钟中断占用相当长时间,甚至超过两次时钟中断间隔
-6. 时钟中断返回前判断到当前中断处于嵌套状态,不执行重新调度,此时`current->ticks == 0`。
-7. 时钟中断返回
-8. 由于上一个时钟中断耗时过长,因此当其刚返回后,14号中断还没来得及继续执行,或者刚执行了有限的几条指令,又被下一个时钟中断打断。
-9. 重复以上逻辑,这个时钟中断逻辑就继续对`current->ticks`减`1`,使其值为`0xFFFFFFFF`。
-
-### 问题修复计划
-
-### 优化中断处理服务程序
-
-只写少量必要代码,尽快返回,不再加入大量调试程序。
-
-#### 不再支持中断嵌套
-
-不支持中断嵌套仅指不嵌套执行中断服务器程序,而其它需要在中断环境执行的逻辑是可以开中断执行的,也就是有再次被新中断打断的可能。
-
-不再支持中断嵌套后,每次中断处理过程大致如下
-
-1. 硬件触发中断,自动关中断
-2. 保存上下文
-3. 执行中断服务例程
-3. 开中断
-4. 执行其它逻辑
-5. 关中断
-6. 恢复上下文返回
-
-可以到第4步是在开中断的状态下执行的。而执行它的时候是可能被新到的中断程序再次打断的,也就是第4步是可能嵌套执行的。
-
-为了避免这种情况,将上述程序引入一个`int`型的全局变更`reenter`,并将其初始化为`-1`后再做修改
-
-1. 硬件触发中断,自动关中断
-2. 保存上下文
-3. `reenter++`
-4. 执行中断服务例程
-5. 判断`reenter != 0`则跳转到第`9`步
-6. 开中断
-7. 执行其它逻辑
-8. 关中断
-9. `reenter--`
-10. 恢复上下文返回
-
-如果在执行第`7`步后被新到中断打断,那新逻辑就会执行如下序列
-
-
-1. 硬件触发中断,自动关中断
-2. 保存上下文
-3. `reenter++`
-4. 执行中断服务例程
-5. 判断`reenter != 0`则跳转到第`9`步
-6. ~~开中断~~
-7. ~~执行其它逻辑~~
-8. ~~关中断~~
-9. `reenter--`
-10. 恢复上下文返回
-
-这样就算第`7`步很耗时,在中断打断这个步骤的情况下,它也只会被执行一次,而不会嵌套执行。这是优点,也是缺点,目前逻辑简单还能应付。后续也还是要继续优化。
-
-
-但这也改变不了时钟中断可能将`current->ticks`改成负数的情况(因为可能在`current->ticks == 0`的情况下,第`7`步是有可能再撑到下一个时钟中断将之再减1的)。因此需要在`task_union`中引入一个`need_resched`字段,当`current->ticks == 0`时不再减,而是直接将`need_resched`设置为`1`。
-
-
-1. 硬件触发中断,自动关中断
-2. 保存上下文
-3. `reenter++`
-4. 执行中断服务例程
-5. 判断`reenter != 0`则跳转到第`11`步
-6. 开中断
-7. 执行其它逻辑
-8. 关中断
-9. assert(reenter == 0);
-10. 如果`current->need_resched == 0`则继续,否则跳`20`
-11. `reenter--`
-12. 恢复上下文返回
-
-
-以下为需要进程抢占步骤,目前不分内核还是用户进程。
-
-20. `reenter--`、`current->need_resched = 0`、`current->ticks = current->priority`
-21. schedule
-22. 跳`12`
-
-相似的逻辑也可以加到系统调用返回处。这样就可以在中断返回和系统调用返回处抢占任务。
\ No newline at end of file
#define ATA_TIMEOUT 10 // 10次时钟中断
-void ata_dma_read_ext(int drv, uint64_t pos, uint16_t count, void *dest);
-int ata_pio_read_ext(int drv, uint64_t pos, uint16_t count, int timeout, void *dest);
+void ata_dma_read_ext(int drv, uint64_t pos, uint16_t count, void* dest);
+int ata_pio_read_ext(int drv, uint64_t pos, uint16_t count, int timeout, void* dest);
-void *mbr_buf;
+void* mbr_buf;
void ata_test(uint64_t nr) {
memset(mbr_buf, 0xAA, SECT_SIZE);
ata_dma_read_ext(0, nr, 1, mbr_buf);
// 2. 等到status的BSY位清除
// 3. 等到status的DRQ位或ERR位设置
u16 identify[256];
-void ata_send_read_identify_cmd(int drv) {}
+void ata_send_read_identify_cmd(int drv) {
+}
-void ata_pio_read_data(int drv, int sect_cnt, void *dst) {
+void ata_pio_read_data(int drv, int sect_cnt, void* dst) {
insl(REG_DATA(drv), dst, (512 * sect_cnt) / sizeof(uint32_t));
}
}
// 这里所用的drv是逻辑编号 ATA0、ATA1下的Master、Salve的drv分别为0,1,2,3
-bool ata_read_identify(int drv, int disable_intr, uint8_t *status, u16 *identify) {
+bool ata_read_identify(int drv, int disable_intr, uint8_t* status, u16* identify) {
memset(identify, 0, SECT_SIZE);
uint8_t ctlv = 0x00;
return true;
}
-bool ata_read_identify_packet(int drv, int disable_intr, uint8_t *status, u16 *identify) {
+bool ata_read_identify_packet(int drv, int disable_intr, uint8_t* status, u16* identify) {
memset(identify, 0, SECT_SIZE);
uint8_t ctlv = 0x00;
return true;
}
-void ata_read_identity_string(const uint16_t *identify, int bgn, int end, char *buf) {
- const char *p = (const char *)(identify + bgn);
+void ata_read_identity_string(const uint16_t* identify, int bgn, int end, char* buf) {
+ const char* p = (const char*)(identify + bgn);
int i = 0;
for (; i <= (end - bgn); i++) {
buf[2 * i + 1] = p[0];
int channel = drvid >> 1;
memset(ide_drives + i, 0, sizeof(ide_drive_t));
- ide_drive_t *drv = ide_drives + drvid;
+ ide_drive_t* drv = ide_drives + drvid;
drv->drvid = drvid;
drv->channel = channel;
drv->ide_pci_controller = ide_pci_controller + channel;
// 2. 等到status的BSY位清除
// 3. 等到status的DRQ位或ERR位设置
uint8_t status = 0;
- const char *ide_drive_type = "NONE";
+ const char* ide_drive_type = "NONE";
if (ata_read_identify(drvid, 1, &status, identify)) {
drv->present = 1;
drv->type = IDE_DRIVE_TYPE_ATA;
if ((identify[83] & (1 << 10)) != 0) {
drv->lba48 = 1;
- max_lba = *(uint64_t *)(identify + 100);
+ max_lba = *(uint64_t*)(identify + 100);
} else {
// panic("your ide disk drive do not support LBA48");
max_lba = (identify[61] << 16) | identify[60];
for (int i = 0; i < MAX_IDE_DRIVE_CNT; i++) {
int drvid = i;
- ide_drive_t *drv = ide_drives + drvid;
+ ide_drive_t* drv = ide_drives + drvid;
if (drv->present) {
assert(drv->dma == 1);
// assert(drv->lba48 == 1);
}
}
-void ide_disk_read(dev_t dev, uint32_t sect_nr, uint32_t count, bbuffer_t *b) {
+void ide_disk_read(dev_t dev, uint32_t sect_nr, uint32_t count, bbuffer_t* b) {
disk_request_t r;
r.dev = dev;
r.command = DISK_REQ_READ;
send_disk_request(&r);
}
-void tmp_ide_disk_read(dev_t dev, uint32_t sect_nr, uint32_t count, char *buf) {
+void tmp_ide_disk_read(dev_t dev, uint32_t sect_nr, uint32_t count, char* buf) {
int ret = 0;
int retry = 3;
while (retry--) {
// mbr_ext_offset: 在MBR中的扩展分区记录里的偏移地址
// lba_partition_table: 扩展分区的真实偏移地址
-void read_partition_table(ide_drive_t *drv, uint32_t mbr_ext_offset, uint64_t lba_partition_table, int depth) {
+void read_partition_table(ide_drive_t* drv, uint32_t mbr_ext_offset, uint64_t lba_partition_table, int depth) {
// disk_request_t r;
- char *sect = kmalloc(SECT_SIZE, 0);
+ char* sect = kmalloc(SECT_SIZE, 0);
memset(sect, 0xAA, SECT_SIZE);
#if 1
// partid == 0 代表整块硬盘
send_disk_request(&r);
#endif
- ide_part_t *part = 0;
+ ide_part_t* part = 0;
uint32_t part_id = 0;
// 用来计算保存下一个扩展分区的起始位置
uint64_t lba_extended_partition = 0;
- const char *pe = sect + PARTITION_TABLE_OFFSET;
+ const char* pe = sect + PARTITION_TABLE_OFFSET;
for (int i = 0; i < 4; i++) {
if (part_id >= MAX_DISK_PARTIONS) {
break;
ide_part_t pt;
pt.flags = (uint8_t)pe[0];
pt.type = (uint8_t)pe[4];
- pt.lba_start = *((uint32_t *)(pe + 8));
- pt.lba_end = *((uint32_t *)(pe + 12));
+ pt.lba_start = *((uint32_t*)(pe + 8));
+ pt.lba_end = *((uint32_t*)(pe + 12));
if (0x00 == pt.type) {
continue;
void ide_read_partions() {
for (int i = 0; i < MAX_IDE_DRIVE_CNT; i++) {
- ide_drive_t *drv = ide_drives + i;
+ ide_drive_t* drv = ide_drives + i;
int channel = i >> 1;
if (0 == drv->present) {
}
// ATA_CMD_READ_DMA_EXT
-void ata_dma_read_ext(int drvid, uint64_t pos, uint16_t count, void *dest) {
+void ata_dma_read_ext(int drvid, uint64_t pos, uint16_t count, void* dest) {
// Intel®
// 82801CA (ICH3), 82801BA
// (ICH2), 82801AA (ICH), and 82801AB
int channel = (drvid >> 1) & 0x01;
assert(channel == 0 || channel == 1);
- ide_pci_controller_t *ide_ctrl = ide_pci_controller + channel;
- ide_drive_t *drv = ide_drives + drvid;
+ ide_pci_controller_t* ide_ctrl = ide_pci_controller + channel;
+ ide_drive_t* drv = ide_drives + drvid;
// 停止DMA
outb(PCI_IDE_CMD_STOP, ide_ctrl->bus_cmd);
// TODO
int ata_dma_stop(int channel) {
- ide_pci_controller_t *ide_ctrl = ide_pci_controller + channel;
+ ide_pci_controller_t* ide_ctrl = ide_pci_controller + channel;
uint8_t x = inb(ide_ctrl->bus_cmd);
x &= ~PCI_IDE_CMD_START;
}
// ATA_CMD_READ_PIO_EXT
-int ata_pio_read_ext(int drvid, uint64_t pos, uint16_t count, int timeout, void *dest) {
- ide_drive_t *drv = ide_drives + drvid;
+int ata_pio_read_ext(int drvid, uint64_t pos, uint16_t count, int timeout, void* dest) {
+ ide_drive_t* drv = ide_drives + drvid;
// PIO读,禁用中断
outb(ATA_CTL_NIEN, REG_CTL(drvid));
#include <system.h>
// only support read
-void blk_rw(dev_t dev, u64_t offset, u32_t size, char *buf) {
+void blk_rw(dev_t dev, u64_t offset, u32_t size, char* buf) {
// assert(DEV_MAJOR(dev) == DEV_MAJOR_HDA);
// assert(offset % SECT_SIZE == 0);
// assert(size % SECT_SIZE == 0);
#include <fs.h>
#include <ide.h>
-void ide_disk_read(dev_t dev, uint32_t sect_nr, uint32_t count, bbuffer_t *b);
-void block_read(bbuffer_t *b) {
+void ide_disk_read(dev_t dev, uint32_t sect_nr, uint32_t count, bbuffer_t* b);
+void block_read(bbuffer_t* b) {
assert(b != NULL);
assert(b->data != NULL);
assert(b->page != NULL);
const int block = 0;
const int offset = 1024;
const int size = 4096;
- bbuffer_t *bb = bread(system.root_dev, block, size);
+ bbuffer_t* bb = bread(system.root_dev, block, size);
- ext2_sb_t *p = (ext2_sb_t *)(bb->data + offset);
+ ext2_sb_t* p = (ext2_sb_t*)(bb->data + offset);
printk("inodes count %u inodes per group %u free %u\n", p->s_inodes_count, p->s_inodes_per_group,
p->s_free_inodes_count);
printk("blocks count %u blocks per group %u free %u magic %04x\n", p->s_blocks_count, p->s_blocks_per_group,
cnsl_t cnsl;
-static bool empty(const cnsl_queue_t *q) { return q->head == q->tail; }
+static bool empty(const cnsl_queue_t* q) {
+ return q->head == q->tail;
+}
-static bool full(const cnsl_queue_t *q) { return (q->head + 1) % CNSL_QUEUE_SIZE == q->tail; }
+static bool full(const cnsl_queue_t* q) {
+ return (q->head + 1) % CNSL_QUEUE_SIZE == q->tail;
+}
-static void put(cnsl_queue_t *q, char c) {
+static void put(cnsl_queue_t* q, char c) {
if (!full(q)) {
q->data[q->head] = c;
q->head = (q->head + 1) % CNSL_QUEUE_SIZE;
}
}
-static bool get(cnsl_queue_t *q, char *c) {
+static bool get(cnsl_queue_t* q, char* c) {
if (!empty(q)) {
*c = q->data[q->tail];
q->tail = (q->tail + 1) % CNSL_QUEUE_SIZE;
return false;
}
-static void clear(cnsl_queue_t *q) { q->head = q->tail = 0; }
+static void clear(cnsl_queue_t* q) {
+ q->head = q->tail = 0;
+}
-static void erase(cnsl_queue_t *q) {
- if (empty(q)) return;
+static void erase(cnsl_queue_t* q) {
+ if (empty(q))
+ return;
if (q->head == 0)
q->head = CNSL_QUEUE_SIZE - 1;
q->head--;
}
-static void cnsl_queue_init(cnsl_queue_t *cq) {
- memset((void *)cq, 0, sizeof(*cq));
+static void cnsl_queue_init(cnsl_queue_t* cq) {
+ memset((void*)cq, 0, sizeof(*cq));
cq->head = 0;
cq->tail = 0;
init_wait_queue_head(&cq->wait);
if (ch == 0) {
return 0;
}
- extern tty_t *const default_tty;
+ extern tty_t* const default_tty;
if (ch == '\b') {
if (!empty(&cnsl.wr_q)) {
tty_color_putc(default_tty, '\b', TTY_FG_HIGHLIGHT | TTY_WHITE, TTY_BLACK);
if (ch == '\n') {
clear(&cnsl.wr_q);
return 0; // TODO FIX
- while (get(&cnsl.sc_q, &ch)) put(&cnsl.rd_q, ch);
+ while (get(&cnsl.sc_q, &ch))
+ put(&cnsl.rd_q, ch);
// wake_up(&rdwq);
up(&sem);
}
}
-int cnsl_read(char *buf, size_t count) {
+int cnsl_read(char* buf, size_t count) {
unsigned long flags;
assert(count > 0);
}
}
#else
- task_union *task = current;
+ task_union* task = current;
DECLARE_WAIT_QUEUE(wait, task);
add_wait_queue(&rdwq, &wait);
task->state = TASK_READY;
del_wait_queue(&rdwq, &wait);
- if (ch == '\n') goto end;
+ if (ch == '\n')
+ goto end;
break;
}
void ata_dma_stop(int channel);
-void ide_stat_print(ide_pci_controller_t *ide_ctrl) {
+void ide_stat_print(ide_pci_controller_t* ide_ctrl) {
int r = atomic_read(&(ide_ctrl->request_cnt));
int i = atomic_read(&(ide_ctrl->irq_cnt));
int c = atomic_read(&(ide_ctrl->consumed_cnt));
printlxy(MPL_IDE0 + channel, MPO_IDE, "IDE%d req %u irq %u consumed %u", channel, r, i, c);
}
-void ide_irq_bh_handler(void *arg) {
+void ide_irq_bh_handler(void* arg) {
int channel = (int)arg;
assert(channel <= 1);
assert(channel >= 0);
- ide_pci_controller_t *ide_ctrl = ide_pci_controller + channel;
+ ide_pci_controller_t* ide_ctrl = ide_pci_controller + channel;
// 读相关status寄存器
const int drvid = (channel << 1); // 虚拟一个drvid
complete(&ide_ctrl->intr_complete);
}
-void ide_irq_handler(unsigned int irq, pt_regs_t *regs, void *devid) {
+void ide_irq_handler(unsigned int irq, pt_regs_t* regs, void* devid) {
// printk("ide irq %d handler pci status: 0x%02x\n", irq, ata_pci_bus_status());
int channel = irq == ide_pci_controller[0].irq_line ? 0 : 1;
ata_dma_stop(channel);
- add_irq_bh_handler(ide_irq_bh_handler, (void *)channel);
+ add_irq_bh_handler(ide_irq_bh_handler, (void*)channel);
}
unsigned int IDE_CHL0_CMD_BASE = 0x1F0;
// 《PCI IDE Controller Specification》
// 《Programming Interface for Bus Master IDE Controller》
-void ide_pci_init(pci_device_t *pci) {
+void ide_pci_init(pci_device_t* pci) {
#if 0
uint32_t v;
uint32_t cmd;
ide_pci_controller[i].bus_cmd = iobase + PCI_IDE_CMD;
ide_pci_controller[i].bus_status = iobase + PCI_IDE_STATUS;
ide_pci_controller[i].bus_prdt = iobase + PCI_IDE_PRDT;
- ide_pci_controller[i].prdt = (prdte_t *)page2va(alloc_one_page(0));
+ ide_pci_controller[i].prdt = (prdte_t*)page2va(alloc_one_page(0));
ide_pci_controller[i].status = 0;
ide_pci_controller[i].pci_status = 0;
// kfree(buf);
// }
-const char *pci_get_info(unsigned int classcode, unsigned int progif);
+const char* pci_get_info(unsigned int classcode, unsigned int progif);
void init_pci_controller(unsigned int classcode) {
- pci_device_t *pci = pci_find_device_by_classcode(classcode);
+ pci_device_t* pci = pci_find_device_by_classcode(classcode);
if (pci == NULL) {
printk("can not find pci classcode: %08x", classcode);
panic("can not find ide controller");
}
}
-extern void *mbr_buf;
+extern void* mbr_buf;
uint8_t ata_pci_bus_status();
ide_ata_init();
}
-ide_drive_t *ide_get_drive(dev_t dev) {
+ide_drive_t* ide_get_drive(dev_t dev) {
int major = DEV_MAJOR(dev);
int minor = DEV_MINOR(dev);
assert(minor >= 0);
assert(drvid < MAX_IDE_DRIVE_CNT);
- ide_drive_t *drv = ide_drives + drvid;
+ ide_drive_t* drv = ide_drives + drvid;
return drv;
}
uint32_t eot : 1;
} prdte_t;
typedef struct _ide_pci_controller {
- pci_device_t *pci;
+ pci_device_t* pci;
unsigned int bus_iobase;
unsigned int bus_cmd;
unsigned int bus_status;
unsigned int bus_prdt;
- prdte_t *prdt;
+ prdte_t* prdt;
//
uint8_t status;
int lba48; // 是否支持LBA48
uint64_t max_lba;
- ide_pci_controller_t *ide_pci_controller;
+ ide_pci_controller_t* ide_pci_controller;
ide_part_t partions[MAX_DISK_PARTIONS];
} ide_drive_t;
#define MAX_IDE_DRIVE_CNT 4
extern ide_drive_t ide_drives[MAX_IDE_DRIVE_CNT];
-ide_drive_t *ide_get_drive(dev_t dev);
-void ide_stat_print(ide_pci_controller_t *ide_ctrl);
+ide_drive_t* ide_get_drive(dev_t dev);
+void ide_stat_print(ide_pci_controller_t* ide_ctrl);
// TODO 改造成环形缓冲区
uint8_t scan_code;
-void kbd_bh_handler(void *arg) {
+void kbd_bh_handler(void* arg) {
kbd_debug(scan_code);
if (0x80 & scan_code) { // break code
return;
cnsl_kbd_write(ch);
}
-void kbd_handler(unsigned int irq, pt_regs_t *regs, void *dev_id) {
+void kbd_handler(unsigned int irq, pt_regs_t* regs, void* dev_id) {
scan_code = inb(0x60);
add_irq_bh_handler(kbd_bh_handler, NULL);
}
-extern tty_t *const default_tty;
-extern tty_t *const monitor_tty;
-extern tty_t *const debug_tty;
+extern tty_t* const default_tty;
+extern tty_t* const monitor_tty;
+extern tty_t* const debug_tty;
extern void tty_switch_to_next();
void kbd_debug(uint8_t scan_code) {
LIST_HEAD(pci_devs);
-const char *pci_get_info(unsigned int classcode, unsigned int progif);
+const char* pci_get_info(unsigned int classcode, unsigned int progif);
int pci_read_config_byte(int cmd) {
outl(PCI_CONFIG_CMD(cmd), PCI_ADDR);
continue;
}
- pci_device_t *pci = kmalloc(sizeof(pci_device_t), 0);
+ pci_device_t* pci = kmalloc(sizeof(pci_device_t), 0);
if (0 == pci) {
printk("no space to alloc for pci_device_t\n");
continue;
}
}
-pci_device_t *pci_find_device(unsigned int vendor, unsigned int device) {
+pci_device_t* pci_find_device(unsigned int vendor, unsigned int device) {
int i;
- list_head_t *p;
- pci_device_t *pci = 0;
+ list_head_t* p;
+ pci_device_t* pci = 0;
list_for_each(p, &pci_devs) {
pci = list_entry(p, pci_device_t, list);
return 0;
}
-pci_device_t *pci_find_device_by_classcode(unsigned int classcode) {
+pci_device_t* pci_find_device_by_classcode(unsigned int classcode) {
int i;
- list_head_t *p;
- pci_device_t *pci = 0;
+ list_head_t* p;
+ pci_device_t* pci = 0;
list_for_each(p, &pci_devs) {
pci = list_entry(p, pci_device_t, list);
- if (pci->classcode == classcode) return pci;
+ if (pci->classcode == classcode)
+ return pci;
}
return 0;
}
-const char *pci_intr_pin(int pin) {
+const char* pci_intr_pin(int pin) {
switch (pin) {
case 0:
return "NONE#";
}
void dump_pci_dev() {
- list_head_t *p;
+ list_head_t* p;
int i;
list_for_each(p, &pci_devs) {
- pci_device_t *pci = list_entry(p, pci_device_t, list);
+ pci_device_t* pci = list_entry(p, pci_device_t, list);
// printk("vendor %04x device %04x class %04x:%02x bus %d intr %3d ", pci->vendor, pci->device, pci->classcode,
// pci->progif, pci->bus, pci->intr_line);
// printk("%s\n", pci_get_info(pci->classcode, pci->progif));
typedef struct pci_info {
unsigned long code;
unsigned int flag;
- const char *info;
- const char *detail;
+ const char* info;
+ const char* detail;
} pci_info_t;
pci_info_t pci_info[] = {
{0x118000, 0, "Acquisition/Signal Processing Controller", "Other Data Acquisition/Signal Processing Controller"},
{0x000000, 0, 0}};
-const char *pci_get_info(unsigned int classcode, unsigned int progif) {
- pci_info_t *p = pci_info;
- const char *s = 0;
+const char* pci_get_info(unsigned int classcode, unsigned int progif) {
+ pci_info_t* p = pci_info;
+ const char* s = 0;
while (p->code != 0 || p->flag != 0 || p->info != 0) {
unsigned long code = classcode;
typedef struct pci_member {
uint16_t vendor_id;
- char *name;
+ char* name;
} pci_member_t;
pci_member_t pci_members[] = {
{0xF5F5, "F5 Networks, Inc."},
{0xFDEF, "Fermionic Design Private Limited"},
{0xFE19, "TenaFe Inc."},
-};
\ No newline at end of file
+};
#include <pci.h>
#include <system.h>
-
void init_sata() {
- pci_device_t *pci = pci_find_device_by_classcode(0x0106);
+ pci_device_t* pci = pci_find_device_by_classcode(0x0106);
if (pci == NULL) {
printk("can not find pci classcode: %08x", 0x0106);
panic("can not find sata controller");
}
+
// progif
// 0x01 AHCI
//
printk("AHCI mode not supported\n");
}
- printk("found sata pci progif %02x %03d:%02d.%d #%02d %04X:%04X\n", pci->progif, pci->bus, pci->dev, pci->devfn, pci->intr_line, pci->vendor, pci->device);
+ printk("found sata pci progif %02x %03d:%02d.%d #%02d %04X:%04X\n", pci->progif, pci->bus, pci->dev, pci->devfn,
+ pci->intr_line, pci->vendor, pci->device);
for (int i = 0; i < 6; i++) {
printk(" sata pci BAR%u value 0x%08X\n", i, pci->bars[i]);
// if (pci->bars[i] != 0) {
// assert((pci->bars[i] & 0x1) == 0x1);
// }
}
-
}
outb(c, SERIAL_PORT);
}
-void serial_write(const char *buf, size_t size) {
+void serial_write(const char* buf, size_t size) {
// return 0;
for (size_t i = 0; i < size; i++) {
serial_putc(buf[i]);
0,
};
-int hashfn(dev_t dev, uint32_t block) { return ((dev) ^ block) % BLOCK_BUFFER_HASH_TABLE_SIZE; }
+int hashfn(dev_t dev, uint32_t block) {
+ return ((dev) ^ block) % BLOCK_BUFFER_HASH_TABLE_SIZE;
+}
typedef struct bbuffer_store {
int blocksize;
// 1024, 2048, 4096
bbuffer_store_t store[3] = {0};
-kmem_cache_t *bbufer_kmem_cache = 0;
+kmem_cache_t* bbufer_kmem_cache = 0;
-bbuffer_store_t *getstore(uint32_t size) {
+bbuffer_store_t* getstore(uint32_t size) {
assert(size == 1024 || size == 2048 || size == 4096);
- bbuffer_store_t *s = 0;
+ bbuffer_store_t* s = 0;
if (1024 == size) {
s = store + 0;
return s;
}
-bbuffer_t *get_from_hash_table(dev_t dev, uint64_t block, uint32_t size) {
- list_head_t *p = 0;
- bbuffer_t *b = 0;
+bbuffer_t* get_from_hash_table(dev_t dev, uint64_t block, uint32_t size) {
+ list_head_t* p = 0;
+ bbuffer_t* b = 0;
uint32_t hash = hashfn(dev, block);
assert(hash < BLOCK_BUFFER_HASH_TABLE_SIZE);
list_for_each(p, block_buffer_hash_table + hash) {
- bbuffer_t *t = list_entry(p, bbuffer_t, node);
+ bbuffer_t* t = list_entry(p, bbuffer_t, node);
if (t->dev != dev) {
continue;
}
return NULL;
}
-bbuffer_t *getblk(dev_t dev, uint64_t block, uint32_t size) {
+bbuffer_t* getblk(dev_t dev, uint64_t block, uint32_t size) {
assert(size == 1024 || size == 2048 || size == 4096);
// 暂时先只支持hard disk
irq_save(iflags);
// 先尝试从hash里分配
- bbuffer_t *b = get_from_hash_table(dev, block, size);
+ bbuffer_t* b = get_from_hash_table(dev, block, size);
if (NULL != b) {
return b;
}
// 如果没找到,则从store的free_list里尝试找到第一个ref_count == 0 且未上锁的
- bbuffer_store_t *s = getstore(size);
- list_head_t *p = 0;
+ bbuffer_store_t* s = getstore(size);
+ list_head_t* p = 0;
list_for_each(p, &s->free_list) {
- bbuffer_t *t = list_entry(p, bbuffer_t, node);
+ bbuffer_t* t = list_entry(p, bbuffer_t, node);
assert(NULL != t);
assert(t->block_size == size);
// FIXME
irq_restore(iflags);
-
// 虽然此时该bbuffer_t上的ref_count为0但其可能还有I/O操作没有完成
// 因为可能有的进程调用了write、read后再直接调用brelse
// 所以需要在此等待其结束
atomic_set(&(b->ref_count), 1);
b->uptodate = 0;
-
return b;
}
-void brelse(bbuffer_t *b) {
+void brelse(bbuffer_t* b) {
assert(b != NULL);
assert(atomic_read(&(b->ref_count)) > 0);
wait_completion(&b->io_done);
- bbuffer_store_t *s = getstore(b->block_size);
+ bbuffer_store_t* s = getstore(b->block_size);
assert(s != NULL);
assert(s - store < 3);
// wake_up(&s->waitq);
}
-bbuffer_t *bread(dev_t dev, uint64_t block, uint32_t size) {
- bbuffer_t *b = getblk(dev, block, size);
+bbuffer_t* bread(dev_t dev, uint64_t block, uint32_t size) {
+ bbuffer_t* b = getblk(dev, block, size);
assert(b != NULL);
init_wait_queue_head(&store[i].waitq);
int page_left_space = 0;
- void *data = NULL;
- page_t *page = NULL;
+ void* data = NULL;
+ page_t* page = NULL;
for (int j = 0; j < MAX_BBUFFER_CNT; j++) {
if (page_left_space < blocksize) {
- data = (void *)page2va(alloc_one_page(0));
+ data = (void*)page2va(alloc_one_page(0));
page = va2page(data);
}
- bbuffer_t *b = kmem_cache_alloc(bbufer_kmem_cache, 0);
+ bbuffer_t* b = kmem_cache_alloc(bbufer_kmem_cache, 0);
assert(NULL != b);
b->block = 0;
#include <vfs.h>
#define DENTRY_HASH_TABLE_SIZE 233
-static kmem_cache_t *g_dentry_kmem_cache = NULL;
+static kmem_cache_t* g_dentry_kmem_cache = NULL;
typedef struct {
list_head_t list;
mutex_t mutex;
#endif
}
-dentry_t *dentry_alloc(dentry_t *parent, const qstr_t *s) {
- dentry_t *dentry = NULL;
+dentry_t* dentry_alloc(dentry_t* parent, const qstr_t* s) {
+ dentry_t* dentry = NULL;
assert(s != NULL);
assert(s->len > 0);
return dentry;
}
-dentry_t *dentry_alloc_root(inode_t *root_inode) {
- dentry_t *dentry;
+dentry_t* dentry_alloc_root(inode_t* root_inode) {
+ dentry_t* dentry;
assert(root_inode != NULL);
return dentry;
}
-dentry_hash_entry_t *dentry_hash(dentry_t *parent, uint64_t hash) {
+dentry_hash_entry_t* dentry_hash(dentry_t* parent, uint64_t hash) {
int index = mod64(hash, DENTRY_HASH_TABLE_SIZE);
assert(index < DENTRY_HASH_TABLE_SIZE);
- dentry_hash_entry_t *dhe = dentry_hash_table + index;
+ dentry_hash_entry_t* dhe = dentry_hash_table + index;
assert(dhe != NULL);
assert(dhe >= dentry_hash_table);
return dhe;
}
-void dentry_attach_inode(dentry_t *dentry, inode_t *inode) {
+void dentry_attach_inode(dentry_t* dentry, inode_t* inode) {
assert(dentry != NULL);
// assert(inode != NULL);
dentry->d_inode = inode;
}
-void dentry_rehash(dentry_t *dentry) {
- dentry_hash_entry_t *dhe = dentry_hash(dentry->d_parent, dentry->d_name.hash);
+void dentry_rehash(dentry_t* dentry) {
+ dentry_hash_entry_t* dhe = dentry_hash(dentry->d_parent, dentry->d_name.hash);
mutex_lock(&dhe->mutex);
mutex_unlock(&dhe->mutex);
}
-void dentry_add(dentry_t *dentry, inode_t *inode) {
+void dentry_add(dentry_t* dentry, inode_t* inode) {
dentry_attach_inode(dentry, inode);
dentry_rehash(dentry);
}
-int dentry_cached_lookup(dentry_t *parent, qstr_t *s, dentry_t **dentry) {
- dentry_hash_entry_t *dhe = dentry_hash(parent, s->hash);
+int dentry_cached_lookup(dentry_t* parent, qstr_t* s, dentry_t** dentry) {
+ dentry_hash_entry_t* dhe = dentry_hash(parent, s->hash);
*dentry = NULL;
mutex_lock(&dhe->mutex);
- list_head_t *p;
+ list_head_t* p;
list_for_each(p, &dhe->list) {
*dentry = list_entry(p, dentry_t, d_hash);
assert(*dentry != NULL);
return 0;
}
-int dentry_real_lookup(dentry_t *parent, qstr_t *s, dentry_t **dentry) {
+int dentry_real_lookup(dentry_t* parent, qstr_t* s, dentry_t** dentry) {
*dentry = NULL;
int ret = 0;
assert(parent->d_inode != NULL);
- inode_t *dir = parent->d_inode;
+ inode_t* dir = parent->d_inode;
down(&dir->i_sem);
return ret;
}
- dentry_t *new_dentry = dentry_alloc(parent, s);
+ dentry_t* new_dentry = dentry_alloc(parent, s);
if (new_dentry == NULL) {
ret = -ENOMEM;
} else {
}
for (int i = 0; i < DENTRY_HASH_TABLE_SIZE; i++) {
- dentry_hash_entry_t *dhe = dentry_hash_table + i;
+ dentry_hash_entry_t* dhe = dentry_hash_table + i;
list_init(&dhe->list);
mutex_init(&dhe->mutex);
}
}
-dentry_t *dentry_get(dentry_t *dentry) {
+dentry_t* dentry_get(dentry_t* dentry) {
assert(dentry != NULL);
atomic_inc(&dentry->d_count);
return dentry;
}
-void dentry_get_locked(dentry_t *dentry) {
+void dentry_get_locked(dentry_t* dentry) {
//
}
-void dentry_put(dentry_t *dentry) {
+void dentry_put(dentry_t* dentry) {
//
}
.next = 0,
};
-void ext2_setup() { vfs_register_filesystem(&ext2_fs_type); }
+void ext2_setup() {
+ vfs_register_filesystem(&ext2_fs_type);
+}
//--------------------------------------------------------------------------
struct {
ext2_sb_t ext2_sb;
- ext2_gd_t *ext2_gd;
+ ext2_gd_t* ext2_gd;
} ext2_fs;
-extern void blk_rw(dev_t dev, u64_t offset, u32_t scnt, char *buf);
-extern void kmem_cache_free(kmem_cache_t *cache, void *addr);
+extern void blk_rw(dev_t dev, u64_t offset, u32_t scnt, char* buf);
+extern void kmem_cache_free(kmem_cache_t* cache, void* addr);
#define BLKRW(blkid, blkcnt, buf) \
do { \
blk_rw(system.root_dev, 1ULL * (blkid) * EXT2_BLOCK_SIZE, (blkcnt) * EXT2_BLOCK_SIZE, buf); \
} while (0)
-kmem_cache_t *ext2_block_cache;
-kmem_cache_t *ext2_inode_cache;
+kmem_cache_t* ext2_block_cache;
+kmem_cache_t* ext2_inode_cache;
ext2_inode_t ext2_root_inode;
static ext2_inode_t boot_inode;
static ext2_inode_t krnl_inode;
-unsigned long ext2_block_size() { return (EXT2_MIN_BLOCK_SIZE << (EXT2_SB)->s_log_block_size); }
+unsigned long ext2_block_size() {
+ return (EXT2_MIN_BLOCK_SIZE << (EXT2_SB)->s_log_block_size);
+}
-void *ext2_alloc_block() { return (void *)kmem_cache_alloc(ext2_block_cache, 0); }
+void* ext2_alloc_block() {
+ return (void*)kmem_cache_alloc(ext2_block_cache, 0);
+}
-void *ext2_free_block(void *blk) { kmem_cache_free(ext2_block_cache, blk); }
+void* ext2_free_block(void* blk) {
+ kmem_cache_free(ext2_block_cache, blk);
+}
-void *ext2_alloc_inode() { return (void *)kmem_cache_alloc(ext2_inode_cache, 0); }
+void* ext2_alloc_inode() {
+ return (void*)kmem_cache_alloc(ext2_inode_cache, 0);
+}
-#define ext2_gd(n) ((ext2_gd_t *)(EXT2_GD) + (n))
-void ext2_read_inode(unsigned int ino, ext2_inode_t *inode) {
- void *blk = ext2_alloc_block();
+#define ext2_gd(n) ((ext2_gd_t*)(EXT2_GD) + (n))
+void ext2_read_inode(unsigned int ino, ext2_inode_t* inode) {
+ void* blk = ext2_alloc_block();
assert(blk != 0);
printd("read_inode %u\n", ino);
ext2_free_block(blk);
}
-void ext2_read_file(const ext2_inode_t *inode, char *buf) {
+void ext2_read_file(const ext2_inode_t* inode, char* buf) {
assert(inode != 0);
assert(buf != 0);
assert(inode->i_size > 0 && inode->i_size <= MAX_SUPT_FILE_SIZE);
if (left) {
printd("read left %u bytes\n", left);
- void *blk = ext2_alloc_block();
+ void* blk = ext2_alloc_block();
memcpy(buf + i * EXT2_BLOCK_SIZE, blk, left);
printd("read file done\n");
}
-void ext2_read_data(const ext2_inode_t *inode, unsigned int offset, size_t size, char *buf) {
+void ext2_read_data(const ext2_inode_t* inode, unsigned int offset, size_t size, char* buf) {
assert(inode != 0);
assert(buf != 0);
assert(inode->i_size > 0 && inode->i_size <= MAX_SUPT_FILE_SIZE);
BLKRW(inode->i_block[blkid], blkcnt, buf);
}
-unsigned int ext2_search_indir(const char *name, const ext2_inode_t *inode, unsigned int *file_type) {
+unsigned int ext2_search_indir(const char* name, const ext2_inode_t* inode, unsigned int* file_type) {
unsigned int ino = 0;
*file_type = EXT2_FT_UNKNOWN;
- void *blk = ext2_alloc_block();
+ void* blk = ext2_alloc_block();
assert(blk != 0);
BLKRW(inode->i_block[0], 1, blk); // only support the first direct blocks
- ext2_dirent_t *dirent = (ext2_dirent_t *)blk;
+ ext2_dirent_t* dirent = (ext2_dirent_t*)blk;
char tmp[64];
while (dirent->name_len != 0) {
memcpy(tmp, dirent->name, dirent->name_len);
break;
}
- dirent = (ext2_dirent_t *)(((unsigned int)dirent) + dirent->rec_len);
+ dirent = (ext2_dirent_t*)(((unsigned int)dirent) + dirent->rec_len);
if (((unsigned long)dirent - (unsigned long)blk) >= EXT2_BLOCK_SIZE) {
ino = 0;
return ino;
}
-static int get_filename_from_path(const char *path, char *file) {
+static int get_filename_from_path(const char* path, char* file) {
int i = 0;
- while (*path == '/' && *path != '\0') path++;
+ while (*path == '/' && *path != '\0')
+ path++;
- while (*path != '/' && *path != '\0') file[i++] = *path++;
+ while (*path != '/' && *path != '\0')
+ file[i++] = *path++;
file[i] = 0;
return i;
}
-unsigned int ext2_search_inpath(const char *path) {
- if (path == 0 || strlen(path) == 0 || path[0] != '/') return 0;
+unsigned int ext2_search_inpath(const char* path) {
+ if (path == 0 || strlen(path) == 0 || path[0] != '/')
+ return 0;
assert(path != 0);
assert(strlen(path) > 0);
assert(path[0] == '/');
- ext2_inode_t *inode = kmalloc(sizeof(ext2_inode_t), 0);
+ ext2_inode_t* inode = kmalloc(sizeof(ext2_inode_t), 0);
assert(inode != 0);
memcpy(inode, &ext2_root_inode, sizeof(ext2_inode_t));
unsigned int file_type = EXT2_FT_UNKNOWN;
while ((len = get_filename_from_path(path, file)) != 0) {
ino = ext2_search_indir(file, inode, &file_type);
- if (ino == 0) return 0;
+ if (ino == 0)
+ return 0;
// assert(ino != 0);
path += len;
}
}
- if (file_type != EXT2_FT_REG_FILE) return 0;
+ if (file_type != EXT2_FT_REG_FILE)
+ return 0;
return ino;
}
void ext2_setup_fs() {
memset(&ext2_fs, 0, sizeof(ext2_fs));
- char *buf = kmalloc(EXT2_BLOCK_SIZE, 0);
+ char* buf = kmalloc(EXT2_BLOCK_SIZE, 0);
if (buf == 0) {
panic("out of memory");
}
printk(" blocks per group %u inodes per group %u\n", EXT2_SB->s_blocks_per_group, EXT2_SB->s_inodes_per_group);
ext2_block_cache = kmem_cache_create("ext2_block_cache", EXT2_BLOCK_SIZE, EXT2_BLOCK_SIZE);
- if (0 == ext2_block_cache) panic("setup ext2 block cache failed. out of memory");
+ if (0 == ext2_block_cache)
+ panic("setup ext2 block cache failed. out of memory");
ext2_inode_cache = kmem_cache_create("ext2_inode_cache", EXT2_INODE_SIZE, EXT2_INODE_SIZE);
- if (0 == ext2_inode_cache) panic("setup ext2 inode cache failed. out of memory");
+ if (0 == ext2_inode_cache)
+ panic("setup ext2 inode cache failed. out of memory");
ext2_fs.ext2_gd = ext2_alloc_block();
assert(ext2_fs.ext2_gd != 0);
- BLKRW(EXT2_SB->s_first_data_block + 1, 1, (char *)ext2_fs.ext2_gd);
+ BLKRW(EXT2_SB->s_first_data_block + 1, 1, (char*)ext2_fs.ext2_gd);
unsigned int gps = EXT2_SB->s_blocks_count / EXT2_SB->s_blocks_per_group;
gps += (EXT2_SB->s_blocks_count % EXT2_SB->s_blocks_per_group) ? 1 : 0;
#define EXT2_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT2_DIR_ROUND) & ~EXT2_DIR_ROUND)
#define EXT2_MAX_REC_LEN ((1 << 16) - 1)
-void ext2_read_inode(unsigned int ino, ext2_inode_t *inode);
-void ext2_read_file(const ext2_inode_t *inode, char *buf);
-void ext2_read_data(const ext2_inode_t *inode, unsigned int offset, size_t size, char *buf);
+void ext2_read_inode(unsigned int ino, ext2_inode_t* inode);
+void ext2_read_file(const ext2_inode_t* inode, char* buf);
+void ext2_read_data(const ext2_inode_t* inode, unsigned int offset, size_t size, char* buf);
#endif //_EXT2_H
#include <irq.h>
#include <task.h>
-file_t *get_file(int fd) {
+file_t* get_file(int fd) {
assert(fd >= 0);
assert(fd < NR_TASK_OPEN_CNT);
- file_t *fp = current->files.fds[fd];
+ file_t* fp = current->files.fds[fd];
// TOOD 添加对fp的引用记数
//////////
const uint32_t PAGE_HASH_BITS = 10;
const uint32_t PAGE_HASH_SIZE = 1 << PAGE_HASH_BITS;
-page_t **page_hash_table = NULL;
+page_t** page_hash_table = NULL;
-static uint32_t page_hash_func(address_space_t *mapping, uint32_t index) {
+static uint32_t page_hash_func(address_space_t* mapping, uint32_t index) {
uint32_t i = (((uint32_t)mapping) / (sizeof(inode_t) & ~(sizeof(inode_t) - 1)));
#define s(x) ((x) + (x) >> PAGE_HASH_BITS)
return s(i + index) & (PAGE_HASH_SIZE - 1);
#undef s
}
-page_t *page_hash(address_space_t *mapping, uint32_t index) {
+page_t* page_hash(address_space_t* mapping, uint32_t index) {
uint32_t hash = page_hash_func(mapping, index);
assert(hash < PAGE_HASH_SIZE);
return page_hash_table[hash];
}
-page_t *find_hash_page(address_space_t *mapping, uint32_t index) {
- page_t *page = NULL;
+page_t* find_hash_page(address_space_t* mapping, uint32_t index) {
+ page_t* page = NULL;
uint32_t hash = page_hash_func(mapping, index);
assert(hash < PAGE_HASH_SIZE);
ENTER_CRITICAL_ZONE(EFLAGS);
- page_t *p = page_hash_table[hash];
+ page_t* p = page_hash_table[hash];
while (p != NULL) {
if (p->mapping == mapping) {
return page;
}
-void add_page_to_hash(page_t *page, address_space_t *mapping, uint32_t index) {
+void add_page_to_hash(page_t* page, address_space_t* mapping, uint32_t index) {
uint32_t hash = page_hash_func(mapping, index);
assert(hash < PAGE_HASH_SIZE);
assert(page->mapping == mapping);
ENTER_CRITICAL_ZONE(EFLAGS);
- page_t *p = 0;
+ page_t* p = 0;
p = page_hash_table[hash];
page->hash_next = p;
page_hash_table[hash] = page;
EXIT_CRITICAL_ZONE(EFLAGS);
}
-void add_page_to_inode(address_space_t *mapping, page_t *page) {
+void add_page_to_inode(address_space_t* mapping, page_t* page) {
assert(mapping != NULL);
assert(page != NULL);
assert(page->mapping == mapping);
EXIT_CRITICAL_ZONE(EFLAGS);
}
-page_t *get_cached_page(address_space_t *mapping, uint32_t index) {
- page_t *page = NULL;
+page_t* get_cached_page(address_space_t* mapping, uint32_t index) {
+ page_t* page = NULL;
page = find_hash_page(mapping, index);
if (NULL == page) {
page = alloc_one_page(0);
}
void vfs_page_cache_init() {
- page_hash_table = (page_t **)page2va(alloc_one_page(0));
+ page_hash_table = (page_t**)page2va(alloc_one_page(0));
assert(page_hash_table != NULL);
memset(page_hash_table, 0, PAGE_SIZE);
}
#define MAX_FILES 1024
file_t g_files[MAX_FILES];
-void init_file(file_t *fp) {
+void init_file(file_t* fp) {
fp->f_dentry = NULL;
fp->f_flags = 0;
fp->f_ops = NULL;
}
}
-file_t *get_empty_filp() {
- file_t *fp = NULL;
+file_t* get_empty_filp() {
+ file_t* fp = NULL;
for (int i = 0; i < MAX_FILES; i++) {
- file_t *p = g_files + i;
+ file_t* p = g_files + i;
if (p->f_state == 0) {
ENTER_CRITICAL_ZONE(EFLAGS);
extern chrdev_t cnsl_chrdev;
-chrdev_t *chrdev[CHRDEV_SIZE] = {&cnsl_chrdev};
+chrdev_t* chrdev[CHRDEV_SIZE] = {&cnsl_chrdev};
// void ext2_setup_fs();
-unsigned int ext2_search_inpath(const char *path);
+unsigned int ext2_search_inpath(const char* path);
-unsigned int namei(const char *path) { return ext2_search_inpath(path); }
+unsigned int namei(const char* path) {
+ return ext2_search_inpath(path);
+}
vfsmount_t rootfs_vfsmount;
//////
-__attribute__((regparm(0))) long sysc_mkdir(const char *path, int mode) {
+__attribute__((regparm(0))) long sysc_mkdir(const char* path, int mode) {
int ret = 0;
// TODO 检查参数
}
}
- dentry_t *dentry = NULL;
+ dentry_t* dentry = NULL;
ret = path_lookup_create(&ni, &dentry);
if (0 == ret && dentry != NULL) {
assert(dentry != NULL);
#include "printk.h"
#include "system.h"
-static kmem_cache_t *g_inode_kmem_cache = NULL;
+static kmem_cache_t* g_inode_kmem_cache = NULL;
-inode_t *alloc_inode(superblock_t *sb) {
- inode_t *inode = 0;
+inode_t* alloc_inode(superblock_t* sb) {
+ inode_t* inode = 0;
assert(NULL != sb->sb_ops);
// assert(NULL != sb->sb_ops->alloc_inode);
return inode;
}
-void init_special_inode(inode_t *inode, umode_t mode, dev_t rdev) {
+void init_special_inode(inode_t* inode, umode_t mode, dev_t rdev) {
inode->i_mode = mode;
if (S_ISCHR(mode)) {
panic("todo");
#include "system.h"
#include "task.h"
-kmem_cache_t *vfsmount_kmem_cache = 0;
+kmem_cache_t* vfsmount_kmem_cache = 0;
// 通过挂载点目录的 path_t 也就是 {mount, dentry}计算hash
// 就可以得到所有挂载在该目录上的挂载描述符 vfsmount
-vfsmount_t **vfsmount_hash_table = 0;
+vfsmount_t** vfsmount_hash_table = 0;
int vfsmount_hash_table_size = 0;
-vfsmount_t *alloc_vfsmount(const char *name) {
- vfsmount_t *mnt = 0;
+vfsmount_t* alloc_vfsmount(const char* name) {
+ vfsmount_t* mnt = 0;
- mnt = (vfsmount_t *)kmem_cache_zalloc(vfsmount_kmem_cache, 0);
+ mnt = (vfsmount_t*)kmem_cache_zalloc(vfsmount_kmem_cache, 0);
if (0 == mnt) {
panic("no mem alloc for vfsmount: %s", name);
return mnt;
}
-vfsmount_t *vfs_kernel_mount(fs_type_t *type, int flags, const char *name, void *data) {
+vfsmount_t* vfs_kernel_mount(fs_type_t* type, int flags, const char* name, void* data) {
int ret = 0;
- vfsmount_t *mnt = 0;
+ vfsmount_t* mnt = 0;
assert(0 != type);
return mnt;
}
-unsigned long vfsmount_table_hash(vfsmount_t *mnt, dentry_t *dentry) {
+unsigned long vfsmount_table_hash(vfsmount_t* mnt, dentry_t* dentry) {
unsigned long h = (unsigned long)mnt / 5;
h += 1;
h += (unsigned long)dentry / 5;
return h & (vfsmount_hash_table_size - 1);
}
-void add_vfsmount_to_hash_table(vfsmount_t *mnt) {
+void add_vfsmount_to_hash_table(vfsmount_t* mnt) {
unsigned long hash = vfsmount_table_hash(mnt->mnt_parent, mnt->mnt_point);
uint32_t eflags;
irq_save(eflags);
- vfsmount_t **p = vfsmount_hash_table + hash;
+ vfsmount_t** p = vfsmount_hash_table + hash;
mnt->hash_next = *p;
panic("create vfsmount kmem cache failed");
}
- vfsmount_hash_table = (vfsmount_t **)page2va(alloc_one_page(0));
+ vfsmount_hash_table = (vfsmount_t**)page2va(alloc_one_page(0));
memset(vfsmount_hash_table, 0, PAGE_SIZE);
- vfsmount_hash_table_size = PAGE_SIZE / sizeof(vfsmount_t *);
+ vfsmount_hash_table_size = PAGE_SIZE / sizeof(vfsmount_t*);
assert(vfsmount_hash_table_size != 0);
}
void mount_root() {
- fs_type_t *type = vfs_find_filesystem("ramfs");
+ fs_type_t* type = vfs_find_filesystem("ramfs");
assert(type != NULL);
- vfsmount_t *mnt = vfs_kernel_mount(type, 0, "ramfs", NULL);
+ vfsmount_t* mnt = vfs_kernel_mount(type, 0, "ramfs", NULL);
assert(mnt != NULL);
assert(mnt->mnt_root != NULL);
#include "vfs.h"
-vfsmount_t *vfs_kernel_mount(fs_type_t *type, int flags, const char *name, void *data);
+vfsmount_t* vfs_kernel_mount(fs_type_t* type, int flags, const char* name, void* data);
int get_unused_fd() {
int fd;
- task_files_t *files = &(current->files);
+ task_files_t* files = &(current->files);
for (int i = 0; i < NR_TASK_OPEN_CNT; i++) {
if (files->fds[i] == 0) {
return -EMFILE;
}
-int filp_open(const char *path, int flags, int mode, file_t **fp) {
+int filp_open(const char* path, int flags, int mode, file_t** fp) {
int ret = 0;
assert(path != NULL);
return ret;
}
-int sysc_open(const char *path, int flags, int mode) {
+int sysc_open(const char* path, int flags, int mode) {
int fd = 0;
fd = get_unused_fd();
return fd;
}
- file_t *fp;
+ file_t* fp;
int ret = filp_open(path, flags, mode, &fp);
if (ret != 0) {
#include <types.h>
#include <vfs.h>
-bool path_init(const char *path, unsigned int flags, namei_t *ni) {
+bool path_init(const char* path, unsigned int flags, namei_t* ni) {
ni->flags = flags;
ni->last_type = LAST_ROOT;
return true;
}
-void follow_dotdot(namei_t *ni) {
+void follow_dotdot(namei_t* ni) {
#if 1
panic("not supported");
#else
while (1) {
- dentry_t *dentry = NULL;
- vfsmount_t *parent = NULL;
+ dentry_t* dentry = NULL;
+ vfsmount_t* parent = NULL;
// 如果当前目录已经是根目录
if (ni->dentry == current->dentry_root) {
#endif
}
-uint64_t compute_qstr_hash(qstr_t *q) {
+uint64_t compute_qstr_hash(qstr_t* q) {
q->hash = 0;
for (int i = 0; i < q->len; i++) {
uint64_t c = (uint64_t)(q->name[i]);
return q->hash;
}
-int follow_down(dentry_t **dentry, vfsmount_t **vfsmnt) {
+int follow_down(dentry_t** dentry, vfsmount_t** vfsmnt) {
// assert(*dentry != NULL);
// assert(*vfsmnt != NULL);
// }
}
-int path_walk(const char *path, namei_t *ni) {
- dentry_t *dentry = NULL;
+int path_walk(const char* path, namei_t* ni) {
+ dentry_t* dentry = NULL;
int ret = 0;
if (path == NULL) {
return -EINVAL;
}
// 拿到当前目录的 inode
- inode_t *inode = ni->path.dentry->d_inode;
+ inode_t* inode = ni->path.dentry->d_inode;
uint32_t path_lookup_flags = ni->flags;
return ret;
}
-int path_lookup_hash(dentry_t *base, qstr_t *name, dentry_t **dentry) {
+int path_lookup_hash(dentry_t* base, qstr_t* name, dentry_t** dentry) {
int ret = 0;
- inode_t *inode = base->d_inode;
+ inode_t* inode = base->d_inode;
ret = dentry_cached_lookup(base, name, dentry);
assert(0 == ret);
return 0;
}
- dentry_t *dentry_new = dentry_alloc(base, name);
+ dentry_t* dentry_new = dentry_alloc(base, name);
if (dentry_new == NULL) {
return ENOMEM;
}
return ret;
}
-int path_lookup_create(namei_t *ni, dentry_t **dentry) {
+int path_lookup_create(namei_t* ni, dentry_t** dentry) {
int err = 0;
// 在调用完path_lookup_create后调用 up 操作
return err;
}
-int path_open_namei(const char *path, int flags, int mode, namei_t *ni) {
+int path_open_namei(const char* path, int flags, int mode, namei_t* ni) {
int ret = 0;
- dentry_t *dentry = NULL;
- dentry_t *dir = NULL;
- inode_t *inode = NULL;
+ dentry_t* dentry = NULL;
+ dentry_t* dir = NULL;
+ inode_t* inode = NULL;
if ((flags & O_CREAT) == 0) {
path_init(path, flags, ni);
inode_t vfs_inode;
} ramfs_inode_t;
-static kmem_cache_t *g_ramfs_inode_cache = 0;
+static kmem_cache_t* g_ramfs_inode_cache = 0;
-inode_t *ramfs_get_inode(superblock_t *sb, umode_t mode, dev_t dev);
+inode_t* ramfs_get_inode(superblock_t* sb, umode_t mode, dev_t dev);
// static inode_t *ramfs_alloc_inode(superblock_t *sb) {
// ramfs_inode_t *inode = kmem_cache_alloc(g_ramfs_inode_cache, 0);
.write_end = NULL,
};
-static int ramfs_mknod(inode_t *dir, dentry_t *dentry, umode_t mode) {
+static int ramfs_mknod(inode_t* dir, dentry_t* dentry, umode_t mode) {
int ret = 0;
- inode_t *inode = NULL;
+ inode_t* inode = NULL;
inode = ramfs_get_inode(dir->i_sb, mode, 0);
if (inode == NULL) {
return ret;
}
-static int ramfs_create(inode_t *dir, dentry_t *dentry, umode_t mode, namei_t *ni) {
+static int ramfs_create(inode_t* dir, dentry_t* dentry, umode_t mode, namei_t* ni) {
return ramfs_mknod(dir, dentry, mode | S_IFREG);
}
-static int ramfs_mkdir(inode_t *dir, dentry_t *dentry, umode_t mode) {
+static int ramfs_mkdir(inode_t* dir, dentry_t* dentry, umode_t mode) {
return ramfs_mknod(dir, dentry, mode | S_IFDIR);
}
-static dentry_t *ramfs_lookup(inode_t *dir, dentry_t *dentry) {
+static dentry_t* ramfs_lookup(inode_t* dir, dentry_t* dentry) {
// 不用上dir去找了,直接用dentry就可以了
// dentry对应的inode在ramfs_mkdir等里去分配的
.mkdir = ramfs_mkdir,
};
-void ramfs_debug_set_f_ops(file_t *filp) {
+void ramfs_debug_set_f_ops(file_t* filp) {
//
filp->f_ops = &ramfs_file_operations;
}
-inode_t *ramfs_get_inode(superblock_t *sb, umode_t mode, dev_t dev) {
- inode_t *inode = alloc_inode(sb);
+inode_t* ramfs_get_inode(superblock_t* sb, umode_t mode, dev_t dev) {
+ inode_t* inode = alloc_inode(sb);
if (NULL == inode) {
return inode;
// .alloc_inode = ramfs_alloc_inode,
};
-int ramfs_fill_super_cb(superblock_t *sb, void *data) {
+int ramfs_fill_super_cb(superblock_t* sb, void* data) {
int err = 0;
// assert(sb->sb_ops != NULL);
- inode_t *fs_root_inode = ramfs_get_inode(sb, S_IFDIR, 0);
+ inode_t* fs_root_inode = ramfs_get_inode(sb, S_IFDIR, 0);
assert(fs_root_inode != NULL);
- dentry_t *fs_root_dentry = 0;
+ dentry_t* fs_root_dentry = 0;
fs_root_dentry = dentry_alloc_root(fs_root_inode);
assert(fs_root_dentry != NULL);
return err;
}
-int ramfs_read_super(fs_type_t *type, int flags, const char *name, void *data, vfsmount_t *mnt) {
+int ramfs_read_super(fs_type_t* type, int flags, const char* name, void* data, vfsmount_t* mnt) {
int ret = 0;
ret = read_super_for_nodev(type, flags, data, ramfs_fill_super_cb, mnt);
#include <sched.h>
#include <types.h>
-ssize_t vfs_generic_file_read(file_t *file, char *buf, size_t size, loff_t *p_pos) {
+ssize_t vfs_generic_file_read(file_t* file, char* buf, size_t size, loff_t* p_pos) {
ssize_t ret = 0;
loff_t pos = *p_pos;
- inode_t *inode = file->f_dentry->d_inode;
- address_space_t *mapping = inode->i_mapping;
+ inode_t* inode = file->f_dentry->d_inode;
+ address_space_t* mapping = inode->i_mapping;
assert(S_ISREG(inode->i_mode));
size_t left = size;
while (left > 0) {
- page_t *page = NULL;
+ page_t* page = NULL;
uint32_t end_index = inode->i_size >> PAGE_SHIFT;
if (index > end_index) {
break;
bytes = bytes - offset;
// 在hash里找page
- page_t *find_hash_page(address_space_t * mapping, uint32_t index);
+ page_t* find_hash_page(address_space_t * mapping, uint32_t index);
page = find_hash_page(mapping, index);
if (NULL == page) {
goto no_cached_page_in_hash;
// copy data
bytes = bytes < left ? bytes : left;
- void *addr = page2va(page);
+ void* addr = page2va(page);
// printk("memcpy bytes %u index %u\n", bytes, index);
// printk("read addr %x bytes %u index %u offset %u\n", addr, bytes, index, offset);
memcpy(buf, addr + offset, bytes);
return ret;
}
-ssize_t sysc_read(int fd, void *buf, size_t count) {
+ssize_t sysc_read(int fd, void* buf, size_t count) {
ssize_t ret = 0;
- file_t *file = get_file(fd);
+ file_t* file = get_file(fd);
if (NULL == file) {
return EBADF;
}
- inode_t *inode = file->f_dentry->d_inode;
+ inode_t* inode = file->f_dentry->d_inode;
assert(file->f_ops != 0);
assert(file->f_ops->read != 0);
assert(inode->i_fops->read != 0);
assert(file->f_ops->read == inode->i_fops->read);
- ssize_t (*read)(file_t *, char *, size_t, loff_t *);
+ ssize_t (*read)(file_t*, char*, size_t, loff_t*);
read = file->f_ops->read;
loff_t pos = file->f_pos;
#include <sched.h>
#include <stat.h>
#include <types.h>
-int sysc_stat(int fd, struct stat *stat) {
+int sysc_stat(int fd, struct stat* stat) {
#if 0
if(fd<0 || fd>=NR_OPENS)
return -EBADF;
LIST_HEAD(g_superblocks);
-static superblock_t *alloc_super(fs_type_t *type) {
- superblock_t *s;
- s = (superblock_t *)kzalloc(sizeof(superblock_t), 0);
+static superblock_t* alloc_super(fs_type_t* type) {
+ superblock_t* s;
+ s = (superblock_t*)kzalloc(sizeof(superblock_t), 0);
if (0 == s) {
panic("alloc superblock for %s", type->name);
return s;
}
static uint32_t __minor = 0;
-int set_anonymous_super(superblock_t *s, void *data) {
+int set_anonymous_super(superblock_t* s, void* data) {
s->sb_dev = MAKE_DEV(0, ++__minor);
return 0;
}
-int read_super_for_nodev(fs_type_t *type, int flags, void *data, fill_super_cb_t fill_super, vfsmount_t *mnt) {
+int read_super_for_nodev(fs_type_t* type, int flags, void* data, fill_super_cb_t fill_super, vfsmount_t* mnt) {
int err = 0;
- superblock_t *s = 0;
+ superblock_t* s = 0;
// 分配superblock
err = sget(type, NULL, set_anonymous_super, NULL, &s);
return err;
}
-int sget(fs_type_t *type, //
- int (*test)(superblock_t *, void *), //
- int (*set)(superblock_t *, void *), //
- void *data, //
- superblock_t **s //
+int sget(fs_type_t* type, //
+ int (*test)(superblock_t*, void*), //
+ int (*set)(superblock_t*, void*), //
+ void* data, //
+ superblock_t** s //
) {
int err = 0;
// 所谓“安装“就是从一个存储设备上读入超级块,在内存中建立起一个superblock结构。进而将此设备上的根目录
// 与文件系统中已经存在的一个空白目录挂上钩。
// 系统初始化时整个文件系统只有一个空白目录"/",所以根设备的根目录就安装到这个节点上。
-dentry_t *root_entry = 0;
+dentry_t* root_entry = 0;
fs_type_t file_systems = {"filesystems", 0, 0};
-int vfs_register_filesystem(fs_type_t *fs) {
+int vfs_register_filesystem(fs_type_t* fs) {
int ret = 0;
assert(fs != NULL);
INIT_LIST_HEAD(&fs->sbs);
- fs_type_t *add = &file_systems;
+ fs_type_t* add = &file_systems;
// TODO: 加锁、解锁保护
- for (fs_type_t *fst = &file_systems; fst != 0; fst = fst->next) {
+ for (fs_type_t* fst = &file_systems; fst != 0; fst = fst->next) {
if (strcmp(fst->name, fs->name) == 0) {
return -EBUSY;
}
return 0;
}
-fs_type_t *vfs_find_filesystem(const char *name) {
- for (fs_type_t *fs = &file_systems; fs != 0; fs = fs->next) {
+fs_type_t* vfs_find_filesystem(const char* name) {
+ for (fs_type_t* fs = &file_systems; fs != 0; fs = fs->next) {
if (strcmp(fs->name, name) == 0) {
return fs;
}
// }
/////////
-vfsmount_t *vfsmnt_get(vfsmount_t *m) {
+vfsmount_t* vfsmnt_get(vfsmount_t* m) {
panic("todo");
return NULL;
}
-void vfsmnt_put(vfsmount_t *m) {
+void vfsmnt_put(vfsmount_t* m) {
//
panic("todo");
}
-int vfs_create(inode_t *dir, dentry_t *dentry, int mode, namei_t *ni) {
+int vfs_create(inode_t* dir, dentry_t* dentry, int mode, namei_t* ni) {
int ret = 0;
assert(dir->i_ops != NULL);
return ret;
}
-int vfs_mkdir(inode_t *dir, dentry_t *dentry, int mode) {
+int vfs_mkdir(inode_t* dir, dentry_t* dentry, int mode) {
int ret = 0;
// TODO REMOVE
#include <types.h>
typedef struct qstr {
- const char *name;
+ const char* name;
unsigned int len;
uint64_t hash;
} qstr_t;
typedef struct address_space address_space_t;
struct path {
- dentry_t *dentry;
- vfsmount_t *mnt;
+ dentry_t* dentry;
+ vfsmount_t* mnt;
};
#define PATH_LOOKUP_PARENT /* */ 0x00000001
typedef struct file file_t;
typedef struct file_operations {
- int (*open)(inode_t *, file_t *);
- int (*release)(inode_t *, file_t *);
- ssize_t (*read)(file_t *, char *, size_t, loff_t *);
- ssize_t (*write)(file_t *, const char *, size_t, loff_t *);
+ int (*open)(inode_t*, file_t*);
+ int (*release)(inode_t*, file_t*);
+ ssize_t (*read)(file_t*, char*, size_t, loff_t*);
+ ssize_t (*write)(file_t*, const char*, size_t, loff_t*);
} file_operations_t;
struct file {
// 多个打开的文件可能是同一个文件
- dentry_t *f_dentry;
- const file_operations_t *f_ops;
+ dentry_t* f_dentry;
+ const file_operations_t* f_ops;
loff_t f_pos;
uint32_t f_flags;
// super block
typedef struct superblock {
// 该超级起的根目录的 dentry
- dentry_t *sb_root;
+ dentry_t* sb_root;
int sb_flags;
//
- void *sb_private;
+ void* sb_private;
//
- sb_operations_t *sb_ops;
+ sb_operations_t* sb_ops;
list_head_t sb_list;
list_head_t sb_instance;
} superblock_t;
struct address_space_operations {
- int (*write_page)(page_t *);
- int (*read_page)(file_t *file, page_t *);
- int (*write_begin)(file_t *file, page_t *, loff_t pos, int len);
- int (*write_end)(file_t *file, page_t *, loff_t pos, int len);
+ int (*write_page)(page_t*);
+ int (*read_page)(file_t* file, page_t*);
+ int (*write_begin)(file_t* file, page_t*, loff_t pos, int len);
+ int (*write_end)(file_t* file, page_t*, loff_t pos, int len);
};
struct address_space {
list_head_t pages;
uint32_t total_pages;
- inode_t *a_inode;
- const address_space_operations_t *a_ops;
+ inode_t* a_inode;
+ const address_space_operations_t* a_ops;
};
// dentry和inode为什么不合二为一?
// 而inode结构代表的是物理意义上的文件
// 它们之间的关系是多对一的关系
struct inode {
- superblock_t *i_sb;
+ superblock_t* i_sb;
- void *i_private;
+ void* i_private;
semaphore_t i_sem;
// fops - file ops 的副本
- const file_operations_t *i_fops;
+ const file_operations_t* i_fops;
// ops - inode ops
- const inode_operations_t *i_ops;
+ const inode_operations_t* i_ops;
// 缓存的pages
list_head_t i_pages;
umode_t i_mode; // FILE DIR CHR BLK FIFO SOCK
- address_space_t *i_mapping;
+ address_space_t* i_mapping;
address_space_t i_as;
};
atomic_t d_count;
//
- dentry_t *d_parent;
+ dentry_t* d_parent;
// 同一目录里所有结点通过d_child链接在一起
// 并连到它们父目录的d_subdirs队列中
list_head_t d_hash;
//
- superblock_t *d_sb;
+ superblock_t* d_sb;
// 每一个dentry指向一个inode
// 但多个dentry可以指向同一个inode(不实现)
- inode_t *d_inode;
+ inode_t* d_inode;
// 需要一个标记自己已经成为挂载点的标志?
// uint32_t d_flags;
list_head_t d_vfsmnt; // 所有挂载到这个目录的挂载点
//
- dentry_operations_t *d_ops;
+ dentry_operations_t* d_ops;
//
- void *d_private;
+ void* d_private;
};
struct sb_operations {
// alloc inode
- inode_t *(*alloc_inode)(superblock_t *sb);
+ inode_t* (*alloc_inode)(superblock_t* sb);
// read_inode
};
// };
struct inode_operations {
// 用于在inode下找一个dentry->d_small_name的目录项
- dentry_t *(*lookup)(inode_t *, dentry_t *);
+ dentry_t* (*lookup)(inode_t*, dentry_t*);
// 在inode下创建一个dentry->d_small_name的文件
- int (*create)(inode_t *, dentry_t *, umode_t, namei_t *);
+ int (*create)(inode_t*, dentry_t*, umode_t, namei_t*);
// 创建文件夹
- int (*mkdir)(inode_t *, dentry_t *, umode_t);
+ int (*mkdir)(inode_t*, dentry_t*, umode_t);
// link
// unlink
// 将vfsmount与被安装设备的根目录dentry关联
#define MAX_VFSMNT_NAME_LEN 32
struct vfsmount {
- dentry_t *mnt_point; // 挂载点 dentry
- dentry_t *mnt_root; // 设备根目录 dentry
- superblock_t *mnt_sb; // 被安装的设备的superblock
- struct vfsmount *mnt_parent; // 如果多个设备挂载到同一个目录,则每个vfsmount的parent都指向同一个vfsmount
+ dentry_t* mnt_point; // 挂载点 dentry
+ dentry_t* mnt_root; // 设备根目录 dentry
+ superblock_t* mnt_sb; // 被安装的设备的superblock
+ struct vfsmount* mnt_parent; // 如果多个设备挂载到同一个目录,则每个vfsmount的parent都指向同一个vfsmount
// sb->sb_ops->read_inode得到被安装设备根目录的inode
list_head_t mnt_list; // vfsmount 链表
- vfsmount_t *hash_next;
+ vfsmount_t* hash_next;
char mnt_devname[MAX_VFSMNT_NAME_LEN];
typedef struct fs_type fs_type_t;
struct fs_type {
- const char *name;
+ const char* name;
// superblock_t *(*read_super)(superblock_t *, void *);
- int (*read_super)(fs_type_t *type, int flags, const char *name, void *data, vfsmount_t *mnt);
+ int (*read_super)(fs_type_t* type, int flags, const char* name, void* data, vfsmount_t* mnt);
int flags; // FS_REQUIRES_DEV or NODEV
- struct fs_type *next;
+ struct fs_type* next;
// 同属于这个文件系统的所有超级块链表
// 因为同名文件系统可能有多个实例,所有的该文件系统的实例的superblock,都通过sbs这个链到一起
list_head_t sbs;
};
-extern superblock_t *root_sb;
+extern superblock_t* root_sb;
-int vfs_register_filesystem(fs_type_t *fs);
-fs_type_t *vfs_find_filesystem(const char *name);
+int vfs_register_filesystem(fs_type_t* fs);
+fs_type_t* vfs_find_filesystem(const char* name);
/////
-int vfs_create(inode_t *dir, dentry_t *dentry, int mode, namei_t *ni);
-int vfs_mkdir(inode_t *dir, dentry_t *dentry, int mode);
+int vfs_create(inode_t* dir, dentry_t* dentry, int mode, namei_t* ni);
+int vfs_mkdir(inode_t* dir, dentry_t* dentry, int mode);
////
-inode_t *alloc_inode(superblock_t *sb);
-void init_special_inode(inode_t *inode, umode_t mode, dev_t rdev);
+inode_t* alloc_inode(superblock_t* sb);
+void init_special_inode(inode_t* inode, umode_t mode, dev_t rdev);
////
-int dentry_cached_lookup(dentry_t *parent, //
- qstr_t *s, //
- dentry_t **dentry // OUT
+int dentry_cached_lookup(dentry_t* parent, //
+ qstr_t* s, //
+ dentry_t** dentry // OUT
);
-int dentry_real_lookup(dentry_t *parent, //
- qstr_t *s, //
- dentry_t **dentry // OUT
+int dentry_real_lookup(dentry_t* parent, //
+ qstr_t* s, //
+ dentry_t** dentry // OUT
);
-dentry_t *dentry_alloc_root(inode_t *root_inode);
-dentry_t *dentry_alloc(dentry_t *parent, const qstr_t *s);
-void dentry_add(dentry_t *dentry, inode_t *inode);
-void dentry_attach_inode(dentry_t *dentry, inode_t *inode);
+dentry_t* dentry_alloc_root(inode_t* root_inode);
+dentry_t* dentry_alloc(dentry_t* parent, const qstr_t* s);
+void dentry_add(dentry_t* dentry, inode_t* inode);
+void dentry_attach_inode(dentry_t* dentry, inode_t* inode);
-vfsmount_t *vfsmnt_get(vfsmount_t *m);
-void vfsmnt_put(vfsmount_t *m);
+vfsmount_t* vfsmnt_get(vfsmount_t* m);
+void vfsmnt_put(vfsmount_t* m);
-dentry_t *dentry_get(dentry_t *dentry);
-void dentry_get_locked(dentry_t *dentry);
+dentry_t* dentry_get(dentry_t* dentry);
+void dentry_get_locked(dentry_t* dentry);
-void dentry_put(dentry_t *dentry);
+void dentry_put(dentry_t* dentry);
//
-bool path_init(const char *path, unsigned int flags, namei_t *ni);
-int path_walk(const char *path, namei_t *ni);
-int path_lookup_create(namei_t *ni, //
- dentry_t **dentry // OUT
+bool path_init(const char* path, unsigned int flags, namei_t* ni);
+int path_walk(const char* path, namei_t* ni);
+int path_lookup_create(namei_t* ni, //
+ dentry_t** dentry // OUT
);
-int path_open_namei(const char *path, int flags, int mode, namei_t *ni);
+int path_open_namei(const char* path, int flags, int mode, namei_t* ni);
//
-ssize_t vfs_generic_file_read(file_t *file, char *buf, size_t size, loff_t *p_pos);
-ssize_t vfs_generic_file_write(file_t *file, const char *buf, size_t size, loff_t *p_pos);
+ssize_t vfs_generic_file_read(file_t* file, char* buf, size_t size, loff_t* p_pos);
+ssize_t vfs_generic_file_write(file_t* file, const char* buf, size_t size, loff_t* p_pos);
// file
-file_t *get_empty_filp();
+file_t* get_empty_filp();
#include <string.h>
#include <types.h>
-page_t *get_cached_page(address_space_t *mapping, uint32_t index);
+page_t* get_cached_page(address_space_t* mapping, uint32_t index);
-ssize_t vfs_generic_file_write(file_t *file, const char *buf, size_t size, loff_t *p_pos) {
+ssize_t vfs_generic_file_write(file_t* file, const char* buf, size_t size, loff_t* p_pos) {
ssize_t ret = 0;
loff_t pos = *p_pos;
assert(file->f_dentry->d_inode != NULL);
assert((file->f_flags & O_APPEND) == O_APPEND); // 目前只支持这个
- inode_t *inode = file->f_dentry->d_inode;
+ inode_t* inode = file->f_dentry->d_inode;
assert(inode != NULL);
- address_space_t *mapping = inode->i_mapping;
+ address_space_t* mapping = inode->i_mapping;
assert(mapping->a_inode == inode);
assert(mapping->a_ops != NULL);
// assert(mapping->a_ops->read_page != NULL);
// 找出page
// 若找不出,则分配一个,并加到cache里
- page_t *page = get_cached_page(mapping, index);
+ page_t* page = get_cached_page(mapping, index);
assert(page != NULL);
assert(page->index == index);
assert(page->mapping == mapping);
- void *addr = page2va(page);
+ void* addr = page2va(page);
// TODO
// ...
return ret;
}
-ssize_t sysc_write(int fd, const char *buf, size_t size) {
+ssize_t sysc_write(int fd, const char* buf, size_t size) {
ssize_t ret = 0;
- file_t *file = get_file(fd);
+ file_t* file = get_file(fd);
if (NULL == file) {
return EBADF;
}
// TODO 检查文件是否有写权限
- inode_t *inode = file->f_dentry->d_inode;
+ inode_t* inode = file->f_dentry->d_inode;
assert(file->f_ops != 0);
assert(file->f_ops->write != 0);
assert(inode->i_fops->write != 0);
assert(file->f_ops->write == inode->i_fops->write);
- ssize_t (*write)(file_t *, const char *, size_t, loff_t *);
+ ssize_t (*write)(file_t*, const char*, size_t, loff_t*);
write = file->f_ops->write;
ret = write(file, buf, size, &file->f_pos);
#include <global.h>
#ifndef ASM
-void assert_fail(char *exp, char *file, unsigned int line, const char *func);
+void assert_fail(char* exp, char* file, unsigned int line, const char* func);
#define assert(exp) ((exp) ? (void)(0) : assert_fail(__STRING(exp), __FILE__, __LINE__, __PRETTY_FUNCTION__))
#endif
volatile int counter;
} atomic_t;
-static inline void atomic_inc(atomic_t *v) { __sync_add_and_fetch(&(v->counter), 1); }
-static inline void atomic_dec(atomic_t *v) { __sync_sub_and_fetch(&(v->counter), 1); }
-
-static inline int atomic_read(atomic_t *v) { return *((int *)(&(v->counter))); }
-
-static inline void atomic_set(atomic_t *v, int i) { __sync_lock_test_and_set(&(v->counter), i); }
+static inline void atomic_inc(atomic_t* v) {
+ __sync_add_and_fetch(&(v->counter), 1);
+}
+static inline void atomic_dec(atomic_t* v) {
+ __sync_sub_and_fetch(&(v->counter), 1);
+}
+
+static inline int atomic_read(atomic_t* v) {
+ return *((int*)(&(v->counter)));
+}
+
+static inline void atomic_set(atomic_t* v, int i) {
+ __sync_lock_test_and_set(&(v->counter), i);
+}
#else
#ifndef _BITS_H
#define _BITS_H
-//#define SET_BIT(bit) (1UL<<bit)
-//#define CLR_BIT(bit) (~(1UL<<bit))
-//#define ISSET_BIT(val,bit) ((val) & SET_BIT(bit))
+// #define SET_BIT(bit) (1UL<<bit)
+// #define CLR_BIT(bit) (~(1UL<<bit))
+// #define ISSET_BIT(val,bit) ((val) & SET_BIT(bit))
#define SET_BIT(val, bit) (val |= (1UL << bit))
#define CLR_BIT(val, bit) (val &= (~(1UL << bit)))
-#define XOR_BIT(val, bit) (btc((unsigned int *)&val, bit), val)
+#define XOR_BIT(val, bit) (btc((unsigned int*)&val, bit), val)
#define ISSET_BIT(val, bit) (val & (1UL << bit))
#define ISCLR_BIT(val, bit) (!ISSET_BIT(val, bit))
#define BITS_PER_LONG (sizeof(unsigned long) * 8)
-static inline void btc(unsigned int *v, unsigned int b) { asm("btc %1,%0" : "=m"(*v) : "Ir"(b)); }
+static inline void btc(unsigned int* v, unsigned int b) {
+ asm("btc %1,%0" : "=m"(*v) : "Ir"(b));
+}
-static inline int test_and_set_bit(unsigned int nr, volatile unsigned long *addr) {
+static inline int test_and_set_bit(unsigned int nr, volatile unsigned long* addr) {
int oldbit;
asm("bts %2,%1\n\t"
"sbb %0,%0"
- : "=r"(oldbit), "+m"(*(volatile long *)(addr))
+ : "=r"(oldbit), "+m"(*(volatile long*)(addr))
: "Ir"(nr));
return oldbit;
}
-static inline int test_and_clear_bit(unsigned int nr, volatile unsigned long *addr) {
+static inline int test_and_clear_bit(unsigned int nr, volatile unsigned long* addr) {
int oldbit;
asm volatile(
"btr %2,%1\n\t"
"sbb %0,%0"
- : "=r"(oldbit), "+m"(*(volatile long *)(addr))
+ : "=r"(oldbit), "+m"(*(volatile long*)(addr))
: "Ir"(nr)
: "memory");
* This operation is atomic and cannot be reordered.
* It also implies a memory barrier.
*/
-static inline int test_and_change_bit(int nr, volatile unsigned long *addr) {
+static inline int test_and_change_bit(int nr, volatile unsigned long* addr) {
int oldbit;
asm volatile(
"btc %2,%1\n\t"
"sbb %0,%0"
- : "=r"(oldbit), "+m"(*(volatile long *)(addr))
+ : "=r"(oldbit), "+m"(*(volatile long*)(addr))
: "Ir"(nr)
: "memory");
* If it's called on the same region of memory simultaneously, the effect
* may be that only one operation succeeds.
*/
-static inline void change_bit(int nr, volatile unsigned long *addr) {
- asm volatile("btc %1,%0" : "+m"(*(volatile long *)(addr)) : "Ir"(nr));
+static inline void change_bit(int nr, volatile unsigned long* addr) {
+ asm volatile("btc %1,%0" : "+m"(*(volatile long*)(addr)) : "Ir"(nr));
}
-static inline int constant_test_bit(unsigned int nr, const volatile unsigned long *addr) {
- return ((1UL << (nr % BITS_PER_LONG)) & (((unsigned long *)addr)[nr / BITS_PER_LONG])) != 0;
+static inline int constant_test_bit(unsigned int nr, const volatile unsigned long* addr) {
+ return ((1UL << (nr % BITS_PER_LONG)) & (((unsigned long*)addr)[nr / BITS_PER_LONG])) != 0;
}
/**
* Returns the bit-number of the first set bit, not the number of the byte
* containing a bit.
*/
-static inline int find_first_bit(const unsigned long *addr, unsigned size) {
+static inline int find_first_bit(const unsigned long* addr, unsigned size) {
int d0, d1;
int res;
* Returns the bit-number of the first zero bit, not the number of the byte
* containing a bit.
*/
-static inline int find_first_zero_bit(const unsigned long *addr, unsigned size) {
+static inline int find_first_zero_bit(const unsigned long* addr, unsigned size) {
int d0, d1, d2;
int res;
- if (!size) return 0;
+ if (!size)
+ return 0;
/* This looks at memory. Mark it volatile to tell gcc not to move it around */
__asm__ __volatile__(
"movl $-1,%%eax\n\t"
* @offset: The bitnumber to start searching at
* @size: The maximum size to search
*/
-static inline int find_next_zero_bit(const unsigned long *addr, int size, int offset) {
- unsigned long *p = ((unsigned long *)addr) + (offset >> 5);
+static inline int find_next_zero_bit(const unsigned long* addr, int size, int offset) {
+ unsigned long* p = ((unsigned long*)addr) + (offset >> 5);
int set = 0, bit = offset & 31, res;
if (bit) {
"1:"
: "=r"(set)
: "r"(~(*p >> bit)));
- if (set < (32 - bit)) return set + offset;
+ if (set < (32 - bit))
+ return set + offset;
set = 32 - bit;
p++;
}
/*
* No zero yet, search remaining full bytes for a zero
*/
- res = find_first_zero_bit(p, size - 32 * (p - (unsigned long *)addr));
+ res = find_first_zero_bit(p, size - 32 * (p - (unsigned long*)addr));
return (offset + set + res);
}
-static inline int variable_test_bit(int nr, volatile const unsigned long *addr) {
+static inline int variable_test_bit(int nr, volatile const unsigned long* addr) {
int oldbit;
asm volatile(
"bt %2,%1\n\t"
"sbb %0,%0"
: "=r"(oldbit)
- : "m"(*(unsigned long *)addr), "Ir"(nr));
+ : "m"(*(unsigned long*)addr), "Ir"(nr));
return oldbit;
}
#include <system.h>
typedef struct bbuffer {
uint32_t block; // block number
- void *data; //
+ void* data; //
atomic_t ref_count;
dev_t dev;
- page_t *page;
+ page_t* page;
list_head_t node;
completion_t io_done;
uint16_t block_size; // block size
uint16_t uptodate : 1;
} bbuffer_t;
-bbuffer_t *bread(dev_t dev, uint64_t block, uint32_t size);
+bbuffer_t* bread(dev_t dev, uint64_t block, uint32_t size);
-void brelse(bbuffer_t *b);
+void brelse(bbuffer_t* b);
panic("BUG!"); \
} while (0)
-#define BUG_ON(condition) \
- do { \
- if (unlikely((condition) != 0)) BUG(); \
+#define BUG_ON(condition) \
+ do { \
+ if (unlikely((condition) != 0)) \
+ BUG(); \
} while (0)
wait_queue_head_t wait;
// 仅用于调试
- char *name;
+ char* name;
} completion_t;
-#define COMPLETION_INITIALIZER(x) \
- { 0, WAIT_QUEUE_HEAD_INITIALIZER(x).wait }
+#define COMPLETION_INITIALIZER(x) {0, WAIT_QUEUE_HEAD_INITIALIZER(x).wait}
-void init_completion(completion_t *x);
+void init_completion(completion_t* x);
-void wait_completion(completion_t *x);
+void wait_completion(completion_t* x);
// 一次只唤醒一个进程
-void complete(completion_t *x);
+void complete(completion_t* x);
#pragma once
-
typedef struct cpuid_regs {
unsigned long eax, ebx, ecx, edx;
} cpuid_regs_t;
-
cpuid_regs_t cpuid(unsigned long op);
dev_t dev;
uint64_t pos; // 扇区号
uint16_t count; // 扇区数
- void *buf; // 到的缓冲区
- bbuffer_t *bb;
+ void* buf; // 到的缓冲区
+ bbuffer_t* bb;
disk_request_cmd_t command; // 命令
list_head_t list;
semaphore_t sem;
semaphore_t sem;
} disk_request_queue_t;
-int send_disk_request(disk_request_t *r);
+int send_disk_request(disk_request_t* r);
#define NR_FILES (1)
#define NR_OPENS (1)
-unsigned int namei(const char *path);
+unsigned int namei(const char* path);
#define MAX_SUPT_FILE_SIZE (EXT2_IND_BLOCK * EXT2_BLOCK_SIZE)
typedef struct chrdev {
- int (*read)(char *buf, size_t count);
+ int (*read)(char* buf, size_t count);
} chrdev_t;
enum { CHRDEV_CNSL, CHRDEV_SIZE };
-extern chrdev_t *chrdev[];
+extern chrdev_t* chrdev[];
-typedef int (*fill_super_cb_t)(superblock_t *sb, void *data);
-int read_super_for_nodev(fs_type_t *type, int flags, void *data, fill_super_cb_t fill_super, vfsmount_t *mnt);
+typedef int (*fill_super_cb_t)(superblock_t* sb, void* data);
+int read_super_for_nodev(fs_type_t* type, int flags, void* data, fill_super_cb_t fill_super, vfsmount_t* mnt);
-int sget(fs_type_t *type, //
- int (*test)(superblock_t *, void *), //
- int (*set)(superblock_t *, void *), //
- void *data, //
- superblock_t **s // OUT
+int sget(fs_type_t* type, //
+ int (*test)(superblock_t*, void*), //
+ int (*set)(superblock_t*, void*), //
+ void* data, //
+ superblock_t** s // OUT
);
-file_t *get_file(int fd);
+file_t* get_file(int fd);
#endif //_FS_H
})
#define BUILDIO(bwl, type) \
- static inline void ins##bwl(int port, void *buf, unsigned long count) { \
+ static inline void ins##bwl(int port, void* buf, unsigned long count) { \
asm volatile("cld;rep;ins" #bwl : "+c"(count), "+D"(buf) : "d"(port)); \
}
#define NR_IRQS (0xFF - FIRST_IRQ_VECT)
typedef struct irq_chip {
- const char *name;
+ const char* name;
int (*enable)(unsigned int irq);
int (*disable)(unsigned int irq);
void (*ack)(unsigned int irq);
typedef struct irqaction {
// void (*handler)(pt_regs_t * regs, unsigned int irq);
- void (*handler)(unsigned int irq, pt_regs_t *regs, void *dev_id);
- const char *dev_name;
- void *dev_id;
- struct irqaction *next;
+ void (*handler)(unsigned int irq, pt_regs_t* regs, void* dev_id);
+ const char* dev_name;
+ void* dev_id;
+ struct irqaction* next;
} irq_action_t;
typedef struct irq_desc {
- irq_chip_t *chip;
- irq_action_t *action;
+ irq_chip_t* chip;
+ irq_action_t* action;
unsigned int status;
unsigned int depth;
} irq_desc_t;
typedef struct irq_bh_action {
void (*handler)();
- void *arg;
- struct irq_bh_action *next;
+ void* arg;
+ struct irq_bh_action* next;
} irq_bh_action_t;
extern irq_chip_t i8259_chip;
extern irq_desc_t no_irq_desc;
int request_irq(unsigned int irq,
// void (*handler)(pt_regs_t *, unsigned int),
- void (*handler)(unsigned int, pt_regs_t *, void *), const char *devname, void *dev_id);
+ void (*handler)(unsigned int, pt_regs_t*, void*), const char* devname, void* dev_id);
-void add_irq_bh_handler(void (*handler)(), void *arg);
+void add_irq_bh_handler(void (*handler)(), void* arg);
int open_irq(unsigned int irq);
int close_irq(unsigned int irq);
void enter_critical_zone();
void exit_critical_zone();
-#define ENTER_CRITICAL_ZONE(x) \
- volatile uint32_t __critical_zone_eflags_##x = 0; \
- irq_save(__critical_zone_eflags_##x);
+#define ENTER_CRITICAL_ZONE(x) \
+ volatile uint32_t __critical_zone_eflags_##x = 0; \
+ irq_save(__critical_zone_eflags_##x);
-
-#define EXIT_CRITICAL_ZONE(x) \
- irq_restore(__critical_zone_eflags_##x);
+#define EXIT_CRITICAL_ZONE(x) irq_restore(__critical_zone_eflags_##x);
#define IRQ_CLOCK 0x00
#define IRQ_KEYBOARD 0x01
struct list_head *prev, *next;
} list_head_t;
-#define LIST_HEAD_INIT(name) \
- { &(name), &(name) }
+#define LIST_HEAD_INIT(name) {&(name), &(name)}
#define LIST_HEAD(name) list_head_t name = LIST_HEAD_INIT(name)
#define INIT_LIST_HEAD(ptr) \
(ptr)->prev = (ptr); \
} while (0)
-#define list_entry(ptr, type, member) ((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))
+#define list_entry(ptr, type, member) ((type*)((char*)(ptr) - (unsigned long)(&((type*)0)->member)))
#define list_first_entry(ptr, type, member) list_entry((ptr)->next, type, member)
tmp = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); pos = tmp, tmp = list_entry(tmp->member.next, typeof(*tmp), member))
-static inline void _list_add(list_head_t *pnew, list_head_t *prev, list_head_t *next) {
+static inline void _list_add(list_head_t* pnew, list_head_t* prev, list_head_t* next) {
next->prev = pnew;
pnew->next = next;
pnew->prev = prev;
prev->next = pnew;
}
-static inline void list_add(list_head_t *pnew, list_head_t *head) { _list_add(pnew, head, head->next); }
+static inline void list_add(list_head_t* pnew, list_head_t* head) {
+ _list_add(pnew, head, head->next);
+}
-static inline void list_add_tail(list_head_t *pnew, list_head_t *head) { _list_add(pnew, head->prev, head); }
+static inline void list_add_tail(list_head_t* pnew, list_head_t* head) {
+ _list_add(pnew, head->prev, head);
+}
-static inline void _list_del(list_head_t *prev, list_head_t *next) {
+static inline void _list_del(list_head_t* prev, list_head_t* next) {
next->prev = prev;
prev->next = next;
}
-static inline void list_del(list_head_t *entry) { _list_del(entry->prev, entry->next); }
+static inline void list_del(list_head_t* entry) {
+ _list_del(entry->prev, entry->next);
+}
-static inline void list_del_init(list_head_t *entry) {
+static inline void list_del_init(list_head_t* entry) {
_list_del(entry->prev, entry->next);
INIT_LIST_HEAD(entry);
}
-static inline int list_empty(list_head_t *head) { return head->next == head; }
+static inline int list_empty(list_head_t* head) {
+ return head->next == head;
+}
-static inline void list_init(list_head_t *head) { INIT_LIST_HEAD(head); }
+static inline void list_init(list_head_t* head) {
+ INIT_LIST_HEAD(head);
+}
#define BOOTMEM_PAGE_FREE 0
#define BOOTMEM_PAGE_USED 1
-void *alloc_bootmem(unsigned long size, unsigned long align);
+void* alloc_bootmem(unsigned long size, unsigned long align);
unsigned long bootmem_max_pfn();
unsigned long bootmem_page_state(unsigned long pfn);
-kmem_cache_t *kmem_cache_create(const char *name, size_t size, size_t align);
-void *kmem_cache_alloc(kmem_cache_t *cache, gfp_t gfpflags);
-void *kmem_cache_zalloc(kmem_cache_t *cache, gfp_t gfpflags);
+kmem_cache_t* kmem_cache_create(const char* name, size_t size, size_t align);
+void* kmem_cache_alloc(kmem_cache_t* cache, gfp_t gfpflags);
+void* kmem_cache_zalloc(kmem_cache_t* cache, gfp_t gfpflags);
#define VM_READ 0x00000001
#define VM_WRITE 0x00000002
uint32_t vm_flags;
- struct vm_area *vm_next;
+ struct vm_area* vm_next;
} vm_area_t;
// bit[12:MAXPHYADDR] 用于配置APIC寄存器组的物理基地址
#define MSR_IA32_APIC_BASE 0x1B
-
-
#define MSR_SYSENTER_CS 0x174
#define MSR_SYSENTER_ESP 0x175
#define MSR_SYSENTER_EIP 0x176
#define MSR_IA32_PERF_STATUS 0x198
#define MSR_IA32_PERF_CRTL 0x199
-
// APIC的ID寄存器
#define MSR_IA32_X2APIC_APICID 0x802
// APIC的版本寄存器
#define PAGE_FLAGS(addr) ((addr) - PAGE_ALIGN(addr))
#define va2pa(x) (((unsigned long)(x)) - PAGE_OFFSET)
-#define pa2va(x) ((void *)(((unsigned long)(x)) + PAGE_OFFSET))
+#define pa2va(x) ((void*)(((unsigned long)(x)) + PAGE_OFFSET))
// pfn: page frame number
#define pa2pfn(addr) ((addr) >> PAGE_SHIFT)
-#define pfn2pa(pfn) ((void *)((pfn) << PAGE_SHIFT))
+#define pfn2pa(pfn) ((void*)((pfn) << PAGE_SHIFT))
#define va2pfn(addr) pa2pfn(va2pa(addr))
#define pfn2va(pfn) pa2va(pfn2pa(pfn))
return cr3;
}
-static inline pde_t *get_pgd() {
- return (pde_t *)(get_cr3() & PAGE_MASK);
+static inline pde_t* get_pgd() {
+ return (pde_t*)(get_cr3() & PAGE_MASK);
}
typedef unsigned int gfp_t;
list_head_t list;
- struct page *head_page; // buddy system
+ struct page* head_page; // buddy system
unsigned int order;
- void **freelist; // for slub
+ void** freelist; // for slub
unsigned long index;
- struct page *hash_next;
- struct address_space *mapping;
+ struct page* hash_next;
+ struct address_space* mapping;
- kmem_cache_t *cache;
+ kmem_cache_t* cache;
unsigned long inuse;
//
- struct blk_buffer *buffers;
+ struct blk_buffer* buffers;
} page_t;
-void *page2va(page_t *page);
-void *page2pa(page_t *page);
-page_t *_va2page(unsigned long addr);
-page_t *_pa2page(unsigned long addr);
+void* page2va(page_t* page);
+void* page2pa(page_t* page);
+page_t* _va2page(unsigned long addr);
+page_t* _pa2page(unsigned long addr);
#define va2page(addr) _va2page(PAGE_ALIGN(addr))
#define pa2page(addr) _pa2page(PAGE_ALIGN(addr))
-static inline page_t *get_head_page(page_t *page) { return page->head_page; }
+static inline page_t* get_head_page(page_t* page) {
+ return page->head_page;
+}
-#define __GETPAGEFLAG(name) \
- static inline int Page##name(page_t *page) { return constant_test_bit(PG_##name, &page->flags); }
+#define __GETPAGEFLAG(name) \
+ static inline int Page##name(page_t* page) { \
+ return constant_test_bit(PG_##name, &page->flags); \
+ }
-#define __SETPAGEFLAG(name) \
- static inline int SetPage##name(page_t *page) { return test_and_set_bit(PG_##name, &page->flags); }
+#define __SETPAGEFLAG(name) \
+ static inline int SetPage##name(page_t* page) { \
+ return test_and_set_bit(PG_##name, &page->flags); \
+ }
-#define __CLEARPAGEFLAG(name) \
- static inline int ClearPage##name(page_t *page) { return test_and_clear_bit(PG_##name, &page->flags); }
+#define __CLEARPAGEFLAG(name) \
+ static inline int ClearPage##name(page_t* page) { \
+ return test_and_clear_bit(PG_##name, &page->flags); \
+ }
__GETPAGEFLAG(Private)
__SETPAGEFLAG(Private)
list_head_t free_list;
} free_area_t;
-page_t *alloc_pages(unsigned int gfp_mask, unsigned int order);
+page_t* alloc_pages(unsigned int gfp_mask, unsigned int order);
void free_pages(unsigned long addr);
#define alloc_one_page(gfp_mask) alloc_pages(gfp_mask, 0)
struct kmem_cache {
- const char *name;
+ const char* name;
// 预期分配的大小
unsigned long objsize;
list_head_t partial;
// 正在分配的页
- page_t *page;
+ page_t* page;
list_head_t list;
};
-
void page_map(vaddr_t vaddr, paddr_t paddr, uint32_t flags);
#endif // ASM
#define PCI_VENDORID_NVIDIA 0x10DE
#define PCI_VENDORID_REALTEK 0x10EC
-pci_device_t *pci_find_device(unsigned int vendor, unsigned int device);
-pci_device_t *pci_find_device_by_classcode(unsigned int classcode);
+pci_device_t* pci_find_device(unsigned int vendor, unsigned int device);
+pci_device_t* pci_find_device_by_classcode(unsigned int classcode);
-static inline u32 pci_cmd(pci_device_t *pci, unsigned int reg) { return PCI_CMD(pci->bus, pci->dev, pci->devfn, reg); }
+static inline u32 pci_cmd(pci_device_t* pci, unsigned int reg) {
+ return PCI_CMD(pci->bus, pci->dev, pci->devfn, reg);
+}
int pci_read_config_byte(int cmd);
int pci_read_config_word(int cmd);
#pragma once
-int printk(const char *fmtstr, ...);
-int printd(const char *fmtstr, ...);
-int printlo(unsigned int line, unsigned int offset, const char *fmtstr, ...);
+int printk(const char* fmtstr, ...);
+int printd(const char* fmtstr, ...);
+int printlo(unsigned int line, unsigned int offset, const char* fmtstr, ...);
#define printl(line, fmt, args...) printlo(1, line, fmt, ##args)
#define printll(line, fmt, args...) printlo(0, line, fmt, ##args)
MPO_IDE = 1,
};
-int sprintf(char *str, const char *fmtstr, ...);
+int sprintf(char* str, const char* fmtstr, ...);
#define TRAP_GATE 0x0F // Keep 'IF' bit.
#define TSS_DESC 0x09
-static inline void _init_desc(pDesc desc) { memset((char *)desc, 0, sizeof(Desc)); }
+static inline void _init_desc(pDesc desc) {
+ memset((char*)desc, 0, sizeof(Desc));
+}
static inline Desc _create_seg(u8 type, u8 DPL) {
Desc d;
return d;
}
-static inline void set_idt_gate(u32 vec, u32 handler, u8 type, u8 DPL) { idt[vec] = _create_gate(handler, type, DPL); }
+static inline void set_idt_gate(u32 vec, u32 handler, u8 type, u8 DPL) {
+ idt[vec] = _create_gate(handler, type, DPL);
+}
#define set_sys_int(vect, type, DPL, handler) \
do { \
extern task_t root_task;
-extern void load_cr3(task_t *tsk);
+extern void load_cr3(task_t* tsk);
extern list_head_t all_tasks;
extern list_head_t delay_tasks;
list_head_t wait_list;
} semaphore_t;
-#define SEMAPHORE_INITIALIZER(name, n) \
- { .cnt = (n), .wait_list = LIST_HEAD_INIT((name).wait_list) }
+#define SEMAPHORE_INITIALIZER(name, n) {.cnt = (n), .wait_list = LIST_HEAD_INIT((name).wait_list)}
-void semaphore_init(semaphore_t *s, unsigned int v);
+void semaphore_init(semaphore_t* s, unsigned int v);
// down
// 如果s->cnt > 0不会立即重新调度进程
// 如果s->cnt == 0 会重新调度进程
-volatile void down(semaphore_t *s);
+volatile void down(semaphore_t* s);
// up
// 只会唤醒进程,但不会立即重新调度进程
-volatile void up(semaphore_t *s);
+volatile void up(semaphore_t* s);
typedef semaphore_t mutex_t;
-#define MUTEX_INITIALIZER(name) \
- { .cnt = (1), .wait_list = LIST_HEAD_INIT((name).wait_list) }
+#define MUTEX_INITIALIZER(name) {.cnt = (1), .wait_list = LIST_HEAD_INIT((name).wait_list)}
#define DECLARE_MUTEX(name) mutex_t name = MUTEX_INITIALIZER(name)
(ptr)->cnt = 1; \
INIT_LIST_HEAD(&((ptr)->wait_list)); \
} while (0)
-void mutex_init(mutex_t *);
-void mutex_lock(mutex_t *);
-void mutex_unlock(mutex_t *);
+void mutex_init(mutex_t*);
+void mutex_lock(mutex_t*);
+void mutex_unlock(mutex_t*);
#define _STDIO_H
#include <string.h>
#include <syscall.h>
-extern int write(int fd, const char *buf, unsigned long size);
-extern int vsprintf(char *buf, const char *fmt, char *args);
-static inline int printf(const char *fmt, ...) {
+extern int write(int fd, const char* buf, unsigned long size);
+extern int vsprintf(char* buf, const char* fmt, char* args);
+static inline int printf(const char* fmt, ...) {
char ptfbuf[512];
- char *args = (char *)(((char *)&fmt) + 4);
+ char* args = (char*)(((char*)&fmt) + 4);
vsprintf(ptfbuf, fmt, args);
return write(0, ptfbuf, strlen(ptfbuf));
}
#ifndef _STDLIB_H
#define _STDLIB_H
-extern int atoi(const char *s);
+extern int atoi(const char* s);
#endif //_STDLIB_H
#include "types.h"
-char *strcpy(char *dest, const char *src);
-char *strncpy(char *dst, const char *src, size_t len);
-size_t strlcpy(char *dst, const char *src, size_t size);
-size_t strlen(const char *str);
-int strcmp(const char *a, const char *b);
-int strncmp(const char *a, const char *b, size_t count);
-char *strcat(char *dest, const char *src);
-char *strstr(const char *a, const char *b);
+char* strcpy(char* dest, const char* src);
+char* strncpy(char* dst, const char* src, size_t len);
+size_t strlcpy(char* dst, const char* src, size_t size);
+size_t strlen(const char* str);
+int strcmp(const char* a, const char* b);
+int strncmp(const char* a, const char* b, size_t count);
+char* strcat(char* dest, const char* src);
+char* strstr(const char* a, const char* b);
-void *memcpy(void *dest, const void *src, size_t size);
-void memset(void *dest, char ch, size_t size);
-int memcmp(const void *a, const void *b, size_t count);
+void* memcpy(void* dest, const void* src, size_t size);
+void memset(void* dest, char ch, size_t size);
+int memcmp(const void* a, const void* b, size_t count);
#endif //_STRING_H
1; \
})
-void *kmalloc(size_t size, gfp_t gfpflags);
-void *kzalloc(size_t size, gfp_t gfpflags);
-void kfree(void *addr);
+void* kmalloc(size_t size, gfp_t gfpflags);
+void* kzalloc(size_t size, gfp_t gfpflags);
+void kfree(void* addr);
#define panic(msg, ...) \
do { \
// 之后要将这个地址映射到显存的物理地址
#define VRAM_VADDR_BASE (PAGE_OFFSET + MAX_SUPT_PHYMM_SIZE)
-
// 算出固定映射区的线性地址
#define FIXED_MAP_VADDR_BASE (VRAM_VADDR_BASE + VRAM_VADDR_SIZE)
u32 page_bitmap;
- u32 *page_dir;
- u32 *pte_start;
- u32 *pte_end;
+ u32* page_dir;
+ u32* pte_start;
+ u32* pte_end;
- void *kernel_begin;
- void *kernel_end;
- void *bootmem_bitmap_begin;
+ void* kernel_begin;
+ void* kernel_end;
+ void* bootmem_bitmap_begin;
// +-------+-------+-------+-------+
// | drive | part1 | part2 | part3 |
u16 x_resolution;
u16 y_resolution;
- void *rsdt_addr;
+ void* rsdt_addr;
dev_t root_dev;
#define CMD_LINE_SIZE 128
- const char *cmdline;
+ const char* cmdline;
u32 debug;
#define NR_TASK_OPEN_CNT 32
typedef struct task_files {
// 暂时先不用bitmap,直接线性搜索
- file_t *fds[NR_TASK_OPEN_CNT];
+ file_t* fds[NR_TASK_OPEN_CNT];
} task_files_t;
typedef union task_union {
pid_t ppid;
volatile unsigned int state;
- const char *reason;
+ const char* reason;
long exit_code;
uint32_t cr3;
path_t root;
path_t pwd;
- vm_area_t *vma_list;
+ vm_area_t* vma_list;
list_head_t list; // 所有进程串成一个链表
unsigned char stack[TASK_SIZE];
} task_t;
-task_t *alloc_task_t();
+task_t* alloc_task_t();
-static inline task_t *get_current() {
- task_t *tsk;
+static inline task_t* get_current() {
+ task_t* tsk;
asm("andl %%esp, %0;" : "=r"(tsk) : "0"(~(TASK_SIZE - 1)));
return tsk;
}
#define current get_current()
-static inline pid_t sysc_getpid() { return current->pid; }
+static inline pid_t sysc_getpid() {
+ return current->pid;
+}
-task_t *find_task(pid_t pid);
+task_t* find_task(pid_t pid);
#define ROOT_TSK_PID (0)
void init_ttys();
-void tty_write(tty_t *tty, const char *buf, size_t size);
-void tty_write_at(tty_t *tty, int xpos, int ypos, const char *buf, size_t size);
-void tty_color_putc(tty_t *tty, char c, unsigned int fg_color, unsigned bg_color);
+void tty_write(tty_t* tty, const char* buf, size_t size);
+void tty_write_at(tty_t* tty, int xpos, int ypos, const char* buf, size_t size);
+void tty_color_putc(tty_t* tty, char c, unsigned int fg_color, unsigned bg_color);
-void tty_set_cursor(tty_t *tty);
-void tty_switch(tty_t *tty);
+void tty_set_cursor(tty_t* tty);
+void tty_switch(tty_t* tty);
void tty_switch_to_next();
-void tty_clear(tty_t *tty);
+void tty_clear(tty_t* tty);
-extern tty_t *current_tty;
+extern tty_t* current_tty;
typedef unsigned long long uint64_t;
typedef long long int64_t;
-
typedef uint32_t uintptr_t;
typedef uint32_t paddr_t;
typedef uint32_t vaddr_t;
typedef unsigned long pid_t;
typedef unsigned long mode_t;
-#define NULL ((void *)0)
+#define NULL ((void*)0)
typedef enum { false, true } bool;
} wait_queue_head_t;
typedef struct {
- task_t *task;
+ task_t* task;
list_head_t entry;
} wait_queue_entry_t;
-#define WAIT_QUEUE_HEAD_INITIALIZER(name) \
- { .task_list = LIST_HEAD_INIT((name).task_list) }
+#define WAIT_QUEUE_HEAD_INITIALIZER(name) {.task_list = LIST_HEAD_INIT((name).task_list)}
#define DECLARE_WAIT_QUEUE_HEAD(name) wait_queue_head_t name = WAIT_QUEUE_HEAD_INITIALIZER(name)
-#define WAIT_QUEUE_ENTRY_INITIALIZER(name, tsk) \
- { .task = tsk, .entry = LIST_HEAD_INIT((name).entry) }
+#define WAIT_QUEUE_ENTRY_INITIALIZER(name, tsk) {.task = tsk, .entry = LIST_HEAD_INIT((name).entry)}
#define DECLARE_WAIT_QUEUE_ENTRY(name, tsk) wait_queue_entry_t name = WAIT_QUEUE_ENTRY_INITIALIZER(name, tsk)
-void init_wait_queue_head(wait_queue_head_t *wqh);
-void add_wait_queue(wait_queue_head_t *head, wait_queue_entry_t *wq);
-void del_wait_queue(wait_queue_head_t *head, wait_queue_entry_t *wq);
+void init_wait_queue_head(wait_queue_head_t* wqh);
+void add_wait_queue(wait_queue_head_t* head, wait_queue_entry_t* wq);
+void del_wait_queue(wait_queue_head_t* head, wait_queue_entry_t* wq);
// prepare_to_wait 不会调用schedule
-void prepare_to_wait(wait_queue_head_t *head, wait_queue_entry_t *wq, unsigned int state);
+void prepare_to_wait(wait_queue_head_t* head, wait_queue_entry_t* wq, unsigned int state);
-void __end_wait(wait_queue_entry_t *wq);
+void __end_wait(wait_queue_entry_t* wq);
// 使用这个函数的时候需要注意
// 设置condition为真的语句和wake_up原子地执行
// wake_up只唤醒不立即重新调度
-void wake_up(wait_queue_head_t *head);
+void wake_up(wait_queue_head_t* head);
// nr == 0 代表唤醒所有
-void __wake_up(wait_queue_head_t *head, int nr);
+void __wake_up(wait_queue_head_t* head, int nr);
// 以下wait_event被定义成宏,而不是函数是因为condition
// condition可能是一个表达式,如果定义成函数,往下传递就直接变成了一个值
#include <cpuid.h>
#include <system.h>
- void lapic_init() {
+void lapic_init() {
cpuid_regs_t r;
r = cpuid(1);
- if(r.edx & (1 << 9)) {
+ if (r.edx & (1 << 9)) {
printk("local apic supported\n");
- if(r.ecx & (1 << 21)) {
+ if (r.ecx & (1 << 21)) {
printk("x2apic supported\n");
} else {
panic("x2apic not supported\n");
uint64_t apic_base = read_msr(MSR_IA32_APIC_BASE);
printk("apic base: %016lx\n", apic_base);
-
// apic 必然已经开启
assert((apic_base & (1 << 11)) != 0);
uint64_t apic_version = read_msr(MSR_IA32_X2APIC_VERSION);
printk("apic version: %08lx\n", apic_version);
-
paddr_t apic_phys_base_addr = apic_base & 0xFFFFF000;
vaddr_t apic_virt_base_addr = apic_phys_base_addr;
- #if 0
+#if 0
unsigned long ddd = 0xFEC00000;
while(ddd < 0xFF000000) {
page_map((void*)ddd, (void*)ddd, PAGE_P);
ddd += 0x1000;
}
- #endif
+#endif
page_map((vaddr_t)apic_virt_base_addr, (paddr_t)apic_phys_base_addr, PAGE_P);
{
- volatile uint32_t *base = (volatile uint32_t *)apic_virt_base_addr;
- uint32_t id = base[0x20/4]; // APIC ID 偏移
- uint32_t version = base[0x30/4];
+ volatile uint32_t* base = (volatile uint32_t*)apic_virt_base_addr;
+ uint32_t id = base[0x20 / 4]; // APIC ID 偏移
+ uint32_t version = base[0x30 / 4];
printk("APIC id %08x version %08x\n", id, version);
}
-
}
-
void init_apic() {
#if 0
lapic_init();
#include <printk.h>
-void assert_fail(char *exp, char *file, unsigned int line, const char *func) {
+void assert_fail(char* exp, char* file, unsigned int line, const char* func) {
asm("cli");
printl(MPL_DEBUG, "%s:%d: %s: Assertion \'%s\' failed.\n", file, line, func, exp);
printk("%s:%d: %s: Assertion \'%s\' failed.\n", file, line, func, exp);
volatile uint64_t jiffies = 0; // TODO uint64: undefined reference to `__umoddi3'
-unsigned int sys_clock() { return jiffies; }
+unsigned int sys_clock() {
+ return jiffies;
+}
void debug_print_all_tasks();
void dump_irq_nr_stack();
-void clk_bh_handler(void *arg);
+void clk_bh_handler(void* arg);
extern volatile bool enable_clock_irq_delay;
-void clk_handler(unsigned int irq, pt_regs_t *regs, void *dev_id) {
+void clk_handler(unsigned int irq, pt_regs_t* regs, void* dev_id) {
// if (jiffies % 100 == 0) {
// printl(MPL_CLOCK, "clock irq: %d", jiffies);
printlxy(MPL_IRQ, MPO_CLOCK, "CLK irq: %d", jiffies);
// 开中断执行这个函数
// 后续放到一个内核任务中去做,需要先把禁止内核抢占做了
-const char *task_state(unsigned int state);
-void clk_bh_handler(void *arg) {
-
- task_t *p = 0;
- list_head_t *t = 0;
- list_head_t *pos = 0;
+const char* task_state(unsigned int state);
+void clk_bh_handler(void* arg) {
+ task_t* p = 0;
+ list_head_t* t = 0;
+ list_head_t* pos = 0;
list_for_each_safe(pos, t, &delay_tasks) {
p = list_entry(pos, task_t, pend);
// printk("%s state: %s\n", p->name, task_state(p->state));
// 8254的最低频率为18.2Hz(1193180/65536,最大计数值是65536是因为往计数器里写0就从65536开始计数)
assert(hz >= 19);
- const uint8_t counter_no = 0; // 第0个计数器
+ const uint8_t counter_no = 0; // 第0个计数器
const uint8_t read_write_latch = 3; // 0 锁存数据供CPU读;1只读写低字节;2只读写高字节;3先读写低字节,后读写高字节
- const uint8_t mode = 2; //
- const uint8_t BCD = 0; // 0 二进制;1 BCD码
+ const uint8_t mode = 2; //
+ const uint8_t BCD = 0; // 0 二进制;1 BCD码
const uint8_t cmd =
((counter_no & 0x03) << 6) | ((read_write_latch & 0x03) << 4) | ((mode & 0x07) << 1) | ((BCD & 0x01) << 0);
#include <completion.h>
#include <sched.h>
-void wait_completion(completion_t *x) {
+void wait_completion(completion_t* x) {
wait_event(&x->wait, (x->done != 0));
x->done--;
}
-void complete(completion_t *x) {
+void complete(completion_t* x) {
uint32_t iflags;
irq_save(iflags);
x->done++;
irq_restore(iflags);
}
-void init_completion(completion_t *x) {
+void init_completion(completion_t* x) {
x->done = 0;
init_wait_queue_head(&x->wait);
#include <string.h>
#include <cpuid.h>
-#define TEST_FEATURE(val, bit, fea) \
- do { \
- if (ISSET_BIT(val, bit)) printk(" %s", fea); \
+#define TEST_FEATURE(val, bit, fea) \
+ do { \
+ if (ISSET_BIT(val, bit)) \
+ printk(" %s", fea); \
} while (0);
cpuid_regs_t cpuid(unsigned long op) {
r = cpuid(1);
pn = ((r.ebx & 0x00FF0000) >> 16);
printk(" x %d Cores\n", pn);
- if(((r.ecx >> 21) & 0x01) == 1) {
+ if (((r.ecx >> 21) & 0x01) == 1) {
printk("x2APIC\n");
}
printk("ECX %x\n", r.ecx);
#include <syscall.h>
#include <types.h>
-extern void *syscall_exit;
+extern void* syscall_exit;
void put_paging(unsigned long vaddr, unsigned long paddr, unsigned long flags) {
assert(PAGE_ALIGN(vaddr) == vaddr);
unsigned int npde = get_npde(vaddr);
unsigned int npte = get_npte(vaddr);
- pde_t *page_dir = (pde_t *)pa2va(current->cr3);
- pte_t *page_table = (pte_t *)PAGE_ALIGN(page_dir[npde]);
+ pde_t* page_dir = (pde_t*)pa2va(current->cr3);
+ pte_t* page_table = (pte_t*)PAGE_ALIGN(page_dir[npde]);
if (page_table == 0) {
- page_table = (pte_t *)page2va(alloc_one_page(0));
+ page_table = (pte_t*)page2va(alloc_one_page(0));
memset(page_table, 0, PAGE_SIZE);
- page_table = (pte_t *)va2pa(page_table);
+ page_table = (pte_t*)va2pa(page_table);
assert(page_table != 0);
}
page_table[npte] = paddr | flags;
}
-int sysc_exec(const char *path, char *const argv[]) {
+int sysc_exec(const char* path, char* const argv[]) {
assert(argv == NULL); // unsupport now
unsigned int ino = namei(path);
- if (ino == 0) return -ENOENT;
+ if (ino == 0)
+ return -ENOENT;
ext2_inode_t inode;
ext2_read_inode(ino, &inode);
- Elf32_Ehdr *ehdr = (Elf32_Ehdr *)(page2va(alloc_one_page(0)));
+ Elf32_Ehdr* ehdr = (Elf32_Ehdr*)(page2va(alloc_one_page(0)));
assert(ehdr != 0);
- ext2_read_data(&inode, 0, PAGE_SIZE, (char *)ehdr);
- printk("%08x\n", *((unsigned long *)ehdr->e_ident));
+ ext2_read_data(&inode, 0, PAGE_SIZE, (char*)ehdr);
+ printk("%08x\n", *((unsigned long*)ehdr->e_ident));
assert(strncmp(ELFMAG, ehdr->e_ident, sizeof(ELFMAG) - 1) == 0);
printk("Elf Entry: %08x\n", ehdr->e_entry);
int i, j;
for (i = 0; i < ehdr->e_phnum; ++i) {
- Elf32_Phdr *phdr;
- phdr = (Elf32_Phdr *)(((unsigned long)ehdr) + ehdr->e_phoff + (i * ehdr->e_phentsize));
+ Elf32_Phdr* phdr;
+ phdr = (Elf32_Phdr*)(((unsigned long)ehdr) + ehdr->e_phoff + (i * ehdr->e_phentsize));
printk("Type %08x Off %08x Va %08x Pa %08x Fsz %08x Mmsz %08x\n", phdr->p_type, phdr->p_offset, phdr->p_vaddr,
phdr->p_paddr, phdr->p_filesz, phdr->p_memsz);
unsigned long mmsz = phdr->p_memsz;
unsigned long filesz = phdr->p_filesz;
- if (phdr->p_type != PT_LOAD) continue;
+ if (phdr->p_type != PT_LOAD)
+ continue;
assert(mmsz >= filesz);
unsigned int pgcnt = (mmsz + PAGE_SIZE - 1) / PAGE_SIZE;
unsigned int blkcnt = (filesz + EXT2_BLOCK_SIZE - 1) / EXT2_BLOCK_SIZE;
- void *buf = kmalloc(pgcnt * PAGE_SIZE, PAGE_SIZE);
+ void* buf = kmalloc(pgcnt * PAGE_SIZE, PAGE_SIZE);
assert(PAGE_ALIGN(buf) == (unsigned long)buf);
assert(buf != 0);
printk("vvvbufsz %08x datasz %08x\n", pgcnt * PAGE_SIZE, blkcnt * EXT2_BLOCK_SIZE);
- if (filesz > 0) ext2_read_data(&inode, offset, blkcnt * EXT2_BLOCK_SIZE, buf);
+ if (filesz > 0)
+ ext2_read_data(&inode, offset, blkcnt * EXT2_BLOCK_SIZE, buf);
for (j = 0; j < pgcnt; ++j) {
put_paging(vaddr + j * PAGE_SIZE, (unsigned long)(va2pa(buf)) + j * PAGE_SIZE, 7);
disable_irq();
- pt_regs_t *regs = ((pt_regs_t *)(TASK_SIZE + (unsigned long)current)) - 1;
+ pt_regs_t* regs = ((pt_regs_t*)(TASK_SIZE + (unsigned long)current)) - 1;
#if 1
- memset((void *)regs, 0, sizeof(pt_regs_t));
+ memset((void*)regs, 0, sizeof(pt_regs_t));
regs->ss = SELECTOR_USER_DS;
regs->ds = SELECTOR_USER_DS;
regs->es = SELECTOR_USER_DS;
irq_save(flags);
current->state = TASK_EXITING;
- task_t *t = current;
+ task_t* t = current;
irq_restore(flags);
extern pid_t get_next_pid();
extern list_head_t all_tasks;
-int do_fork(pt_regs_t *regs, unsigned long flags) {
- task_t *tsk;
+int do_fork(pt_regs_t* regs, unsigned long flags) {
+ task_t* tsk;
tsk = alloc_task_t();
printd("fork task %08x flags %08x\n", tsk, flags);
assert(tsk->cr3 != 0);
unsigned int i, j;
- pde_t *pde_src = (pde_t *)pa2va(current->cr3);
- pde_t *pde_dst = (pde_t *)pa2va(tsk->cr3);
+ pde_t* pde_src = (pde_t*)pa2va(current->cr3);
+ pde_t* pde_dst = (pde_t*)pa2va(tsk->cr3);
- memcpy((void *)pa2va(tsk->cr3), (void *)pa2va(current->cr3), PAGE_SIZE);
+ memcpy((void*)pa2va(tsk->cr3), (void*)pa2va(current->cr3), PAGE_SIZE);
for (i = 0; i < PAGE_PDE_CNT; ++i) {
unsigned long spde = (unsigned long)pde_src[i];
if (PAGE_ALIGN(spde) != 0) {
dpde = page2va(alloc_one_page(0));
assert(dpde != 0);
- memset((void *)dpde, 0, PAGE_SIZE);
+ memset((void*)dpde, 0, PAGE_SIZE);
dpde = PAGE_FLAGS(spde) | (unsigned long)va2pa(dpde);
} else {
pde_dst[i] = 0;
}
pde_dst[i] = dpde;
- pte_t *pte_src = pa2va(PAGE_ALIGN(spde));
- pte_t *pte_dst = pa2va(PAGE_ALIGN(dpde));
+ pte_t* pte_src = pa2va(PAGE_ALIGN(spde));
+ pte_t* pte_dst = pa2va(PAGE_ALIGN(dpde));
for (j = 0; j < PAGE_PTE_CNT; ++j) {
pte_src[j] &= ~PAGE_WR;
pte_dst[j] = pte_src[j];
continue;
}
printk("----pde[%u] pte_src[%u] %08x\n", i, j, pte_src[j]);
- page_t *page = pa2page(pte_src[j]);
+ page_t* page = pa2page(pte_src[j]);
page->count++;
}
#endif
}
- pt_regs_t *child_regs = ((pt_regs_t *)(TASK_SIZE + (unsigned long)tsk)) - 1;
+ pt_regs_t* child_regs = ((pt_regs_t*)(TASK_SIZE + (unsigned long)tsk)) - 1;
// printd("child regs: %x %x\n", child_regs, regs);
memcpy(child_regs, regs, sizeof(*regs));
// child_regs->eflags |= 0x200;
if (flags & FORK_KRNL) {
- strcpy(tsk->name, (char *)(child_regs->eax));
+ strcpy(tsk->name, (char*)(child_regs->eax));
child_regs->eax = 0;
} else {
- child_regs->eip = *((unsigned long *) && fork_child);
+ child_regs->eip = *((unsigned long*) && fork_child);
}
printk("%s fork %s EFLAGS %08x\n", current->name, tsk->name, regs->eflags);
return 0;
}
-int sysc_fork(pt_regs_t regs) { return do_fork(®s, 0); }
+int sysc_fork(pt_regs_t regs) {
+ return do_fork(®s, 0);
+}
.ack = ack_i8259_irq,
};
-void do_i8259_IRQ(pt_regs_t *regs, unsigned int irq) {}
+void do_i8259_IRQ(pt_regs_t* regs, unsigned int irq) {
+}
-__attribute__((regparm(1))) void boot_irq_handler(pt_regs_t *regs) {
+__attribute__((regparm(1))) void boot_irq_handler(pt_regs_t* regs) {
unsigned int irq = regs->irq;
if (irq != 0 && irq != 1) {
panic("invalid irq %d\n", irq);
do { \
printk("Unsupport Now...[%s]\n", __FUNCTION__); \
printk("EFLAGS:%08x CS:%02x EIP:%08x ERRCODE:%x", regs.eflags, regs.cs, regs.eip, regs.errcode); \
- while (1); \
+ while (1) \
+ ; \
} while (0);
-void doDivideError(pt_regs_t regs) { DIE_MSG(); }
-void doDebug(pt_regs_t regs) { DIE_MSG(); }
-void doNMI(pt_regs_t regs) { DIE_MSG(); }
-void doBreakPoint(pt_regs_t regs) { DIE_MSG(); }
-void doOverFlow(pt_regs_t regs) { DIE_MSG(); }
-void doBoundsCheck(pt_regs_t regs) { DIE_MSG(); }
-void doInvalidOpcode(pt_regs_t regs) { DIE_MSG(); }
-void doDeviceNotAvailable(pt_regs_t regs) { DIE_MSG(); }
-void doDoubleFault(pt_regs_t regs) { DIE_MSG(); }
-void doCoprocSegOverRun(pt_regs_t regs) { DIE_MSG(); }
-void doInvalidTss(pt_regs_t regs) { DIE_MSG(); }
-void doSegNotPresent(pt_regs_t regs) { DIE_MSG(); }
-void doStackFault(pt_regs_t regs) { DIE_MSG(); }
-void doGeneralProtection(pt_regs_t regs) { DIE_MSG(); }
+void doDivideError(pt_regs_t regs) {
+ DIE_MSG();
+}
+void doDebug(pt_regs_t regs) {
+ DIE_MSG();
+}
+void doNMI(pt_regs_t regs) {
+ DIE_MSG();
+}
+void doBreakPoint(pt_regs_t regs) {
+ DIE_MSG();
+}
+void doOverFlow(pt_regs_t regs) {
+ DIE_MSG();
+}
+void doBoundsCheck(pt_regs_t regs) {
+ DIE_MSG();
+}
+void doInvalidOpcode(pt_regs_t regs) {
+ DIE_MSG();
+}
+void doDeviceNotAvailable(pt_regs_t regs) {
+ DIE_MSG();
+}
+void doDoubleFault(pt_regs_t regs) {
+ DIE_MSG();
+}
+void doCoprocSegOverRun(pt_regs_t regs) {
+ DIE_MSG();
+}
+void doInvalidTss(pt_regs_t regs) {
+ DIE_MSG();
+}
+void doSegNotPresent(pt_regs_t regs) {
+ DIE_MSG();
+}
+void doStackFault(pt_regs_t regs) {
+ DIE_MSG();
+}
+void doGeneralProtection(pt_regs_t regs) {
+ DIE_MSG();
+}
-void do_no_page(void *);
-void do_wp_page(void *);
+void do_no_page(void*);
+void do_wp_page(void*);
void do_page_fault(pt_regs_t regs) {
#if 0
US RW P - Description
bit 2: 0 supervisor mode; 1 user mode
#endif
// DIE_MSG();
- void *addr;
+ void* addr;
u32 errcode = regs.errcode;
asm("movl %%cr2,%%eax" : "=a"(addr));
}
}
-void doCoprocError(pt_regs_t regs) { DIE_MSG(); }
+void doCoprocError(pt_regs_t regs) {
+ DIE_MSG();
+}
#include <task.h>
irq_desc_t irq_desc[NR_IRQS];
-irq_bh_action_t *irq_bh_actions = NULL;
-irq_bh_action_t *irq_bh_actions_end = NULL;
+irq_bh_action_t* irq_bh_actions = NULL;
+irq_bh_action_t* irq_bh_actions_end = NULL;
void irq_bh_handler();
void schedule();
volatile uint32_t clk_irq_cnt = 0;
-__attribute__((regparm(1))) void irq_handler(pt_regs_t *regs) {
+__attribute__((regparm(1))) void irq_handler(pt_regs_t* regs) {
assert(current->magic == TASK_MAGIC);
unsigned int irq = regs->irq;
if (irq >= NR_IRQS) {
panic("invalid irq %d\n", irq);
}
- irq_desc_t *p = irq_desc + irq;
- irq_action_t *action = p->action;
+ irq_desc_t* p = irq_desc + irq;
+ irq_action_t* action = p->action;
// 在qemu启动后如果gdb有加断点,就很会一直触发中断重入
reenter++;
#endif
{
while (true) {
- irq_bh_action_t *action = NULL;
+ irq_bh_action_t* action = NULL;
#if 1
disable_irq();
while (action != NULL) {
action->handler(action->arg);
- irq_bh_action_t *p = action;
+ irq_bh_action_t* p = action;
action = action->next;
kfree(p);
}
// 而是会延迟到这次中断返回后下一次的中断的下半部分处理逻辑
}
-int request_irq(unsigned int irq, void (*handler)(unsigned int, pt_regs_t *, void *), const char *devname,
- void *dev_id) {
- irq_action_t *p;
+int request_irq(unsigned int irq, void (*handler)(unsigned int, pt_regs_t*, void*), const char* devname, void* dev_id) {
+ irq_action_t* p;
if (irq >= NR_IRQS) {
return -EINVAL;
p = p->next;
}
- p = (irq_action_t *)kmalloc(sizeof(irq_action_t), 0);
+ p = (irq_action_t*)kmalloc(sizeof(irq_action_t), 0);
if (p == NULL) {
return -ENOMEM;
}
return 0;
}
-void add_irq_bh_handler(void (*handler)(), void *arg) {
+void add_irq_bh_handler(void (*handler)(), void* arg) {
// 只能在中断处理函数中调用
assert(irq_disabled());
assert(reenter >= 0);
// 本函数不用考虑临界问题
- irq_bh_action_t *p;
- p = (irq_bh_action_t *)kmalloc(sizeof(irq_bh_action_t), 0);
+ irq_bh_action_t* p;
+ p = (irq_bh_action_t*)kmalloc(sizeof(irq_bh_action_t), 0);
assert(p != NULL);
p->handler = handler;
p->next = NULL;
}
-int open_irq(unsigned int irq) { return irq_desc[irq].chip->enable(irq); }
+int open_irq(unsigned int irq) {
+ return irq_desc[irq].chip->enable(irq);
+}
-int close_irq(unsigned int irq) { return irq_desc[irq].chip->disable(irq); }
+int close_irq(unsigned int irq) {
+ return irq_desc[irq].chip->disable(irq);
+}
bool irq_enabled() {
uint32_t flags;
return false;
}
-bool irq_disabled() { return !irq_enabled(); }
+bool irq_disabled() {
+ return !irq_enabled();
+}
-int enable_no_irq_chip(unsigned int irq) { return 0; }
-int disable_no_irq_chip(unsigned int irq) { return 0; }
+int enable_no_irq_chip(unsigned int irq) {
+ return 0;
+}
+int disable_no_irq_chip(unsigned int irq) {
+ return 0;
+}
irq_chip_t no_irq_chip = {.name = "none", .enable = enable_no_irq_chip, .disable = disable_no_irq_chip};
irq_desc_t no_irq_desc = {.chip = &no_irq_chip, .action = NULL, .status = 0, .depth = 0};
// __critical_zone_eflags的值会被统一设置为最里层时的eflags
// 意味着如果IF置位了的话,必定会丢失这个信息
static volatile uint32_t __critical_zone_eflags;
-void enter_critical_zone() { irq_save(__critical_zone_eflags); }
-void exit_critical_zone() { irq_restore(__critical_zone_eflags); }
+void enter_critical_zone() {
+ irq_save(__critical_zone_eflags);
+}
+void exit_critical_zone() {
+ irq_restore(__critical_zone_eflags);
+}
#include <irq.h>
#include <system.h>
#include <tty.h>
-int vsprintf(char *buf, const char *fmt, char *args);
+int vsprintf(char* buf, const char* fmt, char* args);
-void serial_write(const char *buf, size_t size);
+void serial_write(const char* buf, size_t size);
-
-extern tty_t *const default_tty;
-int printk(const char *fmtstr, ...) {
+extern tty_t* const default_tty;
+int printk(const char* fmtstr, ...) {
static char pkbuf[1024];
ENTER_CRITICAL_ZONE(EFLAGS);
- char *args = (char *)(((char *)&fmtstr) + 4);
+ char* args = (char*)(((char*)&fmtstr) + 4);
int size = vsprintf(pkbuf, fmtstr, args);
tty_write(default_tty, pkbuf, (size_t)size);
serial_write(pkbuf, (size_t)size);
return 0;
}
-extern tty_t *const debug_tty;
-int printd(const char *fmtstr, ...) {
+extern tty_t* const debug_tty;
+int printd(const char* fmtstr, ...) {
static char pdbuf[1024];
ENTER_CRITICAL_ZONE(EFLAGS);
- char *args = (char *)(((char *)&fmtstr) + 4);
+ char* args = (char*)(((char*)&fmtstr) + 4);
int size = vsprintf(pdbuf, fmtstr, args);
tty_write(debug_tty, pdbuf, (size_t)size);
serial_write(pdbuf, (size_t)size);
return 0;
}
-
-extern tty_t *const monitor_tty;
-int printlo(unsigned int xpos, unsigned int ypos, const char *fmtstr, ...) {
+extern tty_t* const monitor_tty;
+int printlo(unsigned int xpos, unsigned int ypos, const char* fmtstr, ...) {
static char plobuf[1024];
- char *args = (char *)(((char *)&fmtstr) + 4);
+ char* args = (char*)(((char*)&fmtstr) + 4);
ENTER_CRITICAL_ZONE(EFLAGS);
int size = vsprintf(plobuf, fmtstr, args);
return pid;
}
-void load_cr3(task_t *tsk) { set_cr3(tsk->cr3); }
+void load_cr3(task_t* tsk) {
+ set_cr3(tsk->cr3);
+}
extern pde_t __initdata init_pgd[PDECNT_PER_PAGE] __attribute__((__aligned__(PAGE_SIZE)));
printk("init_root_task tss.esp0 %08x\n", tss.esp0);
}
-kmem_cache_t *task_t_cache;
+kmem_cache_t* task_t_cache;
void setup_tasks() {
INIT_LIST_HEAD(&all_tasks);
}
}
-task_t *alloc_task_t() {
- task_t *task;
- task = (task_t *)kmem_cache_alloc(task_t_cache, 0);
+task_t* alloc_task_t() {
+ task_t* task;
+ task = (task_t*)kmem_cache_alloc(task_t_cache, 0);
return task;
}
#endif
}
-void context_switch(task_t *prev, task_t *next) {
+void context_switch(task_t* prev, task_t* next) {
unsigned long eax, ebx, ecx, edx, esi, edi;
asm volatile(
"pushfl;"
: "memory");
}
-task_t *find_task(pid_t pid) {
- task_t *p = 0;
+task_t* find_task(pid_t pid) {
+ task_t* p = 0;
list_head_t *pos = 0, *tmp = 0;
unsigned long iflags;
return p;
}
-const char *task_state(unsigned int state) {
+const char* task_state(unsigned int state) {
static const char s[][8] = {
" ERROR", "\x10\x07RUN\x07", " READY", " WAIT ", " INIT ", " EXIT ",
};
}
void debug_print_all_tasks() {
- task_t *p = 0;
+ task_t* p = 0;
list_head_t *pos = 0, *t = 0;
- printl(MPL_TASK_TITLE, " NAME STATE TK/PI REASON TICKS SCHED KEEP TURN");
+ printl(MPL_TASK_TITLE, " NAME STATE TK/PI REASON SCHED KEEP TURN");
list_for_each_safe(pos, t, &all_tasks) {
p = list_entry(pos, task_t, list);
printl(MPL_TASK_0 + p->pid, "%08x %-6s:%u %s %02u/%02u %-10s %-9u %-9u %-9u", p, p->name, p->pid,
}
void schedule() {
- task_t *root = &root_task;
- task_t *sel = 0;
- task_t *p = 0;
+ task_t* root = &root_task;
+ task_t* sel = 0;
+ task_t* p = 0;
list_head_t *pos = 0, *t = 0;
assert(current->ticks >= 0);
#endif
}
- task_t *prev = current;
- task_t *next = sel != 0 ? sel : root;
+ task_t* prev = current;
+ task_t* next = sel != 0 ? sel : root;
prev->need_resched = 0;
}
void debug_sched() {
- task_t *p = list_entry(current->list.next, task_t, list);
+ task_t* p = list_entry(current->list.next, task_t, list);
p->state = (p->state == TASK_READY) ? TASK_WAIT : TASK_READY;
}
typedef struct semaphore_waiter {
list_head_t list;
- task_t *task;
+ task_t* task;
// 在Linux内核中这个结构体有一个up字段,这个字段的作用是防止进程被错误地唤醒
// 例如
} semaphore_waiter_t;
-void semaphore_init(semaphore_t *s, unsigned int v) {
+void semaphore_init(semaphore_t* s, unsigned int v) {
s->cnt = v;
INIT_LIST_HEAD(&(s->wait_list));
}
-volatile void down(semaphore_t *s) {
+volatile void down(semaphore_t* s) {
unsigned long iflags;
irq_save(iflags);
s->cnt--;
irq_restore(iflags);
} else {
- task_t *task = current;
+ task_t* task = current;
semaphore_waiter_t waiter;
waiter.task = task;
INIT_LIST_HEAD(&waiter.list);
}
}
-volatile void up(semaphore_t *s) {
+volatile void up(semaphore_t* s) {
unsigned long iflags;
irq_save(iflags);
s->cnt++;
irq_restore(iflags);
} else {
- semaphore_waiter_t *waiter = list_first_entry(&s->wait_list, semaphore_waiter_t, list);
+ semaphore_waiter_t* waiter = list_first_entry(&s->wait_list, semaphore_waiter_t, list);
assert(waiter != 0);
list_del(&waiter->list);
- task_t *task = waiter->task;
+ task_t* task = waiter->task;
task->state = TASK_READY;
task->reason = "up";
}
}
-void mutex_init(mutex_t *s) { INIT_MUTEX(s); }
-void mutex_lock(semaphore_t *s) { down(s); }
-void mutex_unlock(semaphore_t *s) { up(s); }
+void mutex_init(mutex_t* s) {
+ INIT_MUTEX(s);
+}
+void mutex_lock(semaphore_t* s) {
+ down(s);
+}
+void mutex_unlock(semaphore_t* s) {
+ up(s);
+}
extern void cnsl_init();
#define VERSION "0.3.1"
-const char *version = "KERNEL v" VERSION " @" BUILDER
- " ["__DATE__
- " " __TIME__
+const char* version = "KERNEL v" VERSION " @" BUILDER " [" __DATE__ " " __TIME__
"]"
"\n\n";
void print_kernel_version() {
//
- extern tty_t *const default_tty;
- tty_t *const tty = default_tty;
+ extern tty_t* const default_tty;
+ tty_t* const tty = default_tty;
int len = strlen(version);
bg_color = TTY_CYAN;
//
- char *dst = (char *)tty->base_addr;
+ char* dst = (char*)tty->base_addr;
//
dst[i * 2 + 0] = c;
printk(version);
}
-void parse_rsdt(void *addr);
+void parse_rsdt(void* addr);
void setup_kernel() {
printk("sysenter esp mode: %s\n",
init_buffer();
- #if 0
+#if 0
parse_rsdt(system.rsdt_addr);
void init_apic();
init_apic();
- #endif
+#endif
void init_mount();
init_mount();
cnsl_init();
boot_delay(DEFAULT_BOOT_DELAY_TICKS);
- const char *title = "KERNEL MONITOR";
+ const char* title = "KERNEL MONITOR";
printlxy(MPL_TITLE, (80 - strlen(title)) / 2, title);
setup_fs();
print_kernel_version();
boot_delay(DEFAULT_BOOT_DELAY_TICKS);
- extern tty_t *const monitor_tty;
+ extern tty_t* const monitor_tty;
// tty_switch(monitor_tty);
boot_delay(DEFAULT_BOOT_DELAY_TICKS);
return 0;
}
-int sysc_test() {}
-int sysc_pause() {}
+int sysc_test() {
+}
+int sysc_pause() {
+}
int sysc_debug(unsigned int v) {
static unsigned int cnt = 0;
void init_sysc_handler_table() {
int i;
- for (i = 0; i < SYSC_NUM; i++) sysc_handler_table[i] = (unsigned long)sysc_none;
+ for (i = 0; i < SYSC_NUM; i++)
+ sysc_handler_table[i] = (unsigned long)sysc_none;
#define _sysc_(nr, sym) \
do { \
asm volatile("sgdt gdtr");
// 复制旧的GDT
- memcpy(gdt, (void *)pa2va(*((uint32_t *)(gdtr + 2))), *((uint16_t *)(gdtr + 0)));
- *((unsigned short *)gdtr) = NGDT * sizeof(Desc);
- *((unsigned long *)(gdtr + 2)) = (unsigned long)gdt;
+ memcpy(gdt, (void*)pa2va(*((uint32_t*)(gdtr + 2))), *((uint16_t*)(gdtr + 0)));
+ *((unsigned short*)gdtr) = NGDT * sizeof(Desc);
+ *((unsigned long*)(gdtr + 2)) = (unsigned long)gdt;
asm volatile("lgdt gdtr");
// 通过中断门进入中断服务程序CPU会自动将中断关闭,也就是将EFLAGS的IF位清0
// 通过陷阱门进入服务程序时则维持IF标志位不变
void setup_idt() {
- *((unsigned short *)idtr) = NIDT * sizeof(Gate);
- *((unsigned long *)(idtr + 2)) = (unsigned long)idt;
+ *((unsigned short*)idtr) = NIDT * sizeof(Gate);
+ *((unsigned long*)(idtr + 2)) = (unsigned long)idt;
asm volatile("lidt idtr");
}
void ide_irq();
-void default_irq_handler(unsigned int irq, pt_regs_t *regs, void *dev_id) { printk("default irq handler %d \n", irq); }
+void default_irq_handler(unsigned int irq, pt_regs_t* regs, void* dev_id) {
+ printk("default irq handler %d \n", irq);
+}
void init_i8259();
}
}
- void kbd_handler(unsigned int irq, pt_regs_t *regs, void *dev_id);
- void clk_handler(unsigned int irq, pt_regs_t *regs, void *dev_id);
+ void kbd_handler(unsigned int irq, pt_regs_t* regs, void* dev_id);
+ void clk_handler(unsigned int irq, pt_regs_t* regs, void* dev_id);
void clk_bh_handler();
request_irq(0x00, clk_handler, "Intel 8254", "Clock Chip");
}
void set_tss() {
- TSS_t *p = &tss;
- memset((void *)p, sizeof(TSS_t), 0);
+ TSS_t* p = &tss;
+ memset((void*)p, sizeof(TSS_t), 0);
p->esp0 = 0; // delay to init root_task
p->ss0 = SELECTOR_KRNL_DS;
p->ss = SELECTOR_KRNL_DS;
#include <sched.h>
void ata_read_identify(int drv, int disable_intr);
-void ata_pio_read_data(int drvid, int sect_cnt, void *dst);
-void ata_dma_read_ext(int drv, uint64_t pos, uint16_t count, void *dest);
+void ata_pio_read_data(int drvid, int sect_cnt, void* dst);
+void ata_dma_read_ext(int drv, uint64_t pos, uint16_t count, void* dest);
-int send_disk_request(disk_request_t *r) {
+int send_disk_request(disk_request_t* r) {
if (NULL == r) {
panic("null disk request");
}
- ide_drive_t *drv = ide_get_drive(r->dev);
+ ide_drive_t* drv = ide_get_drive(r->dev);
assert(drv->present == 1);
return r->ret;
}
-void disk_task_entry(void *arg) {
+void disk_task_entry(void* arg) {
int r_cnt = 0;
while (1) {
int channel = (int)arg;
- ide_pci_controller_t *ide_ctrl = ide_pci_controller + channel;
+ ide_pci_controller_t* ide_ctrl = ide_pci_controller + channel;
#if 1
// 为了在DEBUG时看到RUN
// printk("hard disk channel %d\n", channel);
mutex_lock(&ide_ctrl->request_mutex);
- disk_request_t *r;
+ disk_request_t* r;
r = list_first_entry(&ide_ctrl->request_queue.list, disk_request_t, list);
if (NULL == r) {
panic("no disk request");
atomic_inc(&ide_ctrl->consumed_cnt);
mutex_unlock(&ide_ctrl->request_mutex);
- ide_drive_t *drv = ide_get_drive(r->dev);
+ ide_drive_t* drv = ide_get_drive(r->dev);
int drvid = drv->drvid;
if (drv->present == 0) {
panic("disk not present");
assert(r->buf != NULL || r->bb->data != NULL);
// printk("DISK READ drvid %u pos %u count %u bb %x\n", drvid, (uint32_t)pos, r->count, r->bb);
if (pio_mode) {
- int ata_pio_read_ext(int drvid, uint64_t pos, uint16_t count, int timeout, void *dest);
+ int ata_pio_read_ext(int drvid, uint64_t pos, uint16_t count, int timeout, void* dest);
if (r->bb != 0) {
ata_pio_read_ext(drvid, pos, r->count, 100, r->bb->data);
} else {
#include <system.h>
#include <types.h>
int sysc_wait(int ticks);
-void kernel_task(char *name, void *entry, void *arg);
+void kernel_task(char* name, void* entry, void* arg);
// 测试用的代码
// 这里存的是下标对应的每个扇区的最后2个字节
return debug_sect_nr;
}
-void verify_hd_data(uint64_t sect_nr, uint16_t *buf, const char *name) {
+void verify_hd_data(uint64_t sect_nr, uint16_t* buf, const char* name) {
uint16_t vfp = hd_sect_data_fingerprint[sect_nr];
uint16_t fp = buf[255];
#endif
#if 1
- extern __attribute__((regparm(0))) long sysc_mkdir(const char *path, int mode);
+ extern __attribute__((regparm(0))) long sysc_mkdir(const char* path, int mode);
sysc_mkdir("/root", 0777);
sysc_mkdir("/root/sbin/", 0777);
{
namei_t ni;
- const char *path = "/root/sbin/init.elf";
+ const char* path = "/root/sbin/init.elf";
// path_init(path, PATH_LOOKUP_PARENT, &ni);
// path_walk(path, &ni);
init_rootfs();
#if 1
- kernel_task("ide/0", disk_task_entry, (void *)0);
+ kernel_task("ide/0", disk_task_entry, (void*)0);
void ide_read_partions();
ide_read_partions();
#endif
#if 1
- kernel_task("ide/1", disk_task_entry, (void *)1);
+ kernel_task("ide/1", disk_task_entry, (void*)1);
kernel_task("user", user_task_entry, NULL);
kernel_task("tskA", taskA_entry, NULL);
kernel_task("tskB", taskB_entry, NULL);
void init_rootfs() {
#if 1
- void *mod_start = pa2va(boot_params.boot_module_begin);
+ void* mod_start = pa2va(boot_params.boot_module_begin);
- const uint32_t mod_magic = *(uint32_t *)(mod_start + 0);
- const uint32_t mod_head_size = *(uint32_t *)(mod_start + 4);
- const uint32_t mod_timestamp = *(uint32_t *)(mod_start + 8);
- const uint32_t mod_file_entry_cnt = *(uint32_t *)(mod_start + 12);
- const char *mod_name = (const char *)mod_start + 16;
+ const uint32_t mod_magic = *(uint32_t*)(mod_start + 0);
+ const uint32_t mod_head_size = *(uint32_t*)(mod_start + 4);
+ const uint32_t mod_timestamp = *(uint32_t*)(mod_start + 8);
+ const uint32_t mod_file_entry_cnt = *(uint32_t*)(mod_start + 12);
+ const char* mod_name = (const char*)mod_start + 16;
printk("%x %x\n", boot_params.boot_module_begin, boot_params.boot_module_end);
printk("module magic %08x header size %u timestamp %u file entry cnt %u name %s \n", mod_magic, mod_head_size,
int file_entry_offset = mod_head_size;
for (int i = 0; i < mod_file_entry_cnt; i++) {
- void *fe = mod_start + file_entry_offset;
+ void* fe = mod_start + file_entry_offset;
- const uint32_t fe_size = *(uint32_t *)(fe + 0);
- const uint32_t fe_type = *(uint32_t *)(fe + 4);
- const uint32_t fe_filesz = *(uint32_t *)(fe + 8);
- const uint32_t fe_offset = *(uint32_t *)(fe + 12);
- const char *fe_name = (const char *)(fe + 16);
+ const uint32_t fe_size = *(uint32_t*)(fe + 0);
+ const uint32_t fe_type = *(uint32_t*)(fe + 4);
+ const uint32_t fe_filesz = *(uint32_t*)(fe + 8);
+ const uint32_t fe_offset = *(uint32_t*)(fe + 12);
+ const char* fe_name = (const char*)(fe + 16);
file_entry_offset += fe_size;
- void *fc = mod_start + fe_offset;
+ void* fc = mod_start + fe_offset;
printk(">[fe:%u:%u] file size %u type %u name %s\n", i, fe_size, fe_filesz, fe_type, fe_name);
for (int k = 0; k < 16; k++) {
- uint8_t c = *(uint8_t *)(fc + k);
+ uint8_t c = *(uint8_t*)(fc + k);
printk("%02X ", c);
}
printk("\n");
// TODO支持带多层目录的fe_name
namei_t ni;
- const char *path = fe_name;
+ const char* path = fe_name;
const int flags = O_CREAT | O_APPEND;
#define bufsz 5223
static char buf[bufsz] = {'b', 'u', 'f'};
#if 1
- int sysc_open(const char *path, int flags, int mode);
+ int sysc_open(const char* path, int flags, int mode);
int fd = sysc_open(path, flags, 0700);
assert(fd >= 0);
- ssize_t sysc_write(int fd, const char *buf, size_t size);
+ ssize_t sysc_write(int fd, const char* buf, size_t size);
sysc_write(fd, fc, fe_filesz);
- ssize_t sysc_read(int fd, void *buf, size_t count);
+ ssize_t sysc_read(int fd, void* buf, size_t count);
sysc_read(fd, buf, bufsz);
#else
path_open_namei(path, flags, S_IFREG, &ni);
#include <system.h>
#include <types.h>
-int do_fork(pt_regs_t *regs, unsigned long flags);
+int do_fork(pt_regs_t* regs, unsigned long flags);
int sysc_wait(int ticks);
#define get_eflags(x) __asm__ __volatile__("pushfl; popl %0;" : "=g"(x)::"memory")
-void kernel_task(char *name, void *entry, void *arg) {
+void kernel_task(char* name, void* entry, void* arg) {
pt_regs_t regs;
- memset((void *)®s, 0, sizeof(regs));
+ memset((void*)®s, 0, sizeof(regs));
// 内核任务入口
regs.edx = (unsigned long)entry;
#include <page.h>
void flush_tlb() {
- asm volatile("movl %%cr3, %%eax;"
- "movl %%eax, %%cr3;"
- :
- :
- : "eax");
+ asm volatile(
+ "movl %%cr3, %%eax;"
+ "movl %%eax, %%cr3;"
+ :
+ :
+ : "eax");
}
void user_task_entry() {
// ring3的地址直接是物理地址
extern uint8_t ring3_page_begin;
- paddr_t ring3_page_addr = (paddr_t)&ring3_page_begin; // 不在内核空间的物理地址
+ paddr_t ring3_page_addr = (paddr_t)&ring3_page_begin; // 不在内核空间的物理地址
paddr_t ring3_stack_top = ring3_page_addr + PAGE_SIZE;
- vaddr_t ring3_page_vaddr = 0x08000000; // 指定的ring3的虚拟地址
+ vaddr_t ring3_page_vaddr = 0x08000000; // 指定的ring3的虚拟地址
vaddr_t ring3_stack_top_vaddr = PAGE_OFFSET - 0x100000;
page_map(ring3_page_vaddr, ring3_page_addr, PAGE_P | PAGE_US);
// 这里减去PAGE_SIZE是因为栈是向下生长的,所以得把栈顶虚拟地址空间的前一页映射到ring3_page
- page_map((ring3_stack_top_vaddr-PAGE_SIZE), ring3_page_addr, PAGE_P | PAGE_US | PAGE_WR);
-
+ page_map((ring3_stack_top_vaddr - PAGE_SIZE), ring3_page_addr, PAGE_P | PAGE_US | PAGE_WR);
{
// 在ring3_page里非代码的地方插入特征值方便调试
extern uint8_t ring3_text_end;
uint32_t ring3_text_size = (&ring3_text_end) - (&ring3_page_begin);
- for(uint32_t i = ring3_text_size; i<PAGE_SIZE; i++) {
- ((uint8_t *)(pa2va(ring3_page_addr)))[i] = 0xCC;
+ for (uint32_t i = ring3_text_size; i < PAGE_SIZE; i++) {
+ ((uint8_t*)(pa2va(ring3_page_addr)))[i] = 0xCC;
}
}
uint32_t days_in_month[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
-int is_leap_year(uint32_t year) { return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)); }
+int is_leap_year(uint32_t year) {
+ return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
+}
void timestamp_to_date(uint32_t timestamp) {
// 将时间戳转换为东8区时间
#define BYTES_PER_LINE (CHARS_PER_LINE * 2)
#define TAB_SPACE 4
-tty_t *const default_tty = ttys + 0;
-tty_t *const monitor_tty = ttys + 1;
-tty_t *const debug_tty = ttys + 2;
+tty_t* const default_tty = ttys + 0;
+tty_t* const monitor_tty = ttys + 1;
+tty_t* const debug_tty = ttys + 2;
-void tty_clear(tty_t *tty) {
- char *dst = (char *)tty->base_addr;
+void tty_clear(tty_t* tty) {
+ char* dst = (char*)tty->base_addr;
for (int src = 0; src < (MAX_Y * BYTES_PER_LINE); src += 2) {
*dst++ = 0;
*dst++ = (tty->bg_color << 4) | tty->fg_color;
// 而如果输出字符颜色与光标所处位置已经设置的颜色不一致的话
// 就需要将输出的这个字符的后一个位置的颜色设置成与之一致
// 这样光标颜色才与输出字符一致
-void __tty_set_next_pos_color(tty_t *tty, char color) {
+void __tty_set_next_pos_color(tty_t* tty, char color) {
unsigned int xpos = tty->xpos;
unsigned int ypos = tty->ypos;
xpos %= CHARS_PER_LINE;
if (ypos < MAX_Y) {
- char *dst = (char *)(tty->base_addr + ypos * BYTES_PER_LINE + 2 * xpos);
+ char* dst = (char*)(tty->base_addr + ypos * BYTES_PER_LINE + 2 * xpos);
dst[0] = 0;
dst[1] = color;
}
}
-void init_tty(tty_t *tty, const char *name, unsigned long base) {
+void init_tty(tty_t* tty, const char* name, unsigned long base) {
assert(0 != tty);
assert(NR_TTYS >= 1);
assert(NR_TTYS <= MAX_NR_TTYS);
tty->base_addr = base;
for (int i = 0; i < TTY_VRAM_SIZE; i += 2) {
- uint8_t *p = (uint8_t *)base;
+ uint8_t* p = (uint8_t*)base;
p[i + 0] = ' ';
p[i + 1] = (tty->bg_color << 4) | tty->fg_color;
}
assert(irq_disabled());
for (int i = 0; i < NR_TTYS; i++) {
- tty_t *tty = ttys + i;
+ tty_t* tty = ttys + i;
char name[sizeof(tty->name)];
sprintf(name, "tty.%u", i);
init_tty(tty, name, VADDR + i * TTY_VRAM_SIZE);
debug_tty->bg_color = TTY_BLACK; // TTY_CYAN;
for (int i = 0; i < NR_TTYS; i++) {
- tty_t *tty = ttys + i;
+ tty_t* tty = ttys + i;
tty_clear(tty);
}
current_tty = default_tty;
}
-void tty_do_scroll_up(tty_t *tty) {
+void tty_do_scroll_up(tty_t* tty) {
// 没越过最后一行不需要上卷
if (tty->ypos < MAX_Y - 1) {
return;
// 如果是default_tty则保留用来显示内核版本及编译时间信息
const int keep = tty != default_tty ? 0 : BYTES_PER_LINE;
- char *dst = (char *)tty->base_addr + keep;
+ char* dst = (char*)tty->base_addr + keep;
for (int src = BYTES_PER_LINE + keep; src < (MAX_Y * BYTES_PER_LINE); src++) {
- *dst++ = *(char *)(tty->base_addr + src);
+ *dst++ = *(char*)(tty->base_addr + src);
}
// 清空最后一行
- dst = (char *)(tty->base_addr + ((MAX_Y - 1) * BYTES_PER_LINE));
+ dst = (char*)(tty->base_addr + ((MAX_Y - 1) * BYTES_PER_LINE));
for (int i = 0; i < BYTES_PER_LINE; i += 2) {
*dst++ = 0;
*dst++ = (tty->bg_color << 4) | tty->fg_color;
tty->ypos = MAX_Y - 1;
}
-void tty_color_putc(tty_t *tty, char c, unsigned int fg_color, unsigned bg_color) {
+void tty_color_putc(tty_t* tty, char c, unsigned int fg_color, unsigned bg_color) {
bool display = false;
bool move_to_next_pos = true;
switch (c) {
// 显示
if (display) {
unsigned int pos = tty->ypos * BYTES_PER_LINE + tty->xpos * 2;
- char *va = (char *)(tty->base_addr + pos);
+ char* va = (char*)(tty->base_addr + pos);
va[0] = c;
va[1] = (bg_color << 4) | fg_color;
tty_set_cursor(tty);
}
-void tty_putc(tty_t *tty, char c) { tty_color_putc(tty, c, tty->fg_color, tty->bg_color); }
+void tty_putc(tty_t* tty, char c) {
+ tty_color_putc(tty, c, tty->fg_color, tty->bg_color);
+}
-void tty_write(tty_t *tty, const char *buf, size_t size) {
+void tty_write(tty_t* tty, const char* buf, size_t size) {
assert(0 != tty);
if (0 == buf) {
return;
}
}
-void tty_write_at(tty_t *tty, int xpos, int ypos, const char *buf, size_t size) {
+void tty_write_at(tty_t* tty, int xpos, int ypos, const char* buf, size_t size) {
assert(0 != tty);
assert(xpos < BYTES_PER_LINE);
assert(ypos < MAX_Y);
#define VGA_CRTC_CURSOR_H 0xE
#define VGA_CRTC_CURSOR_L 0xF
-void tty_set_cursor(tty_t *tty) {
+void tty_set_cursor(tty_t* tty) {
if (tty != current_tty) {
return;
}
irq_restore(flags);
}
-void tty_switch(tty_t *tty) {
+void tty_switch(tty_t* tty) {
if (0 == tty) {
return;
}
}
void tty_switch_to_next() {
- tty_t *tty = ttys + ((current_tty - ttys + 1) % NR_TTYS);
+ tty_t* tty = ttys + ((current_tty - ttys + 1) % NR_TTYS);
tty_switch(tty);
}
-tty_t *current_tty;
+tty_t* current_tty;
#include <sched.h>
#include <wait.h>
-volatile void init_wait_queue_head(wait_queue_head_t *wqh) { INIT_LIST_HEAD(&(wqh->task_list)); }
+volatile void init_wait_queue_head(wait_queue_head_t* wqh) {
+ INIT_LIST_HEAD(&(wqh->task_list));
+}
-volatile void prepare_to_wait(wait_queue_head_t *head, wait_queue_entry_t *wqe, unsigned int state) {
+volatile void prepare_to_wait(wait_queue_head_t* head, wait_queue_entry_t* wqe, unsigned int state) {
unsigned long flags;
irq_save(flags);
// 进程可能等待一个condition满足后被唤醒
irq_restore(flags);
}
-volatile void __end_wait(wait_queue_entry_t *wqe) {
+volatile void __end_wait(wait_queue_entry_t* wqe) {
set_current_state(TASK_READY);
current->reason = "e_wait";
unsigned long flags;
irq_restore(flags);
}
-volatile void add_wait_queue(wait_queue_head_t *head, wait_queue_entry_t *wqe) {
+volatile void add_wait_queue(wait_queue_head_t* head, wait_queue_entry_t* wqe) {
unsigned long flags;
irq_save(flags);
list_add_tail(&wqe->entry, &head->task_list);
irq_restore(flags);
}
-volatile void del_wait_queue(wait_queue_head_t *head, wait_queue_entry_t *wqe) {
+volatile void del_wait_queue(wait_queue_head_t* head, wait_queue_entry_t* wqe) {
unsigned long flags;
irq_save(flags);
list_del(&wqe->entry);
irq_restore(flags);
}
-volatile void __wake_up(wait_queue_head_t *head, int nr) {
+volatile void __wake_up(wait_queue_head_t* head, int nr) {
unsigned long flags;
wait_queue_entry_t *p, *tmp;
irq_save(flags);
// no schedule() here.
}
-volatile void wake_up(wait_queue_head_t *head) {
+volatile void wake_up(wait_queue_head_t* head) {
//
__wake_up(head, 0); // wake up all
}
*/
#include <syscall.h>
-int execv(const char *path, char *const argv[]) { return syscall2(SYSC_EXEC, path, argv); }
+int execv(const char* path, char* const argv[]) {
+ return syscall2(SYSC_EXEC, path, argv);
+}
*/
#include <syscall.h>
-int exit(int status) { syscall1(SYSC_EXIT, status); }
+int exit(int status) {
+ syscall1(SYSC_EXIT, status);
+}
if(ScanCode & 0x80) // Make Or Break Code ?
goto BreakCode;
-#if 0
+#if 0
// Ctrl + Alt + Del
if( IS_L_CTRL_DOWN(key) && IS_L_ALT_DOWN(key))
{
E0Flag?SET_R_ALT_DOWN(key):SET_L_ALT_DOWN(key);
goto End;
}
-
+
goto End;
BreakCode:
#include <syscall.h>
#include <system.h>
-int isdigit(char c) { return ('0' <= c && c <= '9'); }
+int isdigit(char c) {
+ return ('0' <= c && c <= '9');
+}
-int atoi(const char *s) {
+int atoi(const char* s) {
int i = 0;
while (isdigit(*s)) {
i *= 10;
// int pause(unsigned long tick) { return syscall1(SYSC_PAUSE, tick); }
-int vsprintf(char *buf, const char *fmt, char *args);
-int sprintf(char *str, const char *fmtstr, ...) {
- char *args = (char *)(((char *)&fmtstr) + 4);
+int vsprintf(char* buf, const char* fmt, char* args);
+int sprintf(char* str, const char* fmtstr, ...) {
+ char* args = (char*)(((char*)&fmtstr) + 4);
vsprintf(str, fmtstr, args);
nop
nop
die:
- jmp die
+ jmp die
*--------------------------------------------------------------------------
*/
#include <syscall.h>
-int open(const char *path, int flags, ...) {
+int open(const char* path, int flags, ...) {
// 不支持第三个参数
return syscall3(SYSC_OPEN, path, flags, 0);
}
*/
#include <syscall.h>
#include <types.h>
-ssize_t read(int fd, void *buf, size_t count) { return (ssize_t)syscall3(SYSC_READ, fd, buf, count); }
+ssize_t read(int fd, void* buf, size_t count) {
+ return (ssize_t)syscall3(SYSC_READ, fd, buf, count);
+}
#include <syscall.h>
#include <types.h>
-int _stat(int fd, struct stat *stat) { return syscall2(SYSC_STAT, fd, stat); }
-int fstat(int fd, struct stat *buf) { return _stat(fd, buf); }
+int _stat(int fd, struct stat* stat) {
+ return syscall2(SYSC_STAT, fd, stat);
+}
+int fstat(int fd, struct stat* buf) {
+ return _stat(fd, buf);
+}
#include "string.h"
-char *strcpy(char *dest, const char *src) {
- char *p = dest;
+char* strcpy(char* dest, const char* src) {
+ char* p = dest;
while ((*dest++ = *src++))
;
return p;
}
-char *strncpy(char *dst, const char *src, size_t len) {
+char* strncpy(char* dst, const char* src, size_t len) {
for (size_t i = 0; i < len; i++) {
dst[i] = src[i];
if (src[i] == 0) {
return dst;
}
-size_t strlcpy(char *dst, const char *src, size_t size) {
+size_t strlcpy(char* dst, const char* src, size_t size) {
size_t i = 0;
if (size == 0) {
return i;
}
-size_t strlen(const char *str) {
+size_t strlen(const char* str) {
int i = 0;
- while (*str++) i++;
+ while (*str++)
+ i++;
return i;
}
-int strcmp(const char *a, const char *b) {
+int strcmp(const char* a, const char* b) {
int delta;
while (*a || *b) {
delta = *a++ - *b++;
- if (delta != 0) return delta;
+ if (delta != 0)
+ return delta;
}
return 0;
}
-int strncmp(const char *a, const char *b, size_t count) {
+int strncmp(const char* a, const char* b, size_t count) {
unsigned char c1, c2;
int delta;
while (count) {
c2 = *b++;
delta = c1 - c2;
- if (delta != 0) return delta;
+ if (delta != 0)
+ return delta;
- if (c1 == 0) break;
+ if (c1 == 0)
+ break;
count--;
}
return 0;
}
-char *strcat(char *dest, const char *src) {
- char *tmp = dest;
- while (*dest) dest++;
+char* strcat(char* dest, const char* src) {
+ char* tmp = dest;
+ while (*dest)
+ dest++;
while (*dest++ = *src++)
;
return tmp;
}
-void *memcpy(void *dest, const void *src, size_t size) {
- char *d = (char *)dest;
- char *s = (char *)src;
+void* memcpy(void* dest, const void* src, size_t size) {
+ char* d = (char*)dest;
+ char* s = (char*)src;
while (size-- > 0) {
*d = *s;
d++;
return dest;
}
-void memset(void *dest, char ch, size_t size) {
- char *p = (char *)dest;
+void memset(void* dest, char ch, size_t size) {
+ char* p = (char*)dest;
for (size_t i = 0; i < size; i++) {
*p = ch;
p++;
}
}
-int memcmp(const void *a, const void *b, size_t count) {
+int memcmp(const void* a, const void* b, size_t count) {
const unsigned char *sa, *sb;
int delta = 0;
for (sa = a, sb = b; count > 0; ++sa, ++sb, --count)
- if ((delta = *sa - *sb) != 0) break;
+ if ((delta = *sa - *sb) != 0)
+ break;
return delta;
}
-char *strstr(const char *a, const char *b) {
+char* strstr(const char* a, const char* b) {
size_t la, lb;
lb = strlen(b);
- if (lb == 0) return (char *)a;
+ if (lb == 0)
+ return (char*)a;
la = strlen(a);
while (la >= lb) {
la--;
- if (memcmp(a, b, lb) == 0) return (char *)a;
+ if (memcmp(a, b, lb) == 0)
+ return (char*)a;
a++;
}
return __sysc_ret__;
}
-int _syscall0(int nr) { return __syscall0(nr); }
+int _syscall0(int nr) {
+ return __syscall0(nr);
+}
-int _syscall1(int nr, unsigned long a) { return __syscall1(nr, a); }
+int _syscall1(int nr, unsigned long a) {
+ return __syscall1(nr, a);
+}
-int _syscall2(int nr, unsigned long a, unsigned long b) { return __syscall2(nr, a, b); }
+int _syscall2(int nr, unsigned long a, unsigned long b) {
+ return __syscall2(nr, a, b);
+}
-int _syscall3(int nr, unsigned long a, unsigned long b, unsigned long c) { return __syscall3(nr, a, b, c); }
+int _syscall3(int nr, unsigned long a, unsigned long b, unsigned long c) {
+ return __syscall3(nr, a, b, c);
+}
int _syscall4(int nr, unsigned long a, unsigned long b, unsigned long c, unsigned long d) {
return __syscall4(nr, a, b, c, d);
#include "string.h"
-char *itoa(char *s, int n);
-char *itou(char *s, unsigned int n);
-char *itoo(char *s, unsigned int n);
-char *itox(char *s, unsigned int n, int upper);
-char *i64tou(char *s, uint64_t n);
-char *i64too(char *s, uint64_t n);
-char *i64tox(char *s, uint64_t n, int upper);
+char* itoa(char* s, int n);
+char* itou(char* s, unsigned int n);
+char* itoo(char* s, unsigned int n);
+char* itox(char* s, unsigned int n, int upper);
+char* i64tou(char* s, uint64_t n);
+char* i64too(char* s, uint64_t n);
+char* i64tox(char* s, uint64_t n, int upper);
enum { ALIGN_RIGHT, ALIGN_LEFT };
-int write_buf(char *buf, const char *str, char fillch, int charcnt, int align) {
- if (str == 0) return 0;
+int write_buf(char* buf, const char* str, char fillch, int charcnt, int align) {
+ if (str == 0)
+ return 0;
int len = strlen(str);
int delta_char_cnt = charcnt - len;
return charcnt > len ? charcnt : len;
}
-int vsprintf(char *buf, const char *fmt, char *args) {
- char *p = buf;
+int vsprintf(char* buf, const char* fmt, char* args) {
+ char* p = buf;
int char_cnt;
char tmp[64];
*p++ = *args;
break;
case 'd':
- itoa(tmp, *((int *)args));
+ itoa(tmp, *((int*)args));
p += write_buf(p, tmp, char_fill, char_cnt, align);
break;
case 'l':
fmt++;
if (*fmt == 'u' || *fmt == 'd') { // d u都当成u来处理
- i64tou(tmp, *((int64_t *)args));
+ i64tou(tmp, *((int64_t*)args));
p += write_buf(p, tmp, char_fill, char_cnt, align);
args += 4;
} else if (*fmt == 'o') {
- i64too(tmp, *((uint64_t *)args));
+ i64too(tmp, *((uint64_t*)args));
p += write_buf(p, tmp, char_fill, char_cnt, align);
args += 4;
} else if (*fmt == 'x' || *fmt == 'X') {
// i64tox(tmp, *((uint64_t *)args), *fmt == 'X' ? 1 : 0);
- i64tox(tmp, *((uint64_t *)args), 1); // x X都强制为大写
+ i64tox(tmp, *((uint64_t*)args), 1); // x X都强制为大写
p += write_buf(p, tmp, char_fill, char_cnt, align);
args += 4;
}
break;
case 's':
- p += write_buf(p, (const char *)*((unsigned int *)args), char_fill, char_cnt, align);
+ p += write_buf(p, (const char*)*((unsigned int*)args), char_fill, char_cnt, align);
break;
case 'u':
- itou(tmp, *((unsigned int *)args));
+ itou(tmp, *((unsigned int*)args));
p += write_buf(p, tmp, char_fill, char_cnt, align);
break;
case 'x':
case 'X':
// itox(tmp, *((unsigned int *)args), *fmt == 'X' ? 1 : 0);
- itox(tmp, *((unsigned int *)args), 1); // x X都强制为大写
+ itox(tmp, *((unsigned int*)args), 1); // x X都强制为大写
p += write_buf(p, tmp, char_fill, char_cnt, align);
break;
case 'o':
- itoo(tmp, *((unsigned *)args));
+ itoo(tmp, *((unsigned*)args));
p += write_buf(p, tmp, char_fill, char_cnt, align);
break;
default:
return p - buf;
}
-void swap_char(char *a, char *b) {
+void swap_char(char* a, char* b) {
char c;
c = *a;
*a = *b;
*b = c;
}
-char *itoa(char *s, int n) {
+char* itoa(char* s, int n) {
int i = 0;
- char *p = 0;
+ char* p = 0;
if (n & 0x80000000) {
n = ~n + 1;
}
}
-char *i64tou(char *s, uint64_t n) {
+char* i64tou(char* s, uint64_t n) {
itou(s, n >> 32);
int i = 0;
if ((n >> 32) > 0) {
itou(s + i, n & 0xFFFFFFFF);
}
-char *itou(char *s, unsigned int n) {
+char* itou(char* s, unsigned int n) {
char c;
- char *p = s;
+ char* p = s;
do {
*p++ = (n % 10) + '0';
}
}
-char *_itoo(char *s, uint64_t n, int bgn) {
- char *p = s;
+char* _itoo(char* s, uint64_t n, int bgn) {
+ char* p = s;
char ch;
int i;
bool flag = false;
return s;
}
-char *itoo(char *s, unsigned int n) {
+char* itoo(char* s, unsigned int n) {
//
return _itoo(s, n, 30);
}
-char *i64too(char *s, uint64_t n) {
+char* i64too(char* s, uint64_t n) {
//
return _itoo(s, n, 63);
}
-char *_itox(char *s, uint64_t n, int upper, int bgn) {
- char *p = s;
+char* _itox(char* s, uint64_t n, int upper, int bgn) {
+ char* p = s;
char ch;
int i;
bool flag = false;
return s;
}
-char *itox(char *s, unsigned int n, int upper) {
+char* itox(char* s, unsigned int n, int upper) {
//
return _itox(s, n, upper, 28);
}
-char *i64tox(char *s, uint64_t n, int upper) {
+char* i64tox(char* s, uint64_t n, int upper) {
//
return _itox(s, n, upper, 60);
}
*/
#include <syscall.h>
-int wait(unsigned long pid) { syscall1(SYSC_WAIT, pid); }
+int wait(unsigned long pid) {
+ syscall1(SYSC_WAIT, pid);
+}
#include <syscall.h>
-int write(int fd, const char *buf, unsigned long size) {
+int write(int fd, const char* buf, unsigned long size) {
// asm(""::"c"(size),"d"(buf),"b"(fd));
// sysenter(0);
// syscall3(0, fd, buf, size);
#include <string.h>
#include <system.h>
-static void get_e820_size(uint32_t size, char *buf) {
- const char *fmt = "%3u %s";
+static void get_e820_size(uint32_t size, char* buf) {
+ const char* fmt = "%3u %s";
if (size < (1 << 10)) {
sprintf(buf, fmt, size, "B");
} else if (size < (1 << 20)) {
// }
// }
-static void get_e820_type(uint32_t type, char *buf) {
+static void get_e820_type(uint32_t type, char* buf) {
switch (type) {
case E820_RAM:
sprintf(buf, "%s", "RAM");
// op: 0 clear bit, 1 set bit
void fast_init_bootmem_bitmap(unsigned long bgn_pfn, unsigned long end_pfn, int op) {
- int (*bit_func)(unsigned int, volatile unsigned long *);
+ int (*bit_func)(unsigned int, volatile unsigned long*);
bit_func = op == 0 ? test_and_clear_bit : test_and_set_bit;
unsigned int bytes = (end_pfn - i) / 8;
// 直接清零或设置
- memset((char *)(bootmem_data.bitmap) + (i / 8), data, bytes);
+ memset((char*)(bootmem_data.bitmap) + (i / 8), data, bytes);
// 最后设置尾部不是整字节的比特
for (i += bytes * 8; i < end_pfn; i++) {
void e820_print_map() {
unsigned int i = 0;
for (i = 0; i < boot_params.e820map.map_cnt; ++i) {
- struct e820_entry *p = boot_params.e820map.map + i;
+ struct e820_entry* p = boot_params.e820map.map + i;
// printk(" [%02d] 0x%010lX - 0x%010lX size %- 10u %8dKB %5dMB ", i, p->addr, (p->addr + p->size - 1),
// (uint32_t)p->size, (uint32_t)(p->size >> 10), (uint32_t)(p->size >> 20));
bootmem_data_t bootmem_data;
-unsigned long bootmem_max_pfn() { return bootmem_data.max_pfn; }
+unsigned long bootmem_max_pfn() {
+ return bootmem_data.max_pfn;
+}
-unsigned long bootmem_page_state(unsigned long pfn) { return constant_test_bit(pfn, bootmem_data.bitmap); }
+unsigned long bootmem_page_state(unsigned long pfn) {
+ return constant_test_bit(pfn, bootmem_data.bitmap);
+}
void e820_init_bootmem_data() {
unsigned int i = 0;
bootmem_data.max_pfn = 0;
for (i = 0; i < boot_params.e820map.map_cnt; ++i) {
- struct e820_entry *p = boot_params.e820map.map + i;
+ struct e820_entry* p = boot_params.e820map.map + i;
if (p->type != E820_RAM) {
continue;
void register_bootmem_pages() {
for (unsigned int i = 0; i < boot_params.e820map.map_cnt; ++i) {
- struct e820_entry *p = boot_params.e820map.map + i;
+ struct e820_entry* p = boot_params.e820map.map + i;
if (p->type != E820_RAM) {
continue;
#endif
}
-void reserve_kernel_pages() { reserve_bootmem(PFN_DW(va2pa(system.kernel_begin)), PFN_UP(va2pa(system.kernel_end))); }
+void reserve_kernel_pages() {
+ reserve_bootmem(PFN_DW(va2pa(system.kernel_begin)), PFN_UP(va2pa(system.kernel_end)));
+}
void reserve_bootmem_bitmap() {
unsigned long bgn_pfn = PFN_DW(va2pa(bootmem_data.bitmap));
// 由于只有在构建buddy system的时候才会用到
// 所以这里就简单实现
-void *alloc_from_bootmem(unsigned long size, char *title) {
- void *region = NULL;
+void* alloc_from_bootmem(unsigned long size, char* title) {
+ void* region = NULL;
unsigned long pfn_cnt = PFN_UP(size);
- bootmem_data_t *pbd = &bootmem_data;
+ bootmem_data_t* pbd = &bootmem_data;
// 从该处开始查找空闲区间
unsigned long search_bgn_pfn = pbd->prepare_alloc_pfn;
#include <sysctl.h>
struct buddy_system {
- page_t *page_map;
- page_t *page_map_end;
+ page_t* page_map;
+ page_t* page_map_end;
free_area_t free_area[MAX_ORDER];
};
struct buddy_system buddy_system;
-int buddy_is_free(page_t *page, unsigned int order) {
- if (PagePrivate(page) && page->private == order) return 1;
+int buddy_is_free(page_t* page, unsigned int order) {
+ if (PagePrivate(page) && page->private == order)
+ return 1;
return 0;
}
-page_t *_va2page(unsigned long addr) {
- page_t *page = buddy_system.page_map + va2pfn(addr);
+page_t* _va2page(unsigned long addr) {
+ page_t* page = buddy_system.page_map + va2pfn(addr);
assert(page >= buddy_system.page_map);
// assert(page < buddy_system.page_map_end);
return page;
}
-page_t *_pa2page(unsigned long paddr) {
+page_t* _pa2page(unsigned long paddr) {
unsigned long vaddr = (unsigned long)pa2va(paddr);
// printk("%s paddr %08x vaddr %08x\n", __func__, paddr, vaddr);
return va2page(vaddr);
}
-void *page2va(page_t *page) { return pfn2va((page)-buddy_system.page_map); }
-void *page2pa(page_t *page) { return pfn2pa((page)-buddy_system.page_map); }
+void* page2va(page_t* page) {
+ return pfn2va((page)-buddy_system.page_map);
+}
+void* page2pa(page_t* page) {
+ return pfn2pa((page)-buddy_system.page_map);
+}
-page_t *__alloc_pages(unsigned int order) {
+page_t* __alloc_pages(unsigned int order) {
//
- page_t *page = 0;
- free_area_t *area;
+ page_t* page = 0;
+ free_area_t* area;
unsigned int select_order;
unsigned int i;
select_order--;
unsigned long buddy_offset = 1UL << select_order;
- page_t *buddy_page = page + buddy_offset;
+ page_t* buddy_page = page + buddy_offset;
list_add(&(buddy_page->lru), &(area->free_list));
area->free_count++;
buddy_page->private = select_order;
// 初始化这一连续的page块
for (i = 0; i < (1UL << order); ++i) {
- page_t *p = page + i;
+ page_t* p = page + i;
p->head_page = page;
p->order = order;
}
return page;
}
-page_t *alloc_pages(unsigned int gfp_mask, unsigned int order) {
+page_t* alloc_pages(unsigned int gfp_mask, unsigned int order) {
// gfp_mask
// ...
unsigned long flags;
irq_save(flags);
- page_t *page = __alloc_pages(order);
+ page_t* page = __alloc_pages(order);
irq_restore(flags);
// unsigned long addr = (unsigned long)page2va(page);
return page;
}
-void __free_pages(page_t *page, unsigned int order) {
- if (order > MAX_ORDER) return;
+void __free_pages(page_t* page, unsigned int order) {
+ if (order > MAX_ORDER)
+ return;
- page_t *buddy = 0;
- page_t *base = buddy_system.page_map;
+ page_t* buddy = 0;
+ page_t* base = buddy_system.page_map;
unsigned long page_inx = page - base;
while (order < (MAX_ORDER - 1)) {
unsigned long buddy_inx = page_inx ^ (1UL << order);
order++;
}
- page_t *p = base + page_inx;
+ page_t* p = base + page_inx;
p->private = order;
p->index = page_inx;
SetPagePrivate(p);
BUG_ON(!valid_va(addr));
}
- page_t *page = va2page(addr);
+ page_t* page = va2page(addr);
unsigned long flags;
irq_save(flags);
printk("order %2d free_count %d ", i, buddy_system.free_area[i].free_count);
if (buddy_system.free_area[i].free_count < 1000) {
- list_head_t *p;
- page_t *page;
+ list_head_t* p;
+ page_t* page;
printk("pfn:");
list_for_each(p, &buddy_system.free_area[i].free_list) {
page = list_entry(p, page_t, lru);
}
void init_buddy_system() {
- page_t *page;
+ page_t* page;
unsigned long i;
unsigned long pfn_cnt = bootmem_max_pfn();
// init page map
unsigned long page_map_size = pfn_cnt * sizeof(page_t);
- void *alloc_from_bootmem(unsigned long size, char *title);
+ void* alloc_from_bootmem(unsigned long size, char* title);
buddy_system.page_map = alloc_from_bootmem(page_map_size, "buddy");
buddy_system.page_map = pa2va(buddy_system.page_map);
if (0 == buddy_system.page_map) {
printk("can not go on playing...\n");
- while (1);
+ while (1)
+ ;
}
buddy_system.page_map_end = buddy_system.page_map + pfn_cnt + 1;
pfn_cnt, sizeof(page_t));
for (i = 0; i < pfn_cnt; ++i) {
page = buddy_system.page_map + i;
- memset((void *)page, 0, sizeof(page_t));
+ memset((void*)page, 0, sizeof(page_t));
page->private = 0;
page->index = i;
INIT_LIST_HEAD(&(page->lru));
static list_head_t slub_caches = LIST_HEAD_INIT(slub_caches);
static kmem_cache_t kmalloc_caches[SLUB_INIT_CACHE_SIZE];
-bool calculate_params(kmem_cache_t *cache) {
+bool calculate_params(kmem_cache_t* cache) {
// calculate size
unsigned long size = cache->objsize;
unsigned long align = cache->align;
align = KMALLOC_MIN_ALIGN > align ? KMALLOC_MIN_ALIGN : align;
size = ALIGN(size, align);
- size = ALIGN(size, sizeof(void *));
+ size = ALIGN(size, sizeof(void*));
cache->size = size;
cache->align = align;
////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool kmem_cache_init(kmem_cache_t *cache, const char *name, size_t size, size_t align) {
+bool kmem_cache_init(kmem_cache_t* cache, const char* name, size_t size, size_t align) {
memset(cache, 0, sizeof(kmem_cache_t));
cache->name = name;
return false;
}
-void *kmem_cache_alloc(kmem_cache_t *cache, gfp_t gfpflags) { return slub_alloc(cache, gfpflags); }
+void* kmem_cache_alloc(kmem_cache_t* cache, gfp_t gfpflags) {
+ return slub_alloc(cache, gfpflags);
+}
-void *kmem_cache_zalloc(kmem_cache_t *cache, gfp_t gfpflags) {
- void *p = slub_alloc(cache, gfpflags);
+void* kmem_cache_zalloc(kmem_cache_t* cache, gfp_t gfpflags) {
+ void* p = slub_alloc(cache, gfpflags);
if (0 != p) {
memset(p, 0, cache->objsize);
}
return p;
}
-void kmem_cache_free(kmem_cache_t *cache, void *addr) {
- page_t *page = 0;
+void kmem_cache_free(kmem_cache_t* cache, void* addr) {
+ page_t* page = 0;
page = get_head_page(va2page((unsigned long)addr));
slub_free(cache, page, addr);
}
-kmem_cache_t *kmem_cache_create(const char *name, size_t size, size_t align) {
- kmem_cache_t *cache = kmalloc(sizeof(kmem_cache_t), 0);
+kmem_cache_t* kmem_cache_create(const char* name, size_t size, size_t align) {
+ kmem_cache_t* cache = kmalloc(sizeof(kmem_cache_t), 0);
if (cache == 0) {
return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
-void *kmalloc(size_t size, gfp_t gfpflags) {
+void* kmalloc(size_t size, gfp_t gfpflags) {
unsigned int i;
- kmem_cache_t *cache = 0;
- void *addr = 0;
+ kmem_cache_t* cache = 0;
+ void* addr = 0;
for (i = 0; i < SLUB_INIT_CACHE_SIZE; ++i) {
- kmem_cache_t *p = kmalloc_caches + i;
+ kmem_cache_t* p = kmalloc_caches + i;
if (p->objsize >= size) {
cache = p;
break;
return addr;
}
-void *kzalloc(size_t size, gfp_t gfpflags) {
- void *p = kmalloc(size, gfpflags);
+void* kzalloc(size_t size, gfp_t gfpflags) {
+ void* p = kmalloc(size, gfpflags);
if (0 != p) {
memset(p, 0, size);
}
return p;
}
-void kfree(void *addr) {
- page_t *page = get_head_page(va2page((unsigned long)addr));
- kmem_cache_t *cache = page->cache;
+void kfree(void* addr) {
+ page_t* page = get_head_page(va2page((unsigned long)addr));
+ kmem_cache_t* cache = page->cache;
slub_free(cache, page, addr);
}
void init_kmem_caches() {
unsigned int i;
- kmem_cache_t *cache;
+ kmem_cache_t* cache;
for (i = SLUB_MIN_SHIFT; i < SLUB_MAX_SHIFT; ++i) {
cache = kmalloc_caches + i - SLUB_MIN_SHIFT;
pde_t __initdata init_pgd[PDECNT_PER_PAGE] __attribute__((__aligned__(PAGE_SIZE)));
pte_t __initdata init_pgt[PTECNT_PER_PAGE * BOOT_INIT_PAGETBL_CNT] __attribute__((__aligned__(PAGE_SIZE)));
-void set_page_shared(void *x) {
+void set_page_shared(void* x) {
unsigned long addr = (unsigned long)x;
addr = PAGE_ALIGN(addr);
unsigned int npd = get_npde(addr);
init_pgd[npd] |= PAGE_US;
- pte_t *pte = pa2va(init_pgd[npd] & PAGE_MASK);
+ pte_t* pte = pa2va(init_pgd[npd] & PAGE_MASK);
pte[get_npte(addr)] |= PAGE_US;
}
-char *paging_page = "paging";
+char* paging_page = "paging";
void init_paging() {
unsigned int i;
unsigned long pfn = 0;
- pte_t *pg_table = 0;
- void *alloc_from_bootmem(unsigned long size, char *title);
+ pte_t* pg_table = 0;
+ void* alloc_from_bootmem(unsigned long size, char* title);
// 在multiboot.S是已经初始化了BOOT_INIT_PAGETBL_CNT个页
// 这里接着初始化剩余的页
unsigned long npte = pfn % PAGE_PTE_CNT;
unsigned long page_addr = (unsigned long)pfn2pa(pfn);
if (npte == 0) {
- pg_table = (pte_t *)alloc_from_bootmem(PAGE_SIZE, paging_page);
+ pg_table = (pte_t*)alloc_from_bootmem(PAGE_SIZE, paging_page);
if (0 == pg_table) {
panic("no pages for paging...");
}
- memset((void *)pg_table, 0, PAGE_SIZE);
+ memset((void*)pg_table, 0, PAGE_SIZE);
init_pgd[get_npde(page_addr)] = (pde_t)((unsigned long)(pg_table) | PAGE_P | PAGE_WR);
}
// 这部分页表在pgd里的pde就不再允许修改了
// 这样,无论内核空间映射如何变化,这部分空间所有进程都能共享到变化
for (i = kernel_npde_base; i < PDECNT_PER_PAGE; ++i) {
- if(0 != init_pgd[i]) {
+ if (0 != init_pgd[i]) {
continue;
}
// 分配一个页表
- pte_t *pg_table = (pte_t *)alloc_from_bootmem(PAGE_SIZE, paging_page);
- if(0 == pg_table) {
+ pte_t* pg_table = (pte_t*)alloc_from_bootmem(PAGE_SIZE, paging_page);
+ if (0 == pg_table) {
panic("no pages for paging...");
}
// 清空页表
- memset((void *)pg_table, 0xAC, PAGE_SIZE);
+ memset((void*)pg_table, 0xAC, PAGE_SIZE);
// 把页表地址填入pgd
init_pgd[i] = (pde_t)((unsigned long)(pg_table) | PAGE_P | PAGE_WR);
}
-
// 建立完内核空间的页映射,需要清空用户空间的映射
for (i = 0; i < kernel_npde_base; ++i) {
init_pgd[i] = 0;
}
-
-
#if 0
// 接下来为显存建立页映射
unsigned long vram_phys_addr = system.vbe_phys_addr;
extern void init_ttys();
-kmem_cache_t *g_vma_kmem_cache = NULL;
+kmem_cache_t* g_vma_kmem_cache = NULL;
void init_mm() {
printk("init bootmem alloc...\n");
assert(g_vma_kmem_cache != NULL);
}
-vm_area_t *vma_alloc() {
- vm_area_t *vma = kmem_cache_alloc(g_vma_kmem_cache, 0);
+vm_area_t* vma_alloc() {
+ vm_area_t* vma = kmem_cache_alloc(g_vma_kmem_cache, 0);
vma->vm_bgn = 0;
vma->vm_end = 0;
vma->vm_flags = 0;
return vma;
}
-void vma_insert(task_t *tsk, vm_area_t *vma_new) {
+void vma_insert(task_t* tsk, vm_area_t* vma_new) {
//
- vm_area_t **p = &tsk->vma_list;
+ vm_area_t** p = &tsk->vma_list;
while (*p != NULL) {
- vm_area_t *v = *p;
+ vm_area_t* v = *p;
assert(v->vm_bgn < v->vm_end);
assert(vma_new->vm_bgn < vma_new->vm_end);
*p = vma_new;
}
-vm_area_t *vma_find(task_t *tsk, vm_area_t *vma, uint32_t addr) {
- vm_area_t **p = &tsk->vma_list;
+vm_area_t* vma_find(task_t* tsk, vm_area_t* vma, uint32_t addr) {
+ vm_area_t** p = &tsk->vma_list;
while (*p != NULL) {
- vm_area_t *v = *p;
+ vm_area_t* v = *p;
if (addr <= v->vm_end) {
break;
#include <sched.h>
#include <types.h>
-void do_no_page(void *addr) {
- pde_t *page_dir = (pde_t *)pa2va(current->cr3);
- pte_t *page_tbl = 0;
+void do_no_page(void* addr) {
+ pde_t* page_dir = (pde_t*)pa2va(current->cr3);
+ pte_t* page_tbl = 0;
unsigned long page = (unsigned long)page2va(alloc_one_page(0));
assert(page != 0);
int npte = get_npte(addr);
if (page_dir[npde] == 0) {
- page_tbl = (pte_t *)page2va(alloc_one_page(0));
+ page_tbl = (pte_t*)page2va(alloc_one_page(0));
assert(page_tbl != 0);
- memset((void *)page_tbl, 0, PAGE_SIZE);
+ memset((void*)page_tbl, 0, PAGE_SIZE);
page_dir[npde] = va2pa(page_tbl) | PAGE_P | PAGE_WR | PAGE_US;
}
- page_tbl = (pte_t *)pa2va(PAGE_ALIGN(page_dir[npde]));
+ page_tbl = (pte_t*)pa2va(PAGE_ALIGN(page_dir[npde]));
page_tbl[npte] = va2pa(page) | PAGE_P | PAGE_WR | PAGE_US;
load_cr3(current);
}
-void do_wp_page(void *addr) {
+void do_wp_page(void* addr) {
// printk("%s addr %08x current %08x\n", __func__, (unsigned long)addr, current);
if ((unsigned long)addr >= PAGE_OFFSET) {
panic("%s invalid addr", __func__);
int npde = get_npde(addr);
int npte = get_npte(addr);
- pde_t *page_dir = (pde_t *)pa2va(current->cr3);
- pde_t *pde = page_dir + npde;
+ pde_t* page_dir = (pde_t*)pa2va(current->cr3);
+ pde_t* pde = page_dir + npde;
// 如果是因为PDE被写保护
if (*pde & PDE_RW == 0) {
assert(newtbl != 0);
// 2. 拷贝页表
- pte_t *oldtbl = pa2va(PAGE_ALIGN(page_dir[npde]));
- memcpy((void *)newtbl, (void *)oldtbl, PAGE_SIZE);
+ pte_t* oldtbl = pa2va(PAGE_ALIGN(page_dir[npde]));
+ memcpy((void*)newtbl, (void*)oldtbl, PAGE_SIZE);
// 3. 对所有PTE加上写保护
- pte_t *pte = (pte_t *)newtbl;
+ pte_t* pte = (pte_t*)newtbl;
for (int i = 0; i < PTECNT_PER_PAGE; i++) {
*pte &= ~PTE_RW;
pte++;
*pde |= PDE_RW;
}
- pte_t *page_tbl = pa2va(PAGE_ALIGN(page_dir[npde]));
- pte_t *pte = page_tbl + npte;
+ pte_t* page_tbl = pa2va(PAGE_ALIGN(page_dir[npde]));
+ pte_t* pte = page_tbl + npte;
// 如果PTE的位置被写保护
if (*pte & PTE_RW == 0) {
assert(newaddr != 0);
// 2. 拷贝页表
- pte_t *oldaddr = pa2va(PAGE_ALIGN(page_dir[npde]));
- memcpy((void *)newaddr, (void *)oldaddr, PAGE_SIZE);
+ pte_t* oldaddr = pa2va(PAGE_ALIGN(page_dir[npde]));
+ memcpy((void*)newaddr, (void*)oldaddr, PAGE_SIZE);
// 3. 解除PTE的写保护
*pte |= PTE_RW;
load_cr3(current);
}
-
void page_map(vaddr_t vaddr, paddr_t paddr, uint32_t flags) {
assert(PAGE_ALIGN(vaddr) == vaddr);
assert(PAGE_ALIGN(paddr) == paddr);
int npte = get_npte(vaddr);
// 获取页目录地址
- pde_t *pgd = (pde_t *) pa2va(get_pgd());
+ pde_t* pgd = (pde_t*)pa2va(get_pgd());
- pte_t *pgt = 0;
+ pte_t* pgt = 0;
pde_t pde = pgd[npde];
- if(pde & PAGE_P) {
- pgt = (pte_t *)pa2va(PAGE_ALIGN(pde));
+ if (pde & PAGE_P) {
+ pgt = (pte_t*)pa2va(PAGE_ALIGN(pde));
} else {
// 分配页表
- pgt = (pte_t *)page2va(alloc_one_page(0));
+ pgt = (pte_t*)page2va(alloc_one_page(0));
// 清空页表
memset(pgt, 0, PAGE_SIZE);
// 页表指向物理地址
pgt[npte] = PAGE_ALIGN(paddr) | flags;
-
asm volatile("invlpg (%0)" : : "r"(vaddr));
}
#include <string.h>
#include <system.h>
-page_t *get_partial(kmem_cache_t *cache, gfp_t gfpflags) {
- if (list_empty(&cache->partial)) return 0;
+page_t* get_partial(kmem_cache_t* cache, gfp_t gfpflags) {
+ if (list_empty(&cache->partial))
+ return 0;
- list_head_t *p = cache->partial.next;
+ list_head_t* p = cache->partial.next;
list_del(p);
- page_t *page = 0;
+ page_t* page = 0;
page = list_entry(p, page_t, lru);
}
// 从伙伴系统批发页,并将之初始化成一个链表
-page_t *new_slub(kmem_cache_t *cache, gfp_t gfpflags) {
- page_t *page = alloc_pages(gfpflags, cache->order);
+page_t* new_slub(kmem_cache_t* cache, gfp_t gfpflags) {
+ page_t* page = alloc_pages(gfpflags, cache->order);
if (0 == page) {
return 0;
}
// 第一遍会将 bgn[0]的地址赋值给bgn[0],也就是 bgn[0] = bgn + 0
// 第二遍开始就是 bgn[n-1] = bgn + n
for (addr = bgn; addr < end; addr += cache->size) {
- *((void **)last) = (void *)addr;
+ *((void**)last) = (void*)addr;
last = addr;
}
// 最后一个赋值为0
- *((void **)last) = 0;
+ *((void**)last) = 0;
- page->freelist = (void **)bgn;
+ page->freelist = (void**)bgn;
page->inuse = 0;
page->cache = cache;
return page;
}
-void *__slub_alloc(kmem_cache_t *cache, gfp_t gfpflags) {
- void **object = 0;
- page_t *page = 0;
+void* __slub_alloc(kmem_cache_t* cache, gfp_t gfpflags) {
+ void** object = 0;
+ page_t* page = 0;
if (cache->page == 0) {
page = get_partial(cache, gfpflags);
return object;
}
-void *slub_alloc(kmem_cache_t *cache, gfp_t gfpflags) {
- void **object = 0;
+void* slub_alloc(kmem_cache_t* cache, gfp_t gfpflags) {
+ void** object = 0;
if (cache == 0) {
return 0;
return object;
}
-void __slub_free(kmem_cache_t *cache, page_t *page, void *addr) {
- void *prior;
- void **object = addr;
+void __slub_free(kmem_cache_t* cache, page_t* page, void* addr) {
+ void* prior;
+ void** object = addr;
prior = object[0] = page->freelist;
page->freelist = object;
}
}
-void slub_free(kmem_cache_t *cache, page_t *page, void *addr) {
+void slub_free(kmem_cache_t* cache, page_t* page, void* addr) {
unsigned long flags;
irq_save(flags);
- void **object = addr;
+ void** object = addr;
page->inuse--;
#define KMALLOC_MIN_SIZE (1UL << (SLUB_MIN_SHIFT))
#define KMALLOC_MIN_ALIGN (1UL << (SLUB_MIN_SHIFT))
-void *slub_alloc(kmem_cache_t *cache, gfp_t gfpflags);
-void slub_free(kmem_cache_t *cache, page_t *page, void *addr);
\ No newline at end of file
+void* slub_alloc(kmem_cache_t* cache, gfp_t gfpflags);
+void slub_free(kmem_cache_t* cache, page_t* page, void* addr);
# Description: none
# ------------------------------------------------------------------------
import re
-import requests
+import requests
from bs4 import BeautifulSoup
members = {}
ids = int(ids)
members[ids] = name
-
+
for ids in sorted(members.keys()) :
print("""{{0x{0:X}, "{1}"}},""".format(ids, members[ids]))
+++ /dev/null
-这两个脚本开始是为了解决宿主机和 docker 容器无法及时同步文件的问题.
-
-但这样写感觉不太优雅,废弃
-
-如果要再使用,注意的是要放在正确的目录
-
-host.mkiso.sh 放到 kernel/mkiso.sh
-container.mkiso.sh 放到 kernel/scripts/mkiso.sh
-
-host.mkiso.sh要在宿主机调用
-container.mkiso.sh会提交到 docker 容器执行
struct list_head *prev, *next;
} list_head_t;
-#define LIST_HEAD_INIT(name) \
- { &(name), &(name) }
+#define LIST_HEAD_INIT(name) {&(name), &(name)}
#define LIST_HEAD(name) list_head_t name = LIST_HEAD_INIT(name)
#define INIT_LIST_HEAD(ptr) \
(ptr)->prev = (ptr); \
} while (0)
-#define list_entry(ptr, type, member) ((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))
+#define list_entry(ptr, type, member) ((type*)((char*)(ptr) - (unsigned long)(&((type*)0)->member)))
#define list_first_entry(ptr, type, member) list_entry((ptr)->next, type, member)
tmp = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); pos = tmp, tmp = list_entry(tmp->member.next, typeof(*tmp), member))
-static inline void _list_add(list_head_t *pnew, list_head_t *prev, list_head_t *next) {
+static inline void _list_add(list_head_t* pnew, list_head_t* prev, list_head_t* next) {
next->prev = pnew;
pnew->next = next;
pnew->prev = prev;
prev->next = pnew;
}
-static inline void list_add(list_head_t *pnew, list_head_t *head) { _list_add(pnew, head, head->next); }
+static inline void list_add(list_head_t* pnew, list_head_t* head) {
+ _list_add(pnew, head, head->next);
+}
-static inline void list_add_tail(list_head_t *pnew, list_head_t *head) { _list_add(pnew, head->prev, head); }
+static inline void list_add_tail(list_head_t* pnew, list_head_t* head) {
+ _list_add(pnew, head->prev, head);
+}
-static inline void _list_del(list_head_t *prev, list_head_t *next) {
+static inline void _list_del(list_head_t* prev, list_head_t* next) {
next->prev = prev;
prev->next = next;
}
-static inline void list_del(list_head_t *entry) {
+static inline void list_del(list_head_t* entry) {
_list_del(entry->prev, entry->next);
entry->prev = NULL;
entry->next = NULL;
}
-static inline void list_del_init(list_head_t *entry) {
+static inline void list_del_init(list_head_t* entry) {
_list_del(entry->prev, entry->next);
INIT_LIST_HEAD(entry);
}
-static inline int list_empty(list_head_t *head) { return head->next == head; }
+static inline int list_empty(list_head_t* head) {
+ return head->next == head;
+}
typedef struct node {
int id;
INIT_LIST_HEAD(&pendH);
for (int i = 0; i < 10; i++) {
- node_t *n = (node_t *)malloc(sizeof(node_t));
+ node_t* n = (node_t*)malloc(sizeof(node_t));
n->id = i;
list_add(&n->list, &allH);
if (n->id % 3 == 0) {
}
}
- list_head_t *pos;
- list_head_t *tmp;
+ list_head_t* pos;
+ list_head_t* tmp;
node_t *p, *p1;
list_for_each_safe(pos, tmp, &allH) {
p = list_entry(pos, node_t, list);
p = list_entry(pos, node_t, pend);
printf("pendH: %d\n", p->id);
}
-}
\ No newline at end of file
+}