/*function to clear the screen after booting*/ #include "multiboot.h" /* Check if the bit BIT in FLAGS is set. */ #define CHECK_FLAG(flags,bit) ((flags) & (1 << (bit))) /* Some screen stuff. */ /* The number of columns. */ #define COLUMNS 80 /* The number of lines. */ #define LINES 24 /* The attribute of an character. */ #define ATTRIBUTE 7 /* The video memory address. */ #define VIDEO 0xB8000 /* Variables. */ /* Save the X position. */ static int xpos; /* Save the Y position. */ static int ypos; /* Point to the video memory. */ static volatile unsigned char *video; static void cls (void); static void itoa (char *buf, int base, int d); static void putchar (int c); void printf (const char *format, ...); void main(unsigned long magic, unsigned long addr) { multiboot_info_t *mbi; /*clear the screen*/ cls(); printf("MemOS: Welcome***System Memory is:\n"); /*intialize mbi to address stored in ebx*/ mbi = (multiboot_info_t *) addr; /*declare variables*/ memory_map_t *base_addr_mmap; memory_map_t *length_mmap; unsigned long base_addr_abs; unsigned long length_abs; unsigned long base; unsigned long len; unsigned type; unsigned long total; if(CHECK_FLAG(mbi->flags, 6)) { memory_map_t *mmap; /*key attributes of memory map from multiboot info struct*/ base_addr_mmap = (memory_map_t *)mbi->mmap_addr; length_mmap = (memory_map_t *)mbi->mmap_length; base_addr_abs = mbi->mmap_addr; length_abs = mbi->mmap_length; /*looping through memory map*/ for(mmap = base_addr_mmap; (unsigned long)mmap < base_addr_abs + length_abs; mmap = (memory_map_t *)((unsigned long)mmap + mmap->size + sizeof(mmap->size))) { base = (unsigned)mmap->base_addr_high; base << 32; base |= (unsigned)mmap->base_addr_low; len = (unsigned)mmap->length_high; len << 32; len |= (unsigned)mmap->length_low; type = (unsigned)mmap->type; total += len; printf("Address Range["); printf("0x%x", base); printf(":"); printf("0x%x", base + len); printf("] status: "); printf("%d\n", type); } xpos = 0; ypos = 6; printf(" "); unsigned long total_print = (total >> 20); xpos = 35; ypos = 0; printf("%d MBs", total_print); } } /* Clear the screen and initialize VIDEO, XPOS and YPOS. */ void cls (void) { int i; video = (unsigned char *) VIDEO; for (i = 0; i < COLUMNS * LINES * 2; i++) *(video + i) = 0; xpos = 0; ypos = 0; } /* Convert the integer D to a string and save the string in BUF. If BASE is equal to 'd', interpret that D is decimal, and if BASE is equal to 'x', interpret that D is hexadecimal. */ static void itoa (char *buf, int base, int d) { char *p = buf; char *p1, *p2; unsigned long ud = d; int divisor = 10; /* If %d is specified and D is minus, put `-' in the head. */ if (base == 'd' && d < 0) { *p++ = '-'; buf++; ud = -d; } else if (base == 'x') divisor = 16; /* Divide UD by DIVISOR until UD == 0. */ do { int remainder = ud % divisor; *p++ = (remainder < 10) ? remainder + '0' : remainder + 'a' - 10; } while (ud /= divisor); /* Terminate BUF. */ *p = 0; /* Reverse BUF. */ p1 = buf; p2 = p - 1; while (p1 < p2) { char tmp = *p1; *p1 = *p2; *p2 = tmp; p1++; p2--; } } /* Put the character C on the screen. */ static void putchar (int c) { if (c == '\n' || c == '\r') { newline: xpos = 0; ypos++; if (ypos >= LINES) ypos = 0; return; } *(video + (xpos + ypos * COLUMNS) * 2) = c & 0xFF; *(video + (xpos + ypos * COLUMNS) * 2 + 1) = ATTRIBUTE; xpos++; if (xpos >= COLUMNS) goto newline; } /* Format a string and print it on the screen, just like the libc function printf. */ void printf (const char *format, ...) { char **arg = (char **) &format; int c; char buf[20]; arg++; while ((c = *format++) != 0) { if (c != '%') putchar (c); else { char *p; c = *format++; switch (c) { case 'd': case 'u': case 'x': itoa (buf, c, *((int *) arg++)); p = buf; goto string; break; case 's': p = *arg++; if (! p) p = "(null)"; string: while (*p) putchar (*p++); break; default: putchar (*((int *) arg++)); break; } } } }