2011-01-16 04:01:19 +03:00
|
|
|
#include <system.h>
|
2011-01-19 09:04:27 +03:00
|
|
|
#include <multiboot.h>
|
2011-01-16 04:01:19 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* memcpy
|
|
|
|
* Copy from source to destination. Assumes that
|
|
|
|
* source and destination are not overlapping.
|
|
|
|
*/
|
2011-01-18 03:22:48 +03:00
|
|
|
void *
|
2011-01-16 04:01:19 +03:00
|
|
|
memcpy(
|
2011-01-18 03:22:48 +03:00
|
|
|
void * restrict dest,
|
|
|
|
const void * restrict src,
|
|
|
|
size_t count
|
2011-01-16 04:01:19 +03:00
|
|
|
) {
|
2011-01-18 03:22:48 +03:00
|
|
|
size_t i;
|
|
|
|
unsigned char *a = dest;
|
|
|
|
const unsigned char *b = src;
|
|
|
|
for ( i = 0; i < count; ++i ) {
|
|
|
|
a[i] = b[i];
|
2011-01-16 04:01:19 +03:00
|
|
|
}
|
|
|
|
return dest;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* memset
|
|
|
|
* Set `count` bytes to `val`.
|
|
|
|
*/
|
2011-01-18 03:22:48 +03:00
|
|
|
void *
|
2011-01-16 04:01:19 +03:00
|
|
|
memset(
|
2011-01-18 03:22:48 +03:00
|
|
|
void *b,
|
|
|
|
int val,
|
|
|
|
size_t count
|
2011-01-16 04:01:19 +03:00
|
|
|
) {
|
2011-01-18 03:22:48 +03:00
|
|
|
size_t i;
|
|
|
|
unsigned char * dest = b;
|
|
|
|
for ( i = 0; i < count; ++i ) {
|
|
|
|
dest[i] = (unsigned char)val;
|
2011-01-16 04:01:19 +03:00
|
|
|
}
|
2011-01-18 03:22:48 +03:00
|
|
|
return b;
|
2011-01-16 04:01:19 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* memsetw
|
|
|
|
* Set `count` shorts to `val`.
|
|
|
|
*/
|
|
|
|
unsigned short *
|
|
|
|
memsetw(
|
|
|
|
unsigned short *dest,
|
|
|
|
unsigned short val,
|
|
|
|
int count
|
2011-01-21 08:21:32 +03:00
|
|
|
) {
|
2011-01-16 04:01:19 +03:00
|
|
|
int i;
|
|
|
|
i = 0;
|
|
|
|
for ( ; i < count; ++i ) {
|
|
|
|
dest[i] = val;
|
|
|
|
}
|
|
|
|
return dest;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* strlen
|
|
|
|
* Returns the length of a given `str`.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
strlen(
|
|
|
|
const char *str
|
|
|
|
) {
|
|
|
|
int i = 0;
|
|
|
|
while (str[i] != (char)0) {
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* inportb
|
|
|
|
* Read from an I/O port.
|
|
|
|
*/
|
|
|
|
unsigned char
|
|
|
|
inportb(
|
|
|
|
unsigned short _port
|
|
|
|
) {
|
|
|
|
unsigned char rv;
|
|
|
|
__asm__ __volatile__ ("inb %1, %0" : "=a" (rv) : "dN" (_port));
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* outportb
|
|
|
|
* Write to an I/O port.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
outportb(
|
|
|
|
unsigned short _port,
|
|
|
|
unsigned char _data
|
|
|
|
) {
|
|
|
|
__asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data));
|
|
|
|
}
|
|
|
|
|
2011-01-21 08:21:32 +03:00
|
|
|
struct multiboot *
|
|
|
|
copy_multiboot(
|
|
|
|
struct multiboot *mboot_ptr
|
|
|
|
) {
|
|
|
|
struct multiboot *new_header = (struct multiboot *)kmalloc(sizeof(struct multiboot));
|
|
|
|
memcpy(new_header, mboot_ptr, sizeof(struct multiboot));
|
|
|
|
return new_header;
|
2011-01-16 19:56:44 +03:00
|
|
|
}
|
|
|
|
|
2011-01-21 08:21:32 +03:00
|
|
|
void
|
|
|
|
dump_multiboot(
|
|
|
|
struct multiboot *mboot_ptr
|
|
|
|
) {
|
|
|
|
resettextcolor();
|
|
|
|
kprintf("MULTIBOOT header at 0x%x:\n", (uintptr_t)mboot_ptr);
|
2011-01-19 09:04:27 +03:00
|
|
|
settextcolor(7,0);
|
2011-01-21 08:21:32 +03:00
|
|
|
kprintf("Flags : 0x%x ", mboot_ptr->flags);
|
|
|
|
kprintf("Mem Lo: 0x%x ", mboot_ptr->mem_lower);
|
|
|
|
kprintf("Mem Hi: 0x%x ", mboot_ptr->mem_upper);
|
2011-01-19 22:00:03 +03:00
|
|
|
kprintf("Boot d: 0x%x\n", mboot_ptr->boot_device);
|
2011-01-21 08:21:32 +03:00
|
|
|
kprintf("cmdlin: 0x%x ", mboot_ptr->cmdline);
|
|
|
|
kprintf("Mods : 0x%x ", mboot_ptr->mods_count);
|
|
|
|
kprintf("Addr : 0x%x ", mboot_ptr->mods_addr);
|
2011-01-19 22:00:03 +03:00
|
|
|
kprintf("Syms : 0x%x\n", mboot_ptr->num);
|
2011-01-21 08:21:32 +03:00
|
|
|
kprintf("Syms : 0x%x ", mboot_ptr->size);
|
|
|
|
kprintf("Syms : 0x%x ", mboot_ptr->addr);
|
|
|
|
kprintf("Syms : 0x%x ", mboot_ptr->shndx);
|
2011-01-19 22:00:03 +03:00
|
|
|
kprintf("MMap : 0x%x\n", mboot_ptr->mmap_length);
|
2011-01-21 08:21:32 +03:00
|
|
|
kprintf("Addr : 0x%x ", mboot_ptr->mmap_addr);
|
|
|
|
kprintf("Drives: 0x%x ", mboot_ptr->drives_length);
|
|
|
|
kprintf("Addr : 0x%x ", mboot_ptr->drives_addr);
|
2011-01-19 22:00:03 +03:00
|
|
|
kprintf("Config: 0x%x\n", mboot_ptr->config_table);
|
2011-01-21 08:21:32 +03:00
|
|
|
kprintf("Loader: 0x%x ", mboot_ptr->boot_loader_name);
|
|
|
|
kprintf("APM : 0x%x ", mboot_ptr->apm_table);
|
|
|
|
kprintf("VBE Co: 0x%x ", mboot_ptr->vbe_control_info);
|
2011-01-19 22:00:03 +03:00
|
|
|
kprintf("VBE Mo: 0x%x\n", mboot_ptr->vbe_mode_info);
|
2011-01-21 08:21:32 +03:00
|
|
|
kprintf("VBE In: 0x%x ", mboot_ptr->vbe_mode);
|
|
|
|
kprintf("VBE se: 0x%x ", mboot_ptr->vbe_interface_seg);
|
|
|
|
kprintf("VBE of: 0x%x ", mboot_ptr->vbe_interface_off);
|
2011-01-19 22:00:03 +03:00
|
|
|
kprintf("VBE le: 0x%x\n", mboot_ptr->vbe_interface_len);
|
2011-01-19 09:04:27 +03:00
|
|
|
resettextcolor();
|
|
|
|
kprintf("Started with: %s\n", (char *)mboot_ptr->cmdline);
|
|
|
|
kprintf("Booted from: %s\n", (char *)mboot_ptr->boot_loader_name);
|
2011-01-19 22:00:03 +03:00
|
|
|
kprintf("%dkB lower memory\n", mboot_ptr->mem_lower);
|
|
|
|
kprintf("%dkB higher memory ", mboot_ptr->mem_upper);
|
|
|
|
int mem_mb = mboot_ptr->mem_upper / 1024;
|
|
|
|
kprintf("(%dMB)\n", mem_mb);
|
2011-01-22 10:57:54 +03:00
|
|
|
kprintf("Found %d module(s).\n", mboot_ptr->mods_count);
|
|
|
|
if (mboot_ptr->mods_count > 0) {
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < mboot_ptr->mods_count; ++i ) {
|
|
|
|
uint32_t module_start = *((uint32_t*)mboot_ptr->mods_addr + 8 * i);
|
|
|
|
uint32_t module_end = *(uint32_t*)(mboot_ptr->mods_addr + 8 * i + 4);
|
|
|
|
kprintf("Module %d is at 0x%x:0x%x\n", i+1, module_start, module_end);
|
|
|
|
}
|
|
|
|
}
|
2011-01-21 08:21:32 +03:00
|
|
|
}
|
2011-01-19 22:00:03 +03:00
|
|
|
|
2011-01-21 08:21:32 +03:00
|
|
|
/*
|
|
|
|
* kernel entry point
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
main(struct multiboot *mboot_ptr) {
|
2011-01-22 10:38:25 +03:00
|
|
|
if (mboot_ptr->mods_count > 0) {
|
2011-01-22 10:57:54 +03:00
|
|
|
uint32_t module_start = *((uint32_t*)mboot_ptr->mods_addr);
|
|
|
|
uint32_t module_end = *(uint32_t*)(mboot_ptr->mods_addr+4);
|
|
|
|
kmalloc_startat(module_end);
|
2011-01-22 10:38:25 +03:00
|
|
|
}
|
2011-01-22 10:57:54 +03:00
|
|
|
//mboot_ptr = copy_multiboot(mboot_ptr);
|
2011-01-22 06:48:17 +03:00
|
|
|
|
|
|
|
gdt_install(); /* Global descriptor table */
|
|
|
|
idt_install(); /* IDT */
|
|
|
|
isrs_install(); /* Interrupt service requests */
|
|
|
|
irq_install(); /* Hardware interrupt requests */
|
|
|
|
init_video(); /* VGA driver */
|
2011-01-21 08:21:32 +03:00
|
|
|
timer_install();
|
|
|
|
keyboard_install();
|
2011-01-22 09:29:04 +03:00
|
|
|
paging_install(mboot_ptr->mem_upper);
|
2011-01-22 08:57:08 +03:00
|
|
|
heap_install();
|
|
|
|
|
2011-01-22 09:29:04 +03:00
|
|
|
settextcolor(12,0);
|
|
|
|
kprintf("[%s %s]\n", KERNEL_UNAME, KERNEL_VERSION_STRING);
|
|
|
|
dump_multiboot(mboot_ptr);
|
2011-01-22 08:57:08 +03:00
|
|
|
|
2011-01-16 04:01:19 +03:00
|
|
|
return 0;
|
|
|
|
}
|