cynix

x86 UNIX-like OS
git clone git://git.2f30.org/cynix
Log | Files | Refs | README | LICENSE

main.c (3624B)


      1 /*
      2  *  core/main.c
      3  *
      4  *  Copyright (C) 2009 stateless
      5  */
      6 
      7 #include <tty.h>
      8 #include <rtc.h>
      9 #include <keyboard.h>
     10 #include <common.h>
     11 #include <x86.h>
     12 #include <idt.h>
     13 #include <gdt.h>
     14 #include <pic.h>
     15 #include <string.h>
     16 #include <multiboot.h>
     17 #include <elf.h>
     18 #include <mm.h>
     19 #include <heap.h>
     20 #include <tss.h>
     21 #include <syscall.h>
     22 #include <errno.h>
     23 #include <ext2.h>
     24 #include <serial.h>
     25 #include <pci.h>
     26 #include <rtl8139.h>
     27 #include <version.h>
     28 
     29 extern struct fs_node_t *vfs_root;
     30 extern struct task_t *current_task;
     31 extern unsigned long int initial_esp;
     32 extern unsigned long int addr_info;
     33 extern uint8_t multiboot_header[0];
     34 extern uint8_t __code[0];
     35 extern uint8_t __data[0];
     36 extern uint8_t __bss[0];
     37 extern uint8_t __end[0];
     38 
     39 multiboot_info_t *info_boot = NULL;
     40 multiboot_header_t *mb_header = NULL;
     41 uint32_t initrd_base;
     42 uint32_t initrd_end;
     43 
     44 static void syscall(void);
     45 static void move_kernel_stack(uint32_t new_stack_addr);
     46 
     47 int
     48 main(void)
     49 {
     50 	int ret;
     51 
     52 	serial_init();
     53 
     54 	ccurr_col(BLACK, WHITE);
     55 	clear_scr();
     56 
     57 	info_boot = (multiboot_info_t *) addr_info;
     58 	mb_header = (multiboot_header_t *)multiboot_header;
     59 	if (mb_header->magic != MULTIBOOT_HEADER_MAGIC)
     60 		panic("invalid multiboot header number");
     61 	if (!(info_boot->flags & (1 << 3)))
     62 		panic("modules can't be located!");
     63 	if (!info_boot->mods_count)
     64 		panic("can't locate initrd, modules count is 0!");
     65 
     66 	initrd_base = *(uint32_t *)info_boot->mods_addr;
     67 	initrd_end = *(uint32_t *)(info_boot->mods_addr + 4);
     68 
     69 	if (prepare_elf() < 0)
     70 		info("could not locate either the symbol table or the string table!\n");
     71 
     72 	initialize_gdt();
     73 	remap_pic();
     74 	initialize_idt();
     75 	init_rtc(100);
     76 	initialize_keyboard();
     77 	sti();
     78 
     79 	if ((ret = init_mm()) < 0)
     80 		kerror(-ret);
     81 	if ((ret = init_vm()) < 0)
     82 		kerror(-ret);
     83 
     84 	move_kernel_stack(0xe0000000);
     85 
     86 	if (!pci_init()) {
     87 		pci_enumerate();
     88 		if (rtl8139_init() < 0)
     89 			info("failed to initialize the rtl8139\n");
     90 	} else {
     91 		info("pci failed to init\n");
     92 	}
     93 
     94 	ext2_mount((char *)initrd_base);
     95 
     96 	if (strlen(REVISION) > 0)
     97 		printf("Revision: %s\n", REVISION);
     98 	printf("Built on %s by %s on host %s\n\n", DATE, USER, HOST);
     99 	printf("Press F12 to drop into the kernel debugger.");
    100 	update_cursor(cursor_y, cursor_x);
    101 	if ((ret = init_tss()) < 0)
    102 		kerror(-ret);
    103 	kick_tss();
    104 	panic("WTF?");
    105 	return 0xdeadc0de;
    106 }
    107 
    108 static void
    109 move_kernel_stack(uint32_t new_stack_addr)
    110 {
    111 	uint32_t curr_esp, i, *ptr, offset;
    112 
    113 	GET_ESP(curr_esp);
    114 	offset = (initial_esp - curr_esp);
    115 	memcpy((void *)(new_stack_addr - offset), (const void *)curr_esp, offset);
    116 	ptr = (uint32_t *)new_stack_addr;
    117 	for (i = 0; i < offset; i += 4) {
    118 		--ptr;
    119 		if (*ptr < initial_esp && *ptr > curr_esp)
    120 			*ptr = *ptr + (new_stack_addr - initial_esp);
    121 	}
    122 	initial_esp = new_stack_addr;
    123 	new_stack_addr -= offset;
    124 	PUT_ESP(new_stack_addr);
    125 }
    126 
    127 uint32_t
    128 get_fnv_hash(const char *buf, size_t count, uint32_t hash)
    129 {
    130 	static uint32_t fnv_offset_basis = 2166136261;
    131 	static uint32_t fnv_prime = 16777619;
    132 
    133 	hash = (!hash) ? fnv_offset_basis : hash;
    134 	while (count--) {
    135 		hash ^= *buf++;
    136 		hash *= fnv_prime;
    137 	}
    138 
    139 	return hash;
    140 }
    141 
    142 __attribute__ ((unused)) static void
    143 syscall(void)
    144 {
    145 	char buf[256];
    146 	uint32_t hash = 0;
    147 	int fd, oldfd;
    148 	ssize_t ret;
    149 
    150 	oldfd = sys_open("/a.out", O_RDONLY, 0);
    151 	if (oldfd < 0)
    152 		kerror(-oldfd);
    153 	if ((fd = sys_dup(oldfd)) < 0)
    154 		kerror(-fd);
    155 	sys_close(oldfd);
    156 	do {
    157 		ret = sys_read(fd, buf, 255);
    158 		if (ret < 0) kerror(-ret);
    159 		if (!ret) break;
    160 		buf[ret] = '\0';
    161 		hash = get_fnv_hash(buf, ret, hash);
    162 		ret = sys_write(fd, buf, ret);
    163 		if (ret < 0) kerror(-ret);
    164 	} while (1);
    165 	serial_dump("hash = 0x%08lx\n", hash);
    166 	sys_close(fd);
    167 }
    168