endif
CFLAGS := -g -c -fno-builtin -m32 -DBUILDER='"$(shell whoami)"' -std=gnu11
+CFLAGS += -Wall
+CFLAGS += -Werror
+CFLAGS += -Wshadow
# 指示编译器禁止生成位置无关代码
CFLAGS += -fno-pic
# 指示编译器在生成目标文件时不省略函数调用栈帧指针: frame pointer
} break;
case 1: { // IO APIC
uint8_t ioapic_id = ptr[2];
- uint8_t reserved = ptr[3];
+ // 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("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);
+ // uint16_t reserved = *(uint16_t*)(ptr + 2);
uint32_t apic_addr = *(uint32_t*)(ptr + 4);
printk("Virtual APIC addr %08x\n", apic_addr);
} break;
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_framebuffer* fb = 0;
struct multiboot_tag_elf_sections* elf = 0;
boot_params.e820map.map_cnt = 0;
strlcpy(boot_params.bootloader, ((struct multiboot_tag_string*)tag)->string,
sizeof(boot_params.bootloader));
break;
- case MULTIBOOT_TAG_TYPE_MODULE:
+ case MULTIBOOT_TAG_TYPE_MODULE: {
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);
printk("\n");
}
#endif
- break;
+ } break;
case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO:
mminfo = (struct multiboot_tag_basic_meminfo*)tag;
// KB to Bytes
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);
+ 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;
case MULTIBOOT_TAG_TYPE_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:
+ case MULTIBOOT_TAG_TYPE_ACPI_OLD: {
extern void parse_acpi(void*);
- parse_acpi(tag);
+ parse_acpi((void*)tag);
break;
+ }
case MULTIBOOT_TAG_TYPE_ACPI_NEW:
printk("ACPI new\n");
break;
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 mode) {
// 设置并执行实模式代码以调用 VBE 函数 0x4F01
// 返回指向 VBE 模式信息的指针
return NULL;
ahci_port_t* port = hba->ports + i;
uint32_t sata_status = port->sata_status;
uint32_t sata_det = (sata_status >> 0) & 0x0F; // device detection
- uint32_t sata_spd = (sata_status >> 4) & 0x0F; // current interface speed
+ // uint32_t sata_spd = (sata_status >> 4) & 0x0F; // current interface speed
uint32_t sata_ipm = (sata_status >> 8) & 0x0F; // interface power management
if (sata_det != 3) {
}
switch (port->signature) {
- case SATA_SIGNATURE_ATA:
+ case SATA_SIGNATURE_ATA: {
extern void init_sata_device(ahci_hba_t * hba, ahci_port_t * port, int index);
init_sata_device(hba, port, i);
printk("SATA device detected at port %d\n", i);
-
- break;
+ } break;
case SATA_SIGNATURE_ATAPI:
printk("SATAPI device detected\n");
break;
// 1. 若为0,就认为没有IDE
// 2. 等到status的BSY位清除
// 3. 等到status的DRQ位或ERR位设置
-u16 identify[256];
+
void ata_send_read_identify_cmd(int drv) {
}
extern unsigned int IDE_CHL1_CTL_BASE;
// 《AT Attachment 8 - ATA/ATAPI Command Set》
-void ide_ata_init() {
+void ide_ata_init(uint16_t* identify) {
printk("IDE %04X %04X %04X %04X\n", IDE_CHL0_CMD_BASE, IDE_CHL1_CMD_BASE, IDE_CHL0_CTL_BASE, IDE_CHL1_CTL_BASE);
for (int i = 0; i < MAX_IDE_DRIVE_CNT; i++) {
int drvid = i;
// Bit 2: 1 表示设备支持应急电源降级。
// Bit 1: 1 表示设备支持硬件重置。
// Bit 0: 1 表示设备支持软重置。
- uint16_t devtype = identify[ATA_IDENT_DEVTYPE];
+ // uint16_t devtype = identify[ATA_IDENT_DEVTYPE];
// printk("device type %04X\n", devtype);
void ide_read_partions() {
for (int i = 0; i < MAX_IDE_DRIVE_CNT; i++) {
ide_drive_t* drv = ide_drives + i;
- int channel = i >> 1;
+ // int channel = i >> 1;
if (0 == drv->present) {
continue;
outb((pos >> 16) & 0xFF, REG_LBAH(drvid));
// 等待硬盘READY
- while (inb(REG_STATUS(drvid)) & ATA_STATUS_RDY == 0) {
+ while ((inb(REG_STATUS(drvid)) & ATA_STATUS_RDY) == 0) {
nop();
}
outb((pos >> 8) & 0xFF, REG_LBAM(drvid));
outb((pos >> 16) & 0xFF, REG_LBAH(drvid));
- while (inb(REG_STATUS(drvid)) & ATA_STATUS_RDY == 0) {
+ while ((inb(REG_STATUS(drvid)) & ATA_STATUS_RDY) == 0) {
nop();
}
// wake_up(&rdwq);
up(&sem);
}
+
+ return 0;
}
int cnsl_read(char* buf, size_t count) {
- unsigned long flags;
+ // unsigned long flags;
assert(count > 0);
int cnt = 0;
uint8_t ata_pci_bus_status();
-void ide_ata_init();
+uint16_t ata_identify[256];
+
+void ide_ata_init(uint16_t* identify);
+
void ide_init() {
memset(ide_pci_controller, 0, sizeof(ide_pci_controller[0]) * NR_IDE_CONTROLLER);
init_pci_controller(0x0101);
// 读IDE 硬盘的identity
- ide_ata_init();
+ ide_ata_init(ata_identify);
}
ide_drive_t* ide_get_drive(dev_t dev) {
};
// TODO 改造成环形缓冲区
-uint8_t scan_code;
+uint8_t kbd_scan_code;
void kbd_bh_handler(void* arg) {
- kbd_debug(scan_code);
- if (0x80 & scan_code) { // break code
+ kbd_debug(kbd_scan_code);
+ if (0x80 & kbd_scan_code) { // break code
return;
}
- uint8_t inx = scan_code & 0xFF;
+ uint8_t inx = kbd_scan_code & 0xFF;
char ch = kbd_char_tbl[inx];
cnsl_kbd_write(ch);
}
void kbd_handler(unsigned int irq, pt_regs_t* regs, void* dev_id) {
- scan_code = inb(0x60);
+ kbd_scan_code = inb(0x60);
add_irq_bh_handler(kbd_bh_handler, NULL);
}
pci->hdr_type &= PCI_HDRTYPE_MASK;
for (i = 0; i < BARS_CNT; ++i) {
- cmd = PCI_CMD(bus, dev, devfn, PCI_BAR0 + i * 4);
+ cmd = PCI_CMD(bus, dev, devfn, (PCI_BAR0 + i * 4));
pci->bars[i] = pci_read_config_long(cmd);
}
}
pci_device_t* pci_find_device(unsigned int vendor, unsigned int device) {
- int i;
list_head_t* p;
pci_device_t* pci = 0;
void dump_pci_dev() {
list_head_t* p;
- int i;
list_for_each(p, &pci_devs) {
pci_device_t* pci = list_entry(p, pci_device_t, list);
uint32_t timeout = 1000000;
while (timeout--) {
- if ((port->cmd_issue) & (1 << 0) == 0) {
+ if (((port->cmd_issue) & (1 << 0)) == 0) {
break;
}
// 不启用中断也仍然会设置
}
bbuffer_t* getblk(dev_t dev, uint64_t block, uint32_t size) {
+ uint32_t iflags;
assert(size == 1024 || size == 2048 || size == 4096);
// 暂时先只支持hard disk
int retry = 0;
again:
- uint32_t iflags;
irq_save(iflags);
// 先尝试从hash里分配
ext2_inode_t ext2_root_inode;
-static ext2_inode_t boot_inode;
-static ext2_inode_t krnl_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);
void* ext2_free_block(void* blk) {
kmem_cache_free(ext2_block_cache, blk);
+ return blk;
}
void* ext2_alloc_inode() {
printd("read_inode %u\n", ino);
- unsigned int in; // inode number
+ // unsigned int in; // inode number
unsigned int gn; // group number
unsigned int gi; // inode index in group
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)
+#define s(x) ((x) + ((x) >> PAGE_HASH_BITS))
return s(i + index) & (PAGE_HASH_SIZE - 1);
#undef s
}
inode->i_size = 0;
inode->i_mapping = &inode->i_as;
inode->i_mapping->a_inode = inode;
- inode->i_mapping->pages;
+ // inode->i_mapping->pages;
INIT_LIST_HEAD(&inode->i_mapping->pages);
inode->i_mapping->a_ops = 0;
return inode;
mnt = alloc_vfsmount(name);
ret = type->read_super(type, flags, name, data, mnt);
+ assert(ret == 0);
assert(mnt->mnt_sb != 0);
assert(mnt->mnt_root != 0);
#include <types.h>
int get_unused_fd() {
- int fd;
+ // int fd;
task_files_t* files = &(current->files);
for (int i = 0; i < NR_TASK_OPEN_CNT; i++) {
// *dentry = dentry_get(tmp_mnt->mnt_root);
// }
// }
+ return 0;
}
int path_walk(const char* path, namei_t* ni) {
return inode;
}
-static sb_operations_t ramfs_ops = {
- // .alloc_inode = ramfs_alloc_inode,
-};
+// static sb_operations_t ramfs_ops = {
+// // .alloc_inode = ramfs_alloc_inode,
+// };
int ramfs_fill_super_cb(superblock_t* sb, void* data) {
int err = 0;
add->next = fs;
fs->next = 0;
- return 0;
+
+ return ret;
}
fs_type_t* vfs_find_filesystem(const char* name) {
pos += bytes;
}
-end:
+ // end:
up(&inode->i_sem);
*p_pos = pos;
void* kzalloc(size_t size, gfp_t gfpflags);
void kfree(void* addr);
-extern char etext, edata, end;
+// extern char etext, edata, end;
#define cli() asm volatile("cli")
#define sti() asm volatile("sti")
// 之前加载的被复制到1MB以下的ap_gdt需要废弃,因为它已经在内核地址空间之外了
// 虽然他们是同一个ap_gdt
extern char ap_gdtr;
- asm("lgdt ap_gdtr");
+ // 最简单的写 asm("lgdt ap_gdtr"); 但是c编译器不通过
+ asm("lgdt %0" ::"m"(ap_gdtr));
// tss
// AP 暂时不服务用户特权级 所以暂时用不到tss
void _system_monitor() {
//
extern volatile uint64_t jiffies;
- extern volatile uint64_t hpet_ticks; // jiffies 和 hpet_ticks 是同一个东西
+ // extern volatile uint64_t hpet_ticks; // jiffies 和 hpet_ticks 是同一个东西
printlxy(MPL_IRQ, MPO_HPET, "HPET: %lu", jiffies);
//
- extern volatile uint8_t scan_code;
+ extern volatile uint8_t kbd_scan_code;
extern volatile uint64_t kbd_irq_cnt;
- printlxy(MPL_IRQ, MPO_KEYBOARD, "KBD: %02x %lu", scan_code, kbd_irq_cnt);
+ printlxy(MPL_IRQ, MPO_KEYBOARD, "KBD: %02x %lu", kbd_scan_code, kbd_irq_cnt);
//
printlxy(MPL_IRQ, MPO_AP_CLOCK, "AP: %lu", ap_lapic_ticks);
// TPR是软件的“计划”,ISR是硬件的“现状”,而PPR是综合二者得出的“当前执行标准”。
// 内核只能通过设置TPR来影响PPR
uint32_t PPR = lapic->read(LAPIC_PPR);
+ printk("TPR: %08x PPR: %08x\n", TPR, PPR);
}
static ioapic_map_t ioapic_map;
ioapic_rte_write(IOAPIC_RTE(i), IOAPIC_RTE_MASK | irq);
}
- uint32_t rcba_phys_base = (uint32_t)get_rcba_paddr();
+ // uint32_t rcba_phys_base = (uint32_t)get_rcba_paddr();
ioapic_enable();
- uint64_t dst_cpuid = 0;
+ // uint64_t dst_cpuid = 0;
extern irq_chip_t ioapic_chip;
#if 1
void detect_cpu() {
cpuid_regs_t r;
- unsigned short int cpu_sn[6]; // serial number
- int i;
+ // unsigned short int cpu_sn[6]; // serial number
+ // int i;
/**********************Get CPU Name********************************/
char cpu_name[13];
assert(ehdr != 0);
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);
+ assert(strncmp(ELFMAG, (char*)ehdr->e_ident, sizeof(ELFMAG) - 1) == 0);
printk("Elf Entry: %08x\n", ehdr->e_entry);
int i, j;
irq_save(flags);
current->state = TASK_EXITING;
- task_t* t = current;
+ // task_t* t = current;
irq_restore(flags);
tsk->cr3 = (uint32_t)page2pa(alloc_one_page(0));
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);
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];
- unsigned long dpde = 0;
+ for (int i = 0; i < PAGE_PDE_CNT; ++i) {
+ // unsigned long spde = (unsigned long)pde_src[i];
+ // unsigned long dpde = 0;
if (i >= get_npde(PAGE_OFFSET)) {
pde_dst[i] = pde_src[i];
mask &= inb(PIC_MASTER_IMR);
outb_p(mask, PIC_MASTER_IMR);
}
+ return 0;
}
int disable_i8259_irq(unsigned int irq) {
mask |= inb(PIC_MASTER_IMR);
outb(mask, PIC_MASTER_IMR);
}
+ return 0;
}
void mask_ack_i8259_irq(unsigned int irq) {
}
void ack_i8259_irq(unsigned int irq) {
- unsigned char mask = 0;
+ // unsigned char mask = 0;
if (irq & 8) // Slave
{
}
void context_switch(task_t* prev, task_t* next) {
- unsigned long eax, ebx, ecx, edx, esi, edi;
+ unsigned long /*eax,*/ ebx, ecx, edx, esi, edi;
asm volatile(
"pushfl;"
"pushl %%ebp;"
}
int sysc_test() {
+ return 0;
}
int sysc_pause() {
+ return 0;
}
int sysc_debug(unsigned int v) {
{
// TODO支持带多层目录的fe_name
- namei_t ni;
+ // namei_t ni;
const char* path = fe_name;
const int flags = O_CREAT | O_APPEND;
#define bufsz 5223
vfs_generic_file_read(&file, buf, bufsz, &file.f_pos);
#endif
- for (int i = 0; i < bufsz; i++) {
- printk("%c", buf[i]);
+ for (int k = 0; k < bufsz; k++) {
+ printk("%c", buf[k]);
}
printk("\n");
}
extern uint8_t ring3_page_begin;
paddr_t ring3_page_addr = (paddr_t)&ring3_page_begin; // 不在内核空间的物理地址
- paddr_t ring3_stack_top = ring3_page_addr + PAGE_SIZE;
+ // paddr_t ring3_stack_top = ring3_page_addr + PAGE_SIZE;
vaddr_t ring3_page_vaddr = 0x08000000; // 指定的ring3的虚拟地址
vaddr_t ring3_stack_top_vaddr = PAGE_OFFSET - 0x100000;
#include <syscall.h>
int exit(int status) {
syscall1(SYSC_EXIT, status);
+ return 0;
}
char* strcat(char* dest, const char* src) {
char* tmp = dest;
- while (*dest)
+ while (*dest) {
dest++;
- while (*dest++ = *src++)
- ;
+ }
+ // while (*dest++ = *src++)
+ // ;
+ while (1) {
+ *dest = *src;
+ dest++;
+ src++;
+ if (*dest == 0) {
+ break;
+ }
+ }
return tmp;
}
void* memcpy(void* dest, const void* src, size_t size) {
}
char* itoa(char* s, int n) {
- int i = 0;
char* p = 0;
if (n & 0x80000000) {
s++;
p--;
}
+
+ return s;
}
char* i64tou(char* s, uint64_t n) {
i = strlen(s);
}
itou(s + i, n & 0xFFFFFFFF);
+ return s;
}
char* itou(char* s, unsigned int n) {
- char c;
char* p = s;
do {
s++;
p--;
}
+ return s;
}
char* _itoo(char* s, uint64_t n, int bgn) {
#include <syscall.h>
int wait(unsigned long pid) {
syscall1(SYSC_WAIT, pid);
+ return 0;
}
// 由于只有在构建buddy system的时候才会用到
// 所以这里就简单实现
void* alloc_from_bootmem(unsigned long size, char* title) {
+ unsigned long free_pfn = 0;
+ unsigned long bgn_pfn = 0;
+ unsigned long end_pfn = 0;
+
void* region = NULL;
unsigned long pfn_cnt = PFN_UP(size);
find_next_block:
// 先找到第一个空闲的pfn
- unsigned long free_pfn = pbd->max_pfn;
+ free_pfn = pbd->max_pfn;
for (unsigned long pfn = search_bgn_pfn; pfn < pbd->max_pfn; pfn++) {
if (bootmem_page_state(pfn) == BOOTMEM_PAGE_FREE) {
free_pfn = pfn;
}
// 检验接下来是否有足够的size
- unsigned long bgn_pfn = free_pfn;
- unsigned long end_pfn = bgn_pfn + pfn_cnt;
+ bgn_pfn = free_pfn;
+ end_pfn = bgn_pfn + pfn_cnt;
// printk("free_pfn: %d end_pfn:%d max_pfn:%d \n", free_pfn, end_pfn, pbd->max_pfn);
#include <task.h>
#include <types.h>
-extern char etext, edata, end;
+// extern char etext, edata, end;
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)));
}
// 分配一个页表
- pte_t* 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...");
}
pde_t* pde = page_dir + npde;
// 如果是因为PDE被写保护
- if (*pde & PDE_RW == 0) {
+ if (((*pde) & PDE_RW) == 0) {
// 1. 分配一个页表
unsigned long newtbl = (unsigned long)page2va(alloc_one_page(0));
assert(newtbl != 0);
pte_t* pte = page_tbl + npte;
// 如果PTE的位置被写保护
- if (*pte & PTE_RW == 0) {
+ if (((*pte) & PTE_RW) == 0) {
// 1. 分配一个页表
unsigned long newaddr = (unsigned long)page2va(alloc_one_page(0));
assert(newaddr != 0);
assert(pgd != 0);
pde_t pde = pgd[npde];
- assert(pde & PAGE_P == PAGE_P);
+ assert(((pde)&PAGE_P) == PAGE_P);
pte_t* pgt = (pte_t*)pa2va(PAGE_ALIGN(pde));
pte_t pte = pgt[npte];
*(.text)
*(.sysexit) /* last */
}
- etext = .;
+ _etext = .;
/* 后续节的物理地址(也就是 LMA: Load Memory Address 加载内存地址)会根据 .text 节的自动计算,不用再每个都写一遍 AT 指令了 */
data = .;
*(.data)
}
- edata = .;
+ _edata = .;
.bss : ALIGN(0x1000)
bss = .;
*(.bss);
}
- ebss = .;
+ _ebss = .;
- end = .;
+ /* end = .; */
_end = .;
kernel_end = .;