不知道这样算不算保护模式下的图形模式

好了先是晒图吧

这里只晒代码了,编译方法和环境搭建过程还是请参考我之前的文章好了,不过觉得自己还真的是切换到了图形模式,只是不懂得怎样调色,还请高手回复帮忙吧(有很多的代码是没有用到的,只是懒得删除罢了!kernel.c就只是从https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html#Examples粘贴过来的,蓝色的部分真正的改正过,也是关键的部分,其余大家可以不看)。multiboot2.h从网站上下载。

boot.s


.extern _kernel_main, _string
.global _put_char

_start:

    jmp _begin
.align 8

header_start: 
    .int 0xe85250d6
    .int 0x0
    .int header_end - header_start
    .int -(0xe85250d6 + 0x0 + (header_end - header_start))

add_tag_start:    
    .word 0x2
    .word 0x0
    .int add_tag_end - add_tag_start
    .int header_start
    .int _start
    .int 0x0
    .int 0x0    
add_tag_end:

entry_add_tag_start:
    .word 0x3
    .word 0x1
    .int entry_add_tag_end - entry_add_tag_start
    .int _begin
entry_add_tag_end:    
.align 8

framebuffer_tag_start:
            .short 0x5
            .short 0x1
            .long framebuffer_tag_end - framebuffer_tag_start
            .long 1024
            .long 768
            .long 32
framebuffer_tag_end:
.align 8

    .word 0x0
    .word 0
    .int 8
header_end:

.align 8


_begin: 

    mov $stack_start, %esp
    pushl $0
    popf 
    cli 

    push %ebx
    push %eax
    call _kernel_main
2:    
    hlt
    jmp 2b
    
.align 8
_put_char: # void print (char str);

    push %es
    push %eax
    push %esi
    mov $0x18, %eax
    mov %eax, %es
    mov (_scr_loc), %esi
    mov 0x10(%esp), %al
    mov $0xc, %ah
    movw %ax, %es: (%esi)
    inc %esi
    inc %esi
    cmp $2000, %esi
    jne next0
    xor %esi, %esi
next0:
    mov %esi, (_scr_loc)
    pop %esi
    pop %eax
    pop %es

    ret

idtr:
    .word 0
    .int 0
gdtr:
    .word 4 * 8 - 1
    .int gdt_start

.align 8

gdt_start:
    .quad 0x0000000000000000
    .quad 0x00c09a100000ffff
    .quad 0x00c092000000ffff
    .quad 0x00c0920b80000002
    
    
gdt_end:

.align 8


_position: .int 0;
_scr_loc: .int 0;


.comm stack, 0x100
.align (4 << 10)
stack_start:

kernel.c

#include "multiboot2.h"
     
#define COLUMNS                 80
#define LINES                   24
#define ATTRIBUTE               7
#define VIDEO                   0xB8000

static int xpos;
static int ypos;
static volatile unsigned char *video;
 
int kernel_main (unsigned int magic, unsigned int addr) ;
static void cls (void);
static void itoa (char *buf, int base, int d);
static void putchar (int c);
void printf (const char *format, ...);


int scr_loc = 0;

char string[10];


extern void put_char(char str);
int kernel_main (unsigned int magic, unsigned int 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);
        
         }
     
       if (addr & 7)
         {
           printf ("Unaligned mbi: 0x%x\n", addr);
        
         }
     
       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;
     
                 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;
                            for (int j= 0; j < 800; j++)
                           *(pixel + j) = 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);
    int aaa = 5678;
    printf("My name is Zhi Qiang Li, %d", aaa);

    
    return 1;
}

     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;
                 }
             }
         }
     }

猜你喜欢

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