■
リンカスクリプトを以下のようにし、bootmiddleが0x1000(8セクション=8*512byte)あるようにbootacient.SのFD読み込み部分を書き直して解決。
苦肉の策だけどまぁ良しとしよう。
※0x800〜0x1000の0x800バイトが無駄になる。
※kernelを0x1000000などに置き直す場合はこの手法は使えない。
boot.ld
SECTIONS { .text ALIGN(0x200) : { "boota.o"(.text) "bootm.o"(.text) . = 0x1000; "cstart.o"(.text) "kernel.o"(.text) } .rodata : {} .bss ALIGN(0x200) : {} .data ALIGN(0x200) : { *(EXCLUDE_FILE (*bootm.o) .data) . = ALIGN(0x6000); "bootm.o"(.data) } }
makefile
makefileも修正
BASEDIR = /home/sode/prog/sodex SRCDIR = ${BASEDIR}/src BIN = ${BASEDIR}/bin LIST = ${BASEDIR}/list INCLUDE = ${SRCDIR}/include AS = /usr/bin/as CC = /usr/bin/gcc LD = /usr/bin/ld CFLAGS = -nostdlib -fno-exceptions -ffreestanding -fno-builtin -Wall LFLAGS = -T boot.ld -Map ${LIST}/boot.map --oformat binary KERNEL = boot.bin ACIENT = boota.o MIDDLE = bootm.o SRC = cstart.c \ kernel.c \ vga.c OBJS = $(SRC:.c=.o) ASMSRC = vga_core.S HEADER = kernel.h \ vga.h ${KERNEL} : ${ACIENT} ${MIDDLE} ${OBJS} vga_core.o boot.ld ${LD} ${LFLAGS} ${ACIENT} ${MIDDLE} ${OBJS} vga_core.o -o $@ ${ACIENT} : bootacient.S ${AS} bootacient.S -o $@ -a > ${LIST}/boota.lst ${MIDDLE} : bootmiddle.S ${AS} bootmiddle.S -o $@ -a > ${LIST}/bootm.lst vga_core.o : vga_core.S ${AS} vga_core.S -o $@ -a > ${LIST}/vga_core.lst %.o: %.c $(CC) -c ${CFLAGS} -I ${INCLUDE} -o $@ $<
表示周りのAPIを書いた。
vga.c
#include "vga.h" static int screenX = 0; static int screenY = 0; static char gColor = 0xf; void sysPointPrintc(int x, int y, char c) { sysPointColorPrintc(x, y, gColor, c); } void sysPrintc(char c) { if (c == '\n') { screenX = 0; if (screenY + 1 > SCREEN_HEIGHT) { sysScreenScrollUp(); } else screenY++; return; } sysPointColorPrintc(screenX, screenY, gColor, c); if (screenX + 1 > SCREEN_WIDTH) { if (screenY + 1 > SCREEN_HEIGHT) { sysScreenScrollUp(); } else screenY++; } screenX = (screenX + 1)%SCREEN_WIDTH; } void sysPrints(char *str) { char *p = str; while (*p != '\0') { sysPrintc(*p); p++; } } void sysClearScreen() { int x, y; for (y=0; y <= SCREEN_HEIGHT; ++y) for (x=0; x <= SCREEN_WIDTH; ++x) sysPointPrintc(x, y, 0); } void sysScreenScrollUp() { int i, j; for (i = SCREEN_WIDTH, j=0; i < SCREEN_WIDTH*SCREEN_HEIGHT; ++i, ++j) VRAM[2 * j] = VRAM[2 * i]; } void sysScreenPointSet(int x, int y) { screenX = x; screenY = y; } void sysScreenSetColor(char color) { gColor = color; } void sysScreenInitial() { sysClearScreen(); sysPrints("------------------------------------------------------------\n"); sysPrints(" This is Sodex Kernel. \n"); sysPrints(" The kernel is starting. \n"); sysPrints(" Now, we're going to implement the A20 and VGA \n"); sysPrints("------------------------------------------------------------\n"); }
vga_core.S
#include "vga.h" VRAM_ADDRESS = 0xb8000 .code32 .text .global sysPointColorPrintc /* void sysPointColorPrintc(int x, int y, char color, char c) * In this code, x is ebx, y is eax, color is dh, c is dl */ sysPointColorPrintc: pushl %ebp movl %esp, %ebp movl 0xc(%ebp), %eax movw $80, %cx mulw %cx # eax = y * 80 movw $2, %cx mulw %cx # eax = y * 80 * 2 movl 0x8(%ebp), %ebx addl %ebx, %eax addl %ebx, %eax addl $VRAM_ADDRESS, %eax movb 0x14(%ebp), %dl # set color movb 0x10(%ebp), %dh # set char movw %dx, (%eax) popl %ebp ret