• 30天自制操作系统-day7


    30天自制操作系统-day7

    这次我们更改main.c以及相关文件,生成彩色条纹,与上次彩色条纹区分开
    main.c

    #include<header.h>
    void bootmain(void){
    	//注意这里的函数名字为bootmain,因为在entry.S中设定的入口名字也是bootmain,两者要保持一致
    	int i;
    	char *p;
    	init_palette();
    	for(i=0xa0000; i<=0xaffff; i++){
    		//write_mem8(i, i&0x0f);
    		p=(char *)i;
    		*p=i&0x0f;
    	}
    
    	for(;;){
    		io_halt();
    	}
    }
    

    header.h

    #ifndef header
    #define header
    #include <x86.h>
    
    #define io_halt() asm("hlt")
    #define write_mem8(addr,data8)   (*(volatile char *)(addr))=(char)data8
    
    #define io_cli() asm("cli")	//!!!本次添加部分
    #define io_sti() asm("sti")//!!!本次添加部分
    
    extern void clear_screen(char color) ; //color=15 pure white color=40 red
    extern void color_screen(char color) ;
    
    extern void init_palette(void);
    extern void set_palette(int start, int end, unsigned char *rgb);
    
    #endif
    

    entry.s

    #include <mmu.h>
    
    # Start the CPU: switch to 32-bit protected mode, jump into C.
    # The BIOS loads this code from the first sector of the hard disk into
    # memory at physical address 0x7c00 and starts executing in real mode
    # with %cs=0 %ip=7c00.
    #define CYLS			0x0ff0			
    #define LEDS			0x0ff1
    #define VMODE			0x0ff2			
    #define SCRNX			0x0ff4			
    #define SCRNY			0x0ff6			
    #define VRAM			0x0ff8			
    
    .set PROT_MODE_CSEG, 0x8         # kernel code segment selector
    .set PROT_MODE_DSEG, 0x10        # kernel data segment selector
    .set CR0_PE_ON,      0x1         # protected mode enable flag
    
    .globl start
    start:
      .code16                     # Assemble for 16-bit mode
    
      # Set up the important data segment registers (DS, ES, SS).
      xorw    %ax,%ax             # Segment number zero
      movw    %ax,%ds             # -> Data Segment
      movw    %ax,%es             # -> Extra Segment
      movw    %ax,%ss             # -> Stack Segment
      
      movb $0x13,%al  # ;vga 320x200x8 位,color mode 
      movb $0x00,%ah
      int $0x10
      
    #save color mode in ram 0x0ff0
     movb $8,(VMODE)
     movw $320,(SCRNX)
     movw $200,(SCRNY)
     movl $0x000a0000,(VRAM)
    
     #get keyboard led status
     movb	$0x02,%ah 
     int     $0x16			#keyboard interrupts
     movb   %al,(LEDS)
    		
    #diplay something
      movw $msg,%si
      call puts
      
      movw $try,%si
      call puts
    
      #jmp .
       cli                         # Disable interrupts
       cld                         # String operations increment
    
      # Enable A20:
      #   For backwards compatibility with the earliest PCs, physical
      #   address line 20 is tied low, so that addresses higher than
      #   1MB wrap around to zero by default.  This code undoes this. 
    seta20.1:
      inb     $0x64,%al               # Wait for not busy
      testb   $0x2,%al
      jnz     seta20.1
    
      movb    $0xd1,%al               # 0xd1 -> port 0x64
      outb    %al,$0x64
    
    seta20.2:
      inb     $0x64,%al               # Wait for not busy
      testb   $02,%al
      jnz     seta20.2
    
      movb    $0xdf,%al               # 0xdf -> port 0x60
      outb    %al,$0x60
    
      # Switch from real to protected mode, using a bootstrap GDT       this is vip ,but i don`t know it clearly now
      # and segment translation that makes virtual addresses 
      # identical to their physical addresses, so that the 
      # effective memory map does not change during the switch.
      lgdt    gdtdesc
      movl    %cr0, %eax
      orl     $CR0_PE_ON, %eax
      movl    %eax, %cr0
      
      # Jump to next instruction, but in 32-bit code segment.
      # Switches processor into 32-bit mode.
      ljmp    $PROT_MODE_CSEG, $protcseg
      msg:
      .asciz "
    
    
    my kernel is runing jos"
      
     try:
      .asciz "
    
    
    try it again"
    
    puts:
    
    	movb (%si),%al
    	add $1,%si
    	cmp $0,%al
    	je over
    	movb $0x0e,%ah
    	movw $15,%bx
    	int $0x10
    	jmp puts
    over:
    	ret	
    	
      .code32                     # Assemble for 32-bit mode
    protcseg:
      # Set up the protected-mode data segment registers
      movw    $PROT_MODE_DSEG, %ax    # Our data segment selector
      movw    %ax, %ds                # -> DS: Data Segment
      movw    %ax, %es                # -> ES: Extra Segment
      movw    %ax, %fs                # -> FS
      movw    %ax, %gs                # -> GS
      movw    %ax, %ss                # -> SS: Stack Segment
      
      # Set up the stack pointer and call into C.
      movl    $start, %esp
      call bootmain
    
      # If bootmain returns (it shouldn't), loop.
    spin:
      jmp spin
    
    
    # Bootstrap GDT
    .p2align 2                                # force 4 byte alignment
    gdt:
      SEG_NULL				# null seg
      SEG(STA_X|STA_R, 0x0, 0xffffffff)	# code seg
      SEG(STA_W, 0x0, 0xffffffff)	        # data seg
    
    gdtdesc:
      .word   0x17                            # sizeof(gdt) - 1
      .long   gdt                             # address gdt
    
    #.fill 310
    

    screen.c

    #include<header.h>
    
    void clear_screen(char color) //15:pure white
    {
    	int i;
    	for(i=0xa0000;i<0xaffff;i++)
    	{
    		write_mem8(i,color);
    	}
    }
    
    void color_screen(char color) //15:pure white
    {
    	int i;
    	color=color;
    	for(i=0xa0000;i<0xaffff;i++)
    	{
    		write_mem8(i,i&0x0f);
    
    	}
    }
    
    void set_palette(int start, int end, unsigned char* rgb){
    	int i, eflags;
    	eflags = read_eflags();	//替代作者的io_load_eflags()
    	io_cli();
    	outb(0x03c8, start);	//替代作者的io_out8()
    	for(i=start; i<=end; i++){
    		outb(0x03c9,rgb[0]/4);
    		outb(0x03c9,rgb[1]/4);
    		outb(0x03c9,rgb[2]/4);
    		rgb+=3;
    	}
    	write_eflags(eflags);	//替代作者的io_store_eflags(eflags)
    	return;
    }
    
    void init_palette(void){
    	//16种color,每个color三个字节。
    	static unsigned char table_rgb[16*3]=
    	{
    		0x00,0x00,0x00,   /*0:black*/
    		0xff,0x00,0x00,   /*1:light red*/ 
    		0x00,0xff,0x00,   /*2:light green*/   
    		0xff,0xff,0x00,   /*3:light yellow*/
    
    		0x00,0x00,0xff,   /*4:light blue*/
    		0xff,0x00,0xff,   /*5:light purper*/ 
    		0x00,0xff,0xff,   /*6:light blue*/
    		0xff,0xff,0xff,   /*7:white*/
    
    		0xc6,0xc6,0xc6,   /*8:light gray*/
    		0x84,0x00,0x00,   /*9:dark red*/
    		0x00,0x84,0x00,   /*10:dark green*/ 
    		0x84,0x84,0x00,   /*11:dark yellow*/
    		0x00,0x00,0x84,   /*12:dark 青*/
    		0x84,0x00,0x84,   /*13:dark purper*/
    		0x00,0x84,0x84,   /*14:light blue*/
    		0x84,0x84,0x84,   /*15:dark gray*/
    	};  
    	set_palette(0,15,table_rgb);
    	return;
    }
    

    kernel/makefile

    addr=0x7c00
    OBJDIR=.
    CFLAGS := $(CFLAGS) -O1 -fno-builtin -I$(OBJDIR) -MD                                                                                        
    CFLAGS += -fno-omit-frame-pointer
    CFLAGS += -Wall -Wno-format -Wno-unused -Werror -gstabs -m32
    LDFLAGS=-m elf_i386
    
    all:kernel
    kernel:entry.o main.o screen.o
    	ld $(LDFLAGS) -N -e start -Ttext $(addr) -o $@.out $^
    	objdump -S $@.out >$@.asm
    #	objcopy -S -O binary -j .text $@.out $@
    	objcopy -S -O binary $@.out $@
    
    entry.o:entry.S
    	gcc -nostdinc $(CFLAGS) -c -o $@ $<
    main.o:main.c
    	gcc -nostdinc $(CFLAGS) -Os -c -o $@ $<
    screen.o:screen.c
    	gcc -nostdinc $(CFLAGS) -c -o $@ $<
    run:
    	qemu-system-i386 -drive file=kernel,if=floppy
    clean:
    	@rm -f entry.o main.o screen.o kernel.out kernel.asm kernel *.d
    
    效果如下:

    源码链接:https://github.com/zchrissirhcz/osask-linux.git

  • 相关阅读:
    mysql忘记root密码解决办法
    laravel 获取所有表名
    跳转/传值(从页面到php文件)
    smarty foreach
    radio单选框
    dedecms实例化对象
    file_get_contents()
    if($a)
    bug解决思路
    git查看远程仓库地址
  • 原文地址:https://www.cnblogs.com/wangdongfang/p/14364994.html
Copyright © 2020-2023  润新知