上一篇仅是晒了图,但没有给代码,这一片把代码晒出来。

/*   multiboot2.h - Multiboot 2 header file. */
/*   Copyright (C) 1999,2003,2007,2008,2009,2010  Free Software Foundation, Inc.
*
*  Permission is hereby granted, free of charge, to any person obtaining a copy
*  of this software and associated documentation files (the "Software"), to
*  deal in the Software without restriction, including without limitation the
*  rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
*  sell copies of the Software, and to permit persons to whom the Software is
*  furnished to do so, subject to the following conditions:
*
*  The above copyright notice and this permission notice shall be included in
*  all copies or substantial portions of the Software.
*
*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL ANY
*  DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
*  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
*  IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#ifndef MULTIBOOT_HEADER
#define MULTIBOOT_HEADER 1

/*  How many bytes from the start of the file we search for the header. */
#define MULTIBOOT_SEARCH                        32768
#define MULTIBOOT_HEADER_ALIGN                  8

/*  The magic field should contain this. */
#define MULTIBOOT2_HEADER_MAGIC                 0xe85250d6

/*  This should be in %eax. */
#define MULTIBOOT2_BOOTLOADER_MAGIC             0x36d76289

/*  Alignment of multiboot modules. */
#define MULTIBOOT_MOD_ALIGN                     0x00001000

/*  Alignment of the multiboot info structure. */
#define MULTIBOOT_INFO_ALIGN                    0x00000008

/*  Flags set in the 'flags' member of the multiboot header. */

#define MULTIBOOT_TAG_ALIGN                  8
#define MULTIBOOT_TAG_TYPE_END               0
#define MULTIBOOT_TAG_TYPE_CMDLINE           1
#define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME  2
#define MULTIBOOT_TAG_TYPE_MODULE            3
#define MULTIBOOT_TAG_TYPE_BASIC_MEMINFO     4
#define MULTIBOOT_TAG_TYPE_BOOTDEV           5
#define MULTIBOOT_TAG_TYPE_MMAP              6
#define MULTIBOOT_TAG_TYPE_VBE               7
#define MULTIBOOT_TAG_TYPE_FRAMEBUFFER       8
#define MULTIBOOT_TAG_TYPE_ELF_SECTIONS      9
#define MULTIBOOT_TAG_TYPE_APM               10
#define MULTIBOOT_TAG_TYPE_EFI32             11
#define MULTIBOOT_TAG_TYPE_EFI64             12
#define MULTIBOOT_TAG_TYPE_SMBIOS            13
#define MULTIBOOT_TAG_TYPE_ACPI_OLD          14
#define MULTIBOOT_TAG_TYPE_ACPI_NEW          15
#define MULTIBOOT_TAG_TYPE_NETWORK           16
#define MULTIBOOT_TAG_TYPE_EFI_MMAP          17
#define MULTIBOOT_TAG_TYPE_EFI_BS            18
#define MULTIBOOT_TAG_TYPE_EFI32_IH          19
#define MULTIBOOT_TAG_TYPE_EFI64_IH          20
#define MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR    21

#define MULTIBOOT_HEADER_TAG_END  0
#define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST  1
#define MULTIBOOT_HEADER_TAG_ADDRESS  2
#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS  3
#define MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS  4
#define MULTIBOOT_HEADER_TAG_FRAMEBUFFER  5
#define MULTIBOOT_HEADER_TAG_MODULE_ALIGN  6
#define MULTIBOOT_HEADER_TAG_EFI_BS        7
#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI32  8
#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64  9
#define MULTIBOOT_HEADER_TAG_RELOCATABLE  10

#define MULTIBOOT_ARCHITECTURE_I386  0
#define MULTIBOOT_ARCHITECTURE_MIPS32  4
#define MULTIBOOT_HEADER_TAG_OPTIONAL 1

#define MULTIBOOT_LOAD_PREFERENCE_NONE 0
#define MULTIBOOT_LOAD_PREFERENCE_LOW 1
#define MULTIBOOT_LOAD_PREFERENCE_HIGH 2

#define MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED 1
#define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2

#ifndef ASM_FILE

typedef unsigned char           multiboot_uint8_t;
typedef unsigned short          multiboot_uint16_t;
typedef unsigned int            multiboot_uint32_t;
typedef unsigned long long      multiboot_uint64_t;

struct multiboot_header
{
/*  Must be MULTIBOOT_MAGIC - see above. */
multiboot_uint32_t magic;

/*  ISA */
multiboot_uint32_t architecture;

/*  Total header length. */
multiboot_uint32_t header_length;

/*  The above fields plus this one must equal 0 mod 2^32. */
multiboot_uint32_t checksum;
};

struct multiboot_header_tag
{
multiboot_uint16_t type;
multiboot_uint16_t flags;
multiboot_uint32_t size;
};

struct multiboot_header_tag_information_request
{
multiboot_uint16_t type;
multiboot_uint16_t flags;
multiboot_uint32_t size;
multiboot_uint32_t requests[0];
};

struct multiboot_header_tag_address
{
multiboot_uint16_t type;
multiboot_uint16_t flags;
multiboot_uint32_t size;
multiboot_uint32_t header_addr;
multiboot_uint32_t load_addr;
multiboot_uint32_t load_end_addr;
multiboot_uint32_t bss_end_addr;
};

struct multiboot_header_tag_entry_address
{
multiboot_uint16_t type;
multiboot_uint16_t flags;
multiboot_uint32_t size;
multiboot_uint32_t entry_addr;
};

struct multiboot_header_tag_console_flags
{
multiboot_uint16_t type;
multiboot_uint16_t flags;
multiboot_uint32_t size;
multiboot_uint32_t console_flags;
};

struct multiboot_header_tag_framebuffer
{
multiboot_uint16_t type;
multiboot_uint16_t flags;
multiboot_uint32_t size;
multiboot_uint32_t width;
multiboot_uint32_t height;
multiboot_uint32_t depth;
};

struct multiboot_header_tag_module_align
{
multiboot_uint16_t type;
multiboot_uint16_t flags;
multiboot_uint32_t size;
};

struct multiboot_header_tag_relocatable
{
multiboot_uint16_t type;
multiboot_uint16_t flags;
multiboot_uint32_t size;
multiboot_uint32_t min_addr;
multiboot_uint32_t max_addr;
multiboot_uint32_t align;
multiboot_uint32_t preference;
};

struct multiboot_color
{
multiboot_uint8_t red;
multiboot_uint8_t green;
multiboot_uint8_t blue;
};

struct multiboot_mmap_entry
{
multiboot_uint64_t addr;
multiboot_uint64_t len;
#define MULTIBOOT_MEMORY_AVAILABLE              1
#define MULTIBOOT_MEMORY_RESERVED               2
#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE       3
#define MULTIBOOT_MEMORY_NVS                    4
#define MULTIBOOT_MEMORY_BADRAM                 5
multiboot_uint32_t type;
multiboot_uint32_t zero;
};
typedef struct multiboot_mmap_entry multiboot_memory_map_t;

struct multiboot_tag
{
multiboot_uint32_t type;
multiboot_uint32_t size;
};

struct multiboot_tag_string
{
multiboot_uint32_t type;
multiboot_uint32_t size;
char string[0];
};

struct multiboot_tag_module
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t mod_start;
multiboot_uint32_t mod_end;
char cmdline[0];
};

struct multiboot_tag_basic_meminfo
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t mem_lower;
multiboot_uint32_t mem_upper;
};

struct multiboot_tag_bootdev
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t biosdev;
multiboot_uint32_t slice;
multiboot_uint32_t part;
};

struct multiboot_tag_mmap
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t entry_size;
multiboot_uint32_t entry_version;
struct multiboot_mmap_entry entries[0];
};

struct multiboot_vbe_info_block
{
multiboot_uint8_t external_specification[512];
};

struct multiboot_vbe_mode_info_block
{
multiboot_uint8_t external_specification[256];
};

struct multiboot_tag_vbe
{
multiboot_uint32_t type;
multiboot_uint32_t size;

multiboot_uint16_t vbe_mode;
multiboot_uint16_t vbe_interface_seg;
multiboot_uint16_t vbe_interface_off;
multiboot_uint16_t vbe_interface_len;

struct multiboot_vbe_info_block vbe_control_info;
struct multiboot_vbe_mode_info_block vbe_mode_info;
};

struct multiboot_tag_framebuffer_common
{
multiboot_uint32_t type;
multiboot_uint32_t size;

multiboot_uint64_t framebuffer_addr;
multiboot_uint32_t framebuffer_pitch;
multiboot_uint32_t framebuffer_width;
multiboot_uint32_t framebuffer_height;
multiboot_uint8_t framebuffer_bpp;
#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB     1
#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT     2
multiboot_uint8_t framebuffer_type;
multiboot_uint16_t reserved;
};

struct multiboot_tag_framebuffer
{
struct multiboot_tag_framebuffer_common common;

union
{
 struct
 {
   multiboot_uint16_t framebuffer_palette_num_colors;
   struct multiboot_color framebuffer_palette[0];
 };
 struct
 {
   multiboot_uint8_t framebuffer_red_field_position;
   multiboot_uint8_t framebuffer_red_mask_size;
   multiboot_uint8_t framebuffer_green_field_position;
   multiboot_uint8_t framebuffer_green_mask_size;
   multiboot_uint8_t framebuffer_blue_field_position;
   multiboot_uint8_t framebuffer_blue_mask_size;
 };
};
};

struct multiboot_tag_elf_sections
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t num;
multiboot_uint32_t entsize;
multiboot_uint32_t shndx;
char sections[0];
};

struct multiboot_tag_apm
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint16_t version;
multiboot_uint16_t cseg;
multiboot_uint32_t offset;
multiboot_uint16_t cseg_16;
multiboot_uint16_t dseg;
multiboot_uint16_t flags;
multiboot_uint16_t cseg_len;
multiboot_uint16_t cseg_16_len;
multiboot_uint16_t dseg_len;
};

struct multiboot_tag_efi32
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t pointer;
};

struct multiboot_tag_efi64
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint64_t pointer;
};

struct multiboot_tag_smbios
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint8_t major;
multiboot_uint8_t minor;
multiboot_uint8_t reserved[6];
multiboot_uint8_t tables[0];
};

struct multiboot_tag_old_acpi
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint8_t rsdp[0];
};

struct multiboot_tag_new_acpi
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint8_t rsdp[0];
};

struct multiboot_tag_network
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint8_t dhcpack[0];
};

struct multiboot_tag_efi_mmap
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t descr_size;
multiboot_uint32_t descr_vers;
multiboot_uint8_t efi_mmap[0];
};

struct multiboot_tag_efi32_ih
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t pointer;
};

struct multiboot_tag_efi64_ih
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint64_t pointer;
};

struct multiboot_tag_load_base_addr
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t load_base_addr;
};

#endif /*  ! ASM_FILE */

#endif /*  ! MULTIBOOT_HEADER */
bits 32

section .text


_start:
	jmp mystart
align 8
header_start:
	dd 0xe85250d6
	dd 0x0
	dd header_end - header_start
	dd - (0xe85250d6 + 0x0 + (header_end - header_start))
	
add_tag_start:
	dw 0x2
	dw 0x0
	dd add_tag_end - add_tag_start
	dd header_start
	dd _start
	dd 0x0
	dd 0x0
add_tag_end:

entry_add_tag_start:
	dw 0x3
	dw 0x1
	dd entry_add_tag_end - entry_add_tag_start
	dd mystart
entry_add_tag_end:
align 8

framebuffer_tag_start:
	dw 0x5
	dw 0x1
	dd framebuffer_tag_end - framebuffer_tag_start
	dd 800
	dd 600
	dd 16
framebuffer_tag_end:
align 8

	dw 0x0
	dw 0x0
	dd 0x8
header_end:
align 8

bits 32
[section .text]
mystart:
	mov esp, _stack_start
	push 0
	popf
	cli	
	
	push ebx
	push eax
extern _kernel_main
	call _kernel_main
	add esp, 8

	jmp $
	
times 1024 dw 0
_stack_start:

times 1024 dw 0
_new_stack:



#define halt() __asm__("hlt")

#define delay(count) ({ \
__asm__(" \
	1: \
	decl %0; \
	jnz 1b" \
	::"c"(count)); \
})

typedef char * va_list;

#ifdef  __cplusplus
#define _ADDRESSOF(v)   ( &reinterpret_cast<const char &>(v) )
#else
#define _ADDRESSOF(v)   ( &(v) )
#endif

#define _INTSIZEOF(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )

#define _crt_va_start(ap,v)  ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )
#define _crt_va_arg(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define _crt_va_end(ap)      ( ap = (va_list)0 )

#define Test_va_start _crt_va_start 
#define Test_va_arg _crt_va_arg
#define Test_va_end _crt_va_end

#define ZEROPAD    1       
#define SIGN   2       
#define PLUS   4       
#define SPACE  8       
#define LEFT   16      
#define SPECIAL    32     
#define LARGE  64      

int _div(long* n,unsigned base);
static inline int isdigit(int ch);
static int skip_atoi(const char **s);
static char *Test_number(char *str, long num, int base, int size, int precision, int type);
int Test_vsprintf(char *buf, const char *fmt, va_list args);
int strnlen(const char * s, int precision);    
int sprintf(char *buf, const char *fmt, ...);



/*  kernel.c - the C part of the kernel */
/*  Copyright (C) 1999, 2010  Free Software Foundation, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "multiboot2.h"

/*  Macros. */

/*  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;

/*  Forward declarations. */
void cmain (unsigned long magic, unsigned long addr);
static void cls (void);
static void itoa (char *buf, int base, int d);
static void putchar (int c);
void printf (const char *format, ...);


unsigned short *videoaddr;
void fillbox(short color, int x0, int y0, int x1, int y1);
void print_ascii (short color, int x, int y, char *font);
void makefont16 (short color, int x, int y, short *font);
void print_gb2312(short color, int x, int y, unsigned char *str);

void mypaint(unsigned int eax, unsigned int ebx);




/*  Check if MAGIC is valid and print the Multiboot information structure
pointed by ADDR. */
void
kernel_main (unsigned long magic, unsigned long addr)
{
struct multiboot_tag *tag;
unsigned size;

/*  Clear the screen. */
cls ();

/*  Am I booted by a Multiboot-compliant boot loader? */
if (magic != MULTIBOOT2_BOOTLOADER_MAGIC)
{
printf ("Invalid magic number: 0x%x\n", (unsigned) magic);
return;
}

if (addr & 7)
{
printf ("Unaligned mbi: 0x%x\n", addr);
return;
}

size = *(unsigned *) addr;
printf ("Announced mbi size 0x%x\n", size);
for (tag = (struct multiboot_tag *) (addr + 8);
tag->type != MULTIBOOT_TAG_TYPE_END;
tag = (struct multiboot_tag *) ((multiboot_uint8_t *) tag
				+ ((tag->size + 7) & ~7)))
{
printf ("Tag 0x%x, Size 0x%x\n", tag->type, tag->size);
switch (tag->type)
{
case MULTIBOOT_TAG_TYPE_CMDLINE:
printf ("Command line = %s\n",
((struct multiboot_tag_string *) tag)->string);
break;
case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME:
printf ("Boot loader name = %s\n",
((struct multiboot_tag_string *) tag)->string);
break;
case MULTIBOOT_TAG_TYPE_MODULE:
printf ("Module at 0x%x-0x%x. Command line %s\n",
((struct multiboot_tag_module *) tag)->mod_start,
((struct multiboot_tag_module *) tag)->mod_end,
((struct multiboot_tag_module *) tag)->cmdline);
break;
case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO:
printf ("mem_lower = %uKB, mem_upper = %uKB\n",
((struct multiboot_tag_basic_meminfo *) tag)->mem_lower,
((struct multiboot_tag_basic_meminfo *) tag)->mem_upper);
break;
case MULTIBOOT_TAG_TYPE_BOOTDEV:
printf ("Boot device 0x%x,%u,%u\n",
((struct multiboot_tag_bootdev *) tag)->biosdev,
((struct multiboot_tag_bootdev *) tag)->slice,
((struct multiboot_tag_bootdev *) tag)->part);
break;
case MULTIBOOT_TAG_TYPE_MMAP:
{
multiboot_memory_map_t *mmap;

printf ("mmap\n");

for (mmap = ((struct multiboot_tag_mmap *) tag)->entries;
(multiboot_uint8_t *) mmap
< (multiboot_uint8_t *) tag + tag->size;
mmap = (multiboot_memory_map_t *)
((unsigned long) mmap
+ ((struct multiboot_tag_mmap *) tag)->entry_size))
printf (" base_addr = 0x%x%x,"
" length = 0x%x%x, type = 0x%x\n",
(unsigned) (mmap->addr >> 32),
(unsigned) (mmap->addr & 0xffffffff),
(unsigned) (mmap->len >> 32),
(unsigned) (mmap->len & 0xffffffff),
(unsigned) mmap->type);
}
break;
case MULTIBOOT_TAG_TYPE_FRAMEBUFFER:
{
multiboot_uint32_t color;
unsigned i;
struct multiboot_tag_framebuffer *tagfb
= (struct multiboot_tag_framebuffer *) tag;
void *fb = (void *) (unsigned long) tagfb->common.framebuffer_addr;
videoaddr = (short *)fb;

switch (tagfb->common.framebuffer_type)
{
case MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED:
{
unsigned best_distance, distance;
struct multiboot_color *palette;

palette = tagfb->framebuffer_palette;

color = 0;
best_distance = 4*256*256;

for (i = 0; i < tagfb->framebuffer_palette_num_colors; i++)
{
distance = (0xff - palette[i].blue)
 * (0xff - palette[i].blue)
 + palette[i].red * palette[i].red
 + palette[i].green * palette[i].green;
if (distance < best_distance)
 {
   color = i;
   best_distance = distance;
 }
}
}
break;

case MULTIBOOT_FRAMEBUFFER_TYPE_RGB:
color = ((1 << tagfb->framebuffer_blue_mask_size) - 1)
<< tagfb->framebuffer_blue_field_position;
break;

case MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT:
color = '\\' | 0x0100;
break;

default:
color = 0xffffffff;
break;
}

for (i = 0; i < tagfb->common.framebuffer_width
&& i < tagfb->common.framebuffer_height; i++)
{
switch (tagfb->common.framebuffer_bpp)
{
case 8:
{
multiboot_uint8_t *pixel = fb
 + tagfb->common.framebuffer_pitch * i + i;
*pixel = color;
}
break;
case 15:
case 16:
{
multiboot_uint16_t *pixel
 = fb + tagfb->common.framebuffer_pitch * i + 2 * i;
*pixel = color;
}
break;
case 24:
{
multiboot_uint32_t *pixel
 = fb + tagfb->common.framebuffer_pitch * i + 3 * i;
*pixel = (color & 0xffffff) | (*pixel & 0xff000000);
}
break;

case 32:
{
multiboot_uint32_t *pixel
 = fb + tagfb->common.framebuffer_pitch * i + 4 * i;
*pixel = color;
}
break;
}
}
break;
}

}
}
tag = (struct multiboot_tag *) ((multiboot_uint8_t *) tag
		   + ((tag->size + 7) & ~7));
printf ("Total mbi size 0x%x\n", (unsigned) tag - addr);


mypaint(magic, addr);

halt();

}

/*  Clear the screen and initialize VIDEO, XPOS and YPOS. */
static 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, *p2;
int pad0 = 0, pad = 0;

c = *format++;
if (c == '0')
{
pad0 = 1;
c = *format++;
}

if (c >= '0' && c <= '9')
{
pad = c - '0';
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:
for (p2 = p; *p2; p2++);
for (; p2 < p + pad; p2++)
putchar (pad0 ? '0' : ' ');
while (*p)
putchar (*p++);
break;

default:
putchar (*((int *) arg++));
break;
}
}
}
}

void fillbox(short color, int x0, int y0, int x1, int y1) {
	short *myfb = videoaddr;
	int xsize = 800;
	int x, y;
	for (y = 0; y <= y1 - y0; y++) {
		for (x = 0; x <= x1 - x0; x++) {
			myfb[x0 + x + (y0 + y) * xsize] = color;
		}
	}
	return;
}


void print_ascii (short color, int x, int y, char *font) {
	short *myfb = videoaddr;
	int xsize = 800;
	char d;
	short *p;
	int i;
	for (i = 0; i < 16; i++){
		p = myfb + (y + i) * xsize + x;
		d = font[i];
		if ((d & 0x80) != 0) {p[0] = color;}
		if ((d & 0x40) != 0) {p[1] = color;}
		if ((d & 0x20) != 0) {p[2] = color;}
		if ((d & 0x10) != 0) {p[3] = color;}
		if ((d & 0x08) != 0) {p[4] = color;}
		if ((d & 0x04) != 0) {p[5] = color;}
		if ((d & 0x02) != 0) {p[6] = color;}
		if ((d & 0x01) != 0) {p[7] = color;}
	}
	return;
}

void makefont16 (short color, int x, int y, short *font) {
	short *myfb = videoaddr;
	int xsize = 800;
	short d;
	short *p;
	int i;
	for (i = 0; i < 16; i++){
		p = myfb + (y + i) * xsize + x;
		d = font[i];
		if ((d & 0x80) != 0) {p[0] = color;}
		if ((d & 0x40) != 0) {p[1] = color;}
		if ((d & 0x20) != 0) {p[2] = color;}
		if ((d & 0x10) != 0) {p[3] = color;}
		if ((d & 0x08) != 0) {p[4] = color;}
		if ((d & 0x04) != 0) {p[5] = color;}
		if ((d & 0x02) != 0) {p[6] = color;}
		if ((d & 0x01) != 0) {p[7] = color;}
		if ((d & 0x8000) != 0) {p[8] = color;}
		if ((d & 0x4000) != 0) {p[9] = color;}
		if ((d & 0x2000) != 0) {p[10] = color;}
		if ((d & 0x1000) != 0) {p[11] = color;}
		if ((d & 0x800) != 0) {p[12] = color;}
		if ((d & 0x400) != 0) {p[13] = color;}
		if ((d & 0x200) != 0) {p[14] = color;}
		if ((d & 0x100) != 0) {p[15] = color;}
	}
	return;
}

void print_gb2312(short color, int x, int y, unsigned char *str) {
	extern short font[0x8000];
	extern char myfont[0x1000];
	int i = 0, j = 0;
	unsigned char a, b;
	unsigned int offset;
	while (str[i] != 0) {
		if (str[i] < 0x80) {
			a = str[i];
			print_ascii (color, x + j, y, myfont + a * 16);
			if (str[i + 1] == 0)
				break;
			i++;
			j += 8;
		} else {	
			a = str[i] - 0xa0;
			b = str[i + 1] - 0xa0;
			offset = ((a - 1) * 94 + (b - 1)) * 16;
			makefont16 (color, x + j , y, font + offset);
			i += 2;
			j += 16;
		}
	}
	return;
}


int sprintf(char *buf, const char *fmt, ...)
{
    va_list args;
    int val = 1;
    Test_va_start(args, fmt);
	Test_vsprintf(buf, fmt, args);
    Test_va_end(args);
    return val;
}



int _div(long* n,unsigned base)
{
     int __res; 
         __res = ((unsigned long) *n) % (unsigned) base; 
         *n = ((unsigned long) *n) / (unsigned) base; 
         return __res;
}

#define do_div(n,base)   _div(&n,base)


static inline int isdigit(int ch)
{
    return (ch >= '0') && (ch <= '9');
}

static int skip_atoi(const char **s)
{
    int i = 0;

    while (isdigit(**s))
        i = i * 10 + *((*s)++) - '0';
    return i;
}

static char *Test_number(char *str, long num, int base, int size, int precision, int type)
{
    char c, sign, tmp[66];
    const char *digits = "0123456789abcdefghijklmnopqrstuvwxyz";
    int i;

    if (type & LARGE)
        digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    if (type & LEFT)
        type &= ~ZEROPAD;
    if (base < 2 || base > 36)
        return 0;
    c = (type & ZEROPAD) ? '0' : ' ';
    sign = 0;
    if (type & SIGN) {
        if (num < 0) {
            sign = '-';
            num = -num;
            size--;
        } else if (type & PLUS) {
            sign = '+';
            size--;
        } else if (type & SPACE) {
            sign = ' ';
            size--;
        }
    }
    if (type & SPECIAL) {
        if (base == 16)
            size -= 2;
        else if (base == 8)
            size--;
    }
    i = 0;
    if (num == 0)
    {
        tmp[i++] = '0';
    }
    else
    {
        while (num != 0)
        {
            tmp[i++] = digits[do_div(num, base)];
        }
    }

    if (i > precision)
        precision = i;
    size -= precision;
    if (!(type & (ZEROPAD + LEFT)))
        while (size-- > 0)
            *str++ = ' ';
    if (sign)
        *str++ = sign;
    if (type & SPECIAL) {
        if (base == 8)
            *str++ = '0';
        else if (base == 16) {
            *str++ = '0';
            *str++ = digits[33];
        }
    }
    if (!(type & LEFT))
        while (size-- > 0)
            *str++ = c;
    while (i < precision--)
        *str++ = '0';
    while (i-- > 0)
        *str++ = tmp[i];
    while (size-- > 0)
        *str++ = ' ';
    return str;
 }


int Test_vsprintf(char *buf, const char *fmt, va_list args)
{
    int len;
    unsigned long num;
    int i, base;
    char *str;
    const char *s;

    int flags;      

    int field_width;   
    int precision;    
    int qualifier;      

    for (str = buf; *fmt; ++fmt) {
        if (*fmt != '%') {
            *str++ = *fmt;
            continue;
        }


        flags = 0;
          repeat:
        ++fmt;      
        switch (*fmt) {
        case '-':
            flags |= LEFT;
            goto repeat;
        case '+':
            flags |= PLUS;
            goto repeat;
        case ' ':
            flags |= SPACE;
            goto repeat;
        case '#':
            flags |= SPECIAL;
            goto repeat;
        case '0':
            flags |= ZEROPAD;
            goto repeat;
        }


        field_width = -1;
        if (isdigit(*fmt))
            field_width = skip_atoi(&fmt);
        else if (*fmt == '*') {
            ++fmt;

            field_width = Test_va_arg(args, int);
            if (field_width < 0) {
                field_width = -field_width;
                flags |= LEFT;
            }
        }


        precision = -1;
        if (*fmt == '.') {
            ++fmt;
            if (isdigit(*fmt))
                precision = skip_atoi(&fmt);
            else if (*fmt == '*') {
                ++fmt;

                precision = Test_va_arg(args, int);
            }
            if (precision < 0)
                precision = 0;
        }


        qualifier = -1;
        if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') {
            qualifier = *fmt;
            ++fmt;
        }


        base = 10;

        switch (*fmt) {
        case 'c':
            if (!(flags & LEFT))
                while (--field_width > 0)
                    *str++ = ' ';
            *str++ = (unsigned char)Test_va_arg(args, int);
            while (--field_width > 0)
                *str++ = ' ';
            continue;

        case 's':
            s = Test_va_arg(args, char *);
            len = strnlen(s, precision);

            if (!(flags & LEFT))
                while (len < field_width--)
                    *str++ = ' ';
            for (i = 0; i < len; ++i)
                *str++ = *s++;
            while (len < field_width--)
                *str++ = ' ';
            continue;

        case 'p':
            if (field_width == -1) {
                field_width = 2 * sizeof(void *);
                flags |= ZEROPAD;
            }
            str = Test_number(str,
                     (unsigned long)Test_va_arg(args, void *), 16,
                     field_width, precision, flags);
            continue;

        case 'n':
            if (qualifier == 'l') {
                long *ip = Test_va_arg(args, long *);
                *ip = (str - buf);
            } else {
                int *ip = Test_va_arg(args, int *);
                *ip = (str - buf);
            }
            continue;

        case '%':
            *str++ = '%';
            continue;

        case 'o':
            base = 8;
            break;

        case 'X':
            flags |= LARGE;
        case 'x':
            base = 16;
            break;

        case 'd':
        case 'i':
            flags |= SIGN;
        case 'u':
            break;

        default:
            *str++ = '%';
            if (*fmt)
                *str++ = *fmt;
            else
                --fmt;
            continue;
        }
        if (qualifier == 'l')
            num = Test_va_arg(args, unsigned long);
        else if (qualifier == 'h') {
            num = (unsigned short)Test_va_arg(args, int);
            if (flags & SIGN)
                num = (short)num;
        } else if (flags & SIGN)
            num = Test_va_arg(args, int);
        else
            num = Test_va_arg(args, unsigned int);
        str = Test_number(str, num, base, field_width, precision, flags);
    }
    *str = '\0';
    return str - buf;
}        

int strnlen(const char * s, int precision) {
	int len = 0;
	while (*s++ != 0) {
		len++;
	}
	return len;
}

void mypaint(unsigned int eax, unsigned int ebx) {
	fillbox(0x051d, 0, 0, 799, 599);
	char buf[0x100], buf0[0x100];
	sprintf(buf, "eax = 0x%x ebx = 0x%x buf 的地址是 0x%x,显存地址是 0x%x", eax, ebx, buf, videoaddr);
	print_gb2312(0xffff, 0, 0, buf);
	int i, j;
	for(i = 0; i < 600; i += 16) {
		fillbox(0xc618, 16 + i, 16, 32 + i, 31);
	}
	for(i = 0; i < 500; i += 16) {
		fillbox(0x0000, 16 + i, 32, 32 + i, 47);
	}
	for(i = 0; i < 400; i += 16) {
		fillbox(0xf800, 16 + i, 48, 32 + i, 63);
	}
	for(i = 0; i < 300; i += 16) {
		fillbox(0x07e0, 16 + i, 64, 32 + i, 79);
	}	
	for(i = 0; i < 200; i += 16) {
		fillbox(0xfd79, 16 + i, 80, 32 + i, 95);
	}
	for(i = 0; i < 100; i += 16) {
		fillbox(0x001f, 16 + i, 96, 32 + i, 111);
	}
	sprintf(buf, "我爱你Snialos!!!");
	print_gb2312(0xff80, 320, 128, buf);
	i = 0;
	while (++i) {
		sprintf(buf, "0x%x", i);
		print_gb2312(0x0000, 0, 128, buf);
//		delay(0x10000);
		fillbox(0x051d, 0, 128, 64, 143);
//		delay(0x1000);
	}
	return;
}
CC=gcc
LD=ld
OBJ = boot.o kernel.o myfont1.o myfont.o

all: kernel

.s.o:
	nasm -felf -o $@ $<
.c.o:

	$(CC) -c -o $@ $<

kernel: $(OBJ)
	$(LD) -Ttext 0x100000 -o $@ $^

default:	
	make all
	objcopy -I pe-i386 -O elf32-i386 kernel
	winimage ..\mybochs\andows.img kernel /i /h /y
 
run: 
	make default
	bochs -q -f ..\mybochs\bochsrc.bxrc
clean:
	del boot.o
	del kernel.o
	del kernel
	del ..\mybochs\*.lock

猜你喜欢

转载自blog.csdn.net/weixin_39410618/article/details/84825655