1.1 整理一下代码
-
cong@msi:/work/os/code/6print$ tree
-
.
-
├── boot
-
│ ├── loader.S
-
│ └── mbr.S
-
├── include
-
│ ├── print.h
-
│ └── stdint.h
-
├── kernel
-
│ └── main.c
-
├── lib
-
│ ├── printf.c
-
│ ├── printf.o
-
│ ├── put_char.o
-
│ └── put_char.S
-
├── Makefile
-
├── makefile_bak
-
└── Makefile_bak
1.2 Makefile
-
cong@msi:/work/os/code/6print$ cat Makefile
-
ENTRY_POINT = 0xc0001500
-
AS = nasm
-
CC = gcc
-
LD = ld
-
LIB = -I lib/ -I lib/kernel/ -I lib/user/ -I kernel/ -I device/
-
ASFLAGS = -f elf
-
CFLAGS = -Wall $(LIB) -c -fno-builtin -W -Wstrict-prototypes \
-
-Wmissing-prototypes
-
LDFLAGS = -Ttext $(ENTRY_POINT) -e main -Map $(BUILD_DIR)/kernel.map
-
-
all: mbr loader kern
-
mbr:
-
nasm ./boot/mbr.S -I ./boot/include/ -o ./boot/mbr.bin
-
loader:
-
nasm ./boot/loader.S -I ./boot/include/ -o ./boot/loader.bin
-
kern:put_char.o printf.o main.o
-
ld -m elf_i386 -Ttext 0xc0001500 -e main -o ./kernel/kernel.bin \
-
./kernel/main.o ./lib/put_char.o ./lib/printf.o
-
main.o:
-
gcc $(CFLAGS) -c -m32 -I ./include -o ./kernel/main.o ./kernel/main.c
-
printf.o:
-
gcc $(CFLAGS) -c -m32 -I ./include -o ./lib/printf.o ./lib/printf.c
-
put_char.o:
-
nasm $(ASFLAGS) ./lib/put_char.S -o ./lib/put_char.o
-
-
clean:
-
-rm /work/os/code/disk.img ./boot/mbr.bin ./boot/loader.bin ./kernel/*.o ./kernel/kernel.bin
-
flash:
-
-rm /work/os/code/disk.img
-
dd if=/dev/zero of=/work/os/code/disk.img bs=1M count=30
-
dd if=./boot/mbr.bin of=/work/os/code/disk.img bs=512 count=1 conv=notrunc
-
dd if=./boot/loader.bin of=/work/os/code/disk.img bs=512 count=5 seek=2 conv=notrunc
-
dd if=./kernel/kernel.bin of=/work/os/code/disk.img bs=512 count=200 seek=9 conv=notrunc
-
show:
-
echo "show loader.bin"
-
xxd ./loader.bin
-
echo "show disk.img"
-
xxd -seek 0x400 -l 0x200 /work/os/code/disk.img
1.3 printf.c
原书中实现了put_char,那么进一步就可以实现printf
-
cong@msi:/work/os/code/6print/lib$ cat printf.c
-
#include "print.h"
-
#include <stdarg.h>
-
void put_string(char *str)
-
{
-
while(*str!='\0')
-
{
-
put_char(*str);
-
str++;
-
}
-
}
-
static void itoa(char **buf, unsigned char i, unsigned char base) -->这儿有个bug,unsigned char应该换成int
-
{
-
static char *s;
-
#define LEN 20
-
unsigned char rem;
-
static char rev[LEN+1];
-
-
rev[LEN] = 0;
-
if (i == 0)
-
{
-
(*buf)[0] = '0';
-
++(*buf);
-
return;
-
}
-
s = &rev[LEN];
-
while (i)
-
{
-
rem = i % base;
-
if (rem < 10)
-
*--s = rem + '0';
-
else if (base == 16)
-
*--s = "abcdef"[rem - 10];
-
i /= base;
-
}
-
while (*s)
-
{
-
(*buf)[0] = *s++;
-
++(*buf);
-
}
-
}
-
char print_buf[250];
-
void printf(char *fmt,...)
-
{
-
va_list ap;
-
int ival;
-
char *p;
-
char *bp;
-
bp= print_buf;
-
*bp= '\0';
-
-
va_start (ap, fmt);
-
for (p= fmt; *p; p++)
-
{
-
if (*p != '%')
-
{
-
*bp++= *p;
-
continue;
-
}
-
switch (*++p) {
-
case 'd':
-
ival= va_arg(ap, int);
-
itoa (&bp, ival, 10);
-
break;
-
case 'x':
-
ival= va_arg(ap, int);
-
itoa (&bp, ival, 16);
-
break;
-
}
-
}
-
*bp = '\0';
-
put_string(print_buf);
-
va_end (ap);
-
}
1.4 main函数测试
-
cong@msi:/work/os/code/6print$ cat kernel/main.c
-
#include "print.h"
-
void main(void)
-
{
-
int a=3;
-
put_char('k');
-
printf("a=%d\n",a);
-
while(1)
-
{
-
}
-
return ;
-
}
1.5 代码打包
6print.rar (下载后改名为6print.tar.gz)
1.6 运行测试
printf实现了
1.7 一个问题
1.7.1 printf.c中使用了系统中的stdarg.h
Makefile中加入-nostdinc时就会报错
./lib/printf.c:2:20: fatal error: stdarg.h: No such file or directory
1.7.2 自己实现一个va_list
-
#ifndef __LIB_STDARG_H
-
#define __LIB_STDARG_H
-
typedef char * va_list;
-
#define _INTSIZEOF(n) ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) )
-
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
-
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
-
#define va_end(ap) ( ap = (va_list)0 )
-
#endif
1.7.3 代码打包
6print.rar (下载后改名为6print.tar.gz)
阅读(1365) | 评论(0) | 转发(0) |