11 #include "mm/paging.h"
12 #include "mm/region.h"
26 static void read_mmap_info(struct mb_info
*mbi
)
28 struct mb_mmap
*region
; // current memory region
29 struct mb_mmap
*end
; // end of memory region array
30 region
= (struct mb_mmap
*) mbi
->mmap_addr
;
31 end
= (struct mb_mmap
*) (mbi
->mmap_addr
+ mbi
->mmap_length
);
32 console_printf(get_vterm(0), "Memory map from bootloader, at address %.8X:\n", mbi
->mmap_addr
);
33 console_puts(get_vterm(0), "Range Type\n");
35 if (region
->type
== 1){
36 // This is a free memory region
37 console_set_fcolour(get_vterm(0), COLOR_BRIGHT_WHITE
);
39 console_reset_colour(get_vterm(0));
41 console_printf(get_vterm(0), "%.8X - %.8X %d\n",
42 (unsigned long) region
->base_addr
,
43 (unsigned long) (region
->base_addr
+ region
->length
- 1),
45 if (region
->type
== 1){
46 pmem_init_mark_free(region
->base_addr
, region
->base_addr
+ region
->length
);
49 region
= (struct mb_mmap
*) (((char *) region
) + region
->size
+ 4);
51 console_reset_colour(get_vterm(0));
54 static void read_multiboot_info(struct mb_info
*mbi
)
56 if (mbi
->flags
& MBI_BOOT_LOADER_NAME
){
57 // Bootloader has given us a name. Why not print it?
58 console_printf(get_vterm(0), "Thank you, %s.\n", mbi
->boot_loader_name
);
60 if (mbi
->flags
& MBI_MMAP_XXX
){
61 // read the memory map
63 } else if (mbi
->flags
& MBI_MEM_XXX
){
64 // Use the more basic memory information
65 console_printf(get_vterm(0), "Upper memory (mbi->mem_upper): %d kiB\n", mbi
->mem_upper
);
66 pmem_init_mark_free(KERNEL_PHYS_BASE
, KERNEL_PHYS_BASE
+ mbi
->mem_upper
* 1024);
68 panic("The bootloader gave us no memory information!");
72 // ignore spurious irq 7
73 void spurious_int_7(int vector
, struct interrupt_stack
*is
)
75 //trace("suprious_int_7() called! \n");
79 void read_mb_modules(struct mb_info
*mbi
)
81 // XXX: we're assuming the first 4 MiB is identity-mapped!
82 struct mb_module
*mod
;
84 if (mbi
->flags
& MBI_MODS_XXX
){
85 // find address of first module structure from the multiboot info
86 mod
= (struct mb_module
*) mbi
->mods_addr
;
87 count
= mbi
->mods_count
;
88 for (i
=0; i
<count
; ++i
){
89 // print info about each module
90 trace("Module: %s at 0x%.8X (%d kiB)\n", (char *) mod
->string
, mod
->mod_start
,
91 uldivru(mod
->mod_end
- mod
->mod_start
, 1024));
93 // load only the first module, for now
94 load_elf_module((void *)((KERNEL_VIRT_BASE
- KERNEL_PHYS_BASE
) + mod
->mod_start
), // start_addr
95 mod
->mod_start
, // phys_addr
96 mod
->mod_end
- mod
->mod_start
); // length
101 trace("No multiboot modules found.\n");
104 trace("No multiboot module information.\n");
105 trace("Either the bootloader doesn't support modules,\n");
106 trace("or no modules were loaded.\n");
110 void kmain(uint32_t freemem_base
, struct mb_info
*mbi
, unsigned int magic
)
112 MULTITASKING
= false;
116 // try initializing COM1 for 9600 baud output
117 if (serial_init(&com1
, 1, 9600) == 0){
118 // also send console output to COM1
119 console_serial_enable(get_vterm(0), &com1
);
122 console_set_fcolour(get_vterm(0), COLOR_BRIGHT_WHITE
);
123 console_puts(get_vterm(0), "CommunityOS booting up...\n");
124 console_reset_colour(get_vterm(0));
125 if (magic
!= MB_BOOT_MAGIC
){
126 console_set_fcolour(get_vterm(0), COLOR_BRIGHT_RED
);
127 console_printf(get_vterm(0), "Bootloader gave us an invalid magic number: 0x%.8X\n", magic
);
128 console_reset_colour(get_vterm(0));
130 pmem_init_set_freemem_base(freemem_base
);
131 read_multiboot_info(mbi
);
132 console_printf(get_vterm(0), "Free memory: %d MiB\n", uldivru(pmem_get_size(), 1024 * 1024));
134 console_puts(get_vterm(0), "Loading GDT and task register...\n");
136 console_puts(get_vterm(0), "Loading IDT...\n");
139 //console_puts(get_vterm(0), "Triggering interrupt 0x80 to test the IDT...\n");
140 //asm volatile ("int $0x80" ::: "cc");
141 console_puts(get_vterm(0), "Installing page fault handler...\n");
142 set_pagefault_handler();
144 console_puts(get_vterm(0), "Configuring PIT...\n");
146 console_puts(get_vterm(0), "Getting CPUID information...\n");
155 counter
= read_cpu_timestamp();
157 counter
= (read_cpu_timestamp() - counter
);
158 console_printf(get_vterm(0), "parse_mp_tables took 0x%llX ticks\n", counter
);
160 counter
= read_cpu_timestamp();
162 counter
= (read_cpu_timestamp() - counter
);
163 console_printf(get_vterm(0), "parse_smbios took 0x%llX ticks\n", counter
);
166 console_puts(get_vterm(0), "Initializing Real-Time Clock...\n");
169 console_puts(get_vterm(0), "Initializing keyboard driver...\n");
172 //console_set_fcolour(get_vterm(0), COLOR_BRIGHT_GREEN);
173 //console_puts(get_vterm(0), "Bootup complete!\n"); no it's not!
174 //console_reset_colour(get_vterm(0));
175 interrupt_set_handler(irq_to_int(7), spurious_int_7
);
177 // Now, in order for the console code to continue working,
178 // it needs 0xB8000 mapped somewhere sensible.
179 // NOTE: the whole screen at 0xB8000 fits one page
180 // (80 * 25 * 2 = 4000)
182 if (alloc_kvpages(1, 1, &vram_vaddr
) < 1){
183 panic("Cannot allocate (alloc_kvpages) virtual page for vram");
185 map_mem(0xB8000, vram_vaddr
, 1, PTE_PRESENT
| PTE_WRITABLE
);
186 // Tell the console driver where the new VRAM virtual-address is
187 console_change_vram((uint16_t *) vram_vaddr
);
192 struct addr_space
*aspace
;
193 struct vm_region
*vm_r
;
194 aspace
= addr_space_new();
195 vm_r
= vm_region_new_physical(aspace
, 0x10000000, 1);
196 addr_space_switch(aspace
);
197 asm volatile ("movl 0x10000800,%%eax" ::: "eax");
203 read_mb_modules(mbi
);
205 //create_task((uint32_t)kmain_task, "Kernel Task", PRIO_HIGH);
206 //create_task((uint32_t)kshell_task, "Kernel Shell", PRIO_NORMAL);
210 // enter an idle loop, so we can see the effects of interrupts
216 void kmain_task(void)
218 critical_state_t crs
= critical_enter();
219 console_printf(get_vterm(0), "task_mgr: kmain_task() has been called \n");
220 console_printf(get_vterm(1), "Hey, this is virtual terminal 1\n");
223 // test the device interface
224 struct chardev
*tty2
= chardev_get(4, 2);
226 chardev_write(tty2
, "Waay it's tty2!\n", 16);
228 trace("chardev_get(4, 2) failed\n");
232 change_task_priority(active_id
, PRIO_VERYLOW
);