printf应该运行在用户空间,所以printf不应该直接操做显存,所以需要一个系统调用
sched.h中定义typedef int (*fn_ptr)();
include\linux中添加sys.h
extern int sys_read();
extern int sys_write();
fn_ptr sys_call_table[] = { sys_read,
sys_write };
定义一个fs文件夹,此文件夹下新建read_write.c
#include <linux/head.h>
#include <linux/kernel.h>
#include <linux/sched.h>
int sys_write(unsigned int fd,char * buf,int count)
{
tty_write(0,buf,count);
return 0;
}
int sys_read(unsigned int fd,char * buf,int count)
{
return 0;
}
fs下添加Makefile
AS =as
LD =ld
LDFLAGS = --oformat binary -N -e start -Ttext 0x0
CC =gcc
CFLAGS = -I../include -fno-stack-protector
.c.s:
$(CC) $(CFLAGS) \
-S -o $*.s $<
.s.o:
$(AS) -c -o $*.o $<
.c.o:
$(CC) $(CFLAGS) \
-c -o $*.o $<
OBJS = read_write.o
fs.o:$(OBJS)
$(LD) -r -o fs.o $(OBJS)
sync
clean:
rm -f *.o *.s
中添加:
.align 2
system_call:
push %ds
pushl %eax
pushl %edx
pushl %ecx
pushl %ebx
movl $0x10,%edx # set up ds,es to kernel space
mov %dx,%ds
mov %dx,%es
movl $0x17,%edx # fs points to local data space
mov %dx,%fs
call sys_call_table(,%eax,4)
popl %ebx
popl %ecx
popl %edx
popl %eax
pop %ds
iret
main.c中的mian函数中添加set_system_gate(0x80,&system_call);定义0x80中断的处理函数为system_call
system.h中添加
#define set_system_gate(n,addr) \
_set_gate(&idt[n],15,3,addr)
添加lib文件夹,此文件夹下添加write.c
#include <sys/types.h>
#define __NR_write 1
int write(int a,const char * b,off_t c)
{
long __res;
__asm__ volatile ("int $0x80" \
: "=a" (__res) \
: "0" (__NR_write),"b" ((long)(a)),"c" ((long)(b)),"d" ((long)(c)));
if (__res>=0)
return (int) __res;
return -1;
}
lib下的Makefile
AS =as
LD =ld
LDFLAGS = --oformat binary -N -e start -Ttext 0x0
CC =gcc
CFLAGS = -I../include -fno-stack-protector
.c.s:
$(CC) $(CFLAGS) \
-S -o $*.s $<
.s.o:
$(AS) -c -o $*.o $<
.c.o:
$(CC) $(CFLAGS) \
-c -o $*.o $<
OBJS = write.o
lib.a: $(OBJS)
$(AR) rcs lib.a $(OBJS)
sync
clean:
rm -f *.o *.s
off_t的定义在include\sys\types.h中
#ifndef SYS_TYPES_H
#define SYS_TYPES_H
typedef long off_t;
#endif
main.c中实现我们的printf函数
static char printbuf[1024];
extern int vsprintf();
static int printf(const char *fmt, ...)
{
int i;
va_list args = (va_list)((char*)(&fmt)+4);
write(1,printbuf,i=vsprintf(printbuf, fmt, args));
return i;
}
顶层Makefile
AS =as
LD =ld
LDFLAGS = --oformat binary -N -e start -Ttext 0x0
LIBS =lib/lib.a
all:Image
Image:boot/bootsect boot/setup system
cat boot/bootsect boot/setup system >Image
boot/bootsect:boot/bootsect.s
$(AS) -o boot/bootsect.o -a boot/bootsect.s
$(LD) $(LDFLAGS) -o boot/bootsect boot/bootsect.o
boot/setup:boot/setup.s
$(AS) -o boot/setup.o -a boot/setup.s
$(LD) $(LDFLAGS) -o boot/setup boot/setup.o
boot/head.o:boot/head.s
$(AS) -o boot/head.o -a boot/head.s
init/main.o: init/main.c
gcc -Iinclude -c -o init/main.o init/main.c
kernel/kernel.o:
(cd kernel; make)
fs/fs.o:
(cd fs; make)
lib/lib.a:
(cd lib; make)
system: boot/head.o init/main.o kernel/kernel.o fs/fs.o $(LIBS)
$(LD) $(LDFLAGS) -o system boot/head.o kernel/kernel.o init/main.o fs/fs.o $(LIBS)
clean:
rm -f Image system *.o *.s
rm -f boot/*.o boot/*.s boot/setup boot/bootsect
rm -f init/*.o
(cd kernel; make clean)