ich einen Kernel folgende James M Tutorials zu schreiben, und vor kurzem habe ich ein Tastaturtreiber (von bkerndev Tutorial), um eine einfache Schale zu implementieren. Der Tastaturtreiber funktionierte bisher gut, bis ich eine Möglichkeit gefunden habe, eine Eingabezeile vom Benutzer zu identifizieren. Es schreibt im Grunde nur die Eingabezeile in ein Array als eine Zeichenfolge, die dann als die 'Eingabe'-Variable in der Datei' kernel.c 'verwendet wird. Allerdings, wenn ich den Code zu kompilieren bekomme ich folgende Fehler von dem Linker:Linker Fehler: undefined reference to `USER_INPUT‘
keyboard.c:(.text+0x8c): undefined reference to `user_input'
Die Referenz wird definiert in der Datei ‚kernel.h‘.
keyboard.c
#include <kstdio.h>
#include <isr.h>
#include <keyboard.h>
#include <kernel.h>
u32int shiftKey;
static char letter;
static char upLetter;
static char key_buffer[256]; // The buffer line
#define RSHIFT 0x80 - 42
#define LSHIFT 0x80 - 54
#define ENTER 0x1C
#define BACKSPACE 0x0E
// kbdus is the scancode tables for English US
unsigned char kbdus[128] =
{
0, 27, '1', '2', '3', '4', '5', '6', '7', '8', /* 9 */
'9', '0', '-', '=', '\b', /* Backspace */
'\t', /* Tab */
'q', 'w', 'e', 'r', /* 19 */
't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', /* Enter key */
0, /* 29 - Control */
'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* 39 */
'\'', '`', 0, /* Left shift */
'\\', 'z', 'x', 'c', 'v', 'b', 'n', /* 49 */
'm', ',', '.', '/', 0, /* Right shift */
'*',
0, /* Alt */
' ', /* Space bar */
0, /* Caps lock */
0, /* 59 - F1 key ... > */
0, 0, 0, 0, 0, 0, 0, 0,
0, /* < ... F10 */
0, /* 69 - Num lock*/
0, /* Scroll Lock */
0, /* Home key */
0, /* Up Arrow */
0, /* Page Up */
'-',
0, /* Left Arrow */
0,
0, /* Right Arrow */
'+',
0, /* 79 - End key*/
0, /* Down Arrow */
0, /* Page Down */
0, /* Insert Key */
0, /* Delete Key */
0, 0, 0,
0, /* F11 Key */
0, /* F12 Key */
0, /* All other keys are undefined */
};
unsigned char upkbdus[128] =
{
0, 27, '!', '@', '#', '$', '%', '^', '&', '*', /* 9 */
'(', ')', '_', '+', '\b', /* Backspace */
'\t', /* Tab */
'Q', 'W', 'E', 'R', /* 19 */
'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', /* Enter key */
0, /* 29 - Control */
'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', /* 39 */
'\'', '`', 0, /* Left shift */
'\\', 'Z', 'X', 'C', 'V', 'B', 'N', /* 49 */
'M', ',', '.', '/', 0, /* Right shift */
'*',
0, /* Alt */
' ', /* Space bar */
0, /* Caps lock */
0, /* 59 - F1 key ... > */
0, 0, 0, 0, 0, 0, 0, 0,
0, /* < ... F10 */
0, /* 69 - Num lock*/
0, /* Scroll Lock */
0, /* Home key */
0, /* Up Arrow */
0, /* Page Up */
'-',
0, /* Left Arrow */
0,
0, /* Right Arrow */
'+',
0, /* 79 - End key*/
0, /* Down Arrow */
0, /* Page Down */
0, /* Insert Key */
0, /* Delete Key */
0, 0, 0,
0, /* F11 Key */
0, /* F12 Key */
0, /* All other keys are undefined */
};
/* Handles the keyboard interrupt */
void keyboard_handler(struct regs *r)
{
unsigned char scancode;
/* Read from the keyboard's data buffer */
scancode = inb(0x60);
/* If the top bit of the byte we read from the keyboard is
* set, that means that a key has just been released */
if (scancode & 0x80)
{
if (scancode == LSHIFT || scancode == RSHIFT) {
shiftKey = 1;
}
else {
shiftKey = 0;
}
}
else
{
letter = kbdus[scancode];
upLetter = upkbdus[scancode];
/* Here, a key was just pressed. Please note that if you
* hold a key down, you will get repeated key press
* interrupts. */
/* Just to show you how this works, we simply translate
* the keyboard scancode into an ASCII value, and then
* display it to the screen. You can get creative and
* use some flags to see if a shift is pressed and use a
* different layout, or you can add another 128 entries
* to the above layout to correspond to 'shift' being
* held. If shift is held using the larger lookup table,
* you would add 128 to the scancode when you look for it */
if (scancode == BACKSPACE) {
backspace(key_buffer);
} else if (scancode == ENTER) {
user_input(key_buffer);
kprintf("\n");
key_buffer[0] = '\0';
} else {
/* Remember that kprint only accepts char[] */
char str[2] = {letter, '\0'};
append(key_buffer, letter);
kprintf(str);
}
/* if (shiftKey == 0) {
kputc(letter);
}
else if (shiftKey == 1) {
kputc(upLetter);
} */
}
}
void keyboard_install() {
register_interrupt_handler(IRQ1, &keyboard_handler);
}
keyboard.h
#ifndef KEYBOARD_H
#define KEYBOARD_H
void keyboard_install();
#endif
kernel.h
#ifndef KERNEL_H
#define KERNEL_H
#include <keyboard.h>
void user_input(char *input);
#endif
Makefi le
# Makefile for Sierra Kernel
# The C and C++ rules are already setup by default.
# The only one that needs changing is the assembler
# rule, as we use nasm instead of GNU as.
DESTDIR?=
INCLUDEDIR?=include
PREFIX?=/usr/local
EXEC_PREFIX?=$(PREFIX)
BOOTDIR?=$(EXEC_PREFIX)/boot
export AR=/Users/development/opt/cross/bin/i386-elf-ar
export AS=/Users/development/opt/cross/bin/i386-elf-as
export CC=/Users/development/opt/cross/bin/i386-elf-gcc
export GDB=/Users/development/opt/cross/bin/i386-elf-gdb
CFLAGS=-nostdlib -nostdinc -fno-builtin -I include
LDFLAGS=-Tlink.ld
ASFLAGS=-felf
SOURCES=boot/boot.o drivers/halt.o drivers/kstdio/screen.o drivers/kstdio/io.o kernel/sierra/kernel.o \
kernel/tables/gdt.o kernel/tables/tables.o kernel/tables/isr.o kernel/timer.o kernel/tables/inter.o \
drivers/keyboard.o
all: $(SOURCES) link
clean:
rm -rf boot/*.o drivers/*.o drivers/kstdio/*.o kernel/sierra/*.o kernel/tables/*.o \
*.o kernel/*.o *.kernel
link:
/Users/development/opt/cross/i386-elf/bin/ld $(LDFLAGS) -o sierra.kernel $(SOURCES)
.s.o:
nasm $(ASFLAGS) $<
install: install-headers install-kernel
install-headers:
mkdir -p $(DESTDIR)$(INCLUDEDIR)
cp -R --preserve=timestamps include/. $(DESTDIR)$(INCLUDEDIR)/.
install-kernel:
mkdir -p $(DESTDIR)$(BOOTDIR)
cp kernel $(DESTDIR)$(BOOTDIR)
image:
./update_image.sh
run:
qemu-system-i386 -fda system.img
bundle:
make clean
make
make image
make run
mac:
make clean
make
Das gesamte Projekt Quelle ist hier verfügbar: https://github.com/sofferjacob/Sierra-Kernel/tree/testing.
Danke für die Hilfe.
Btw Ich benutze eine Cross-Compile-Toolchain in Ubuntu 16.10 (manchmal benutze ich die gleiche Toolchain in MacOS 10.12, aber es ist in der Regel Ubuntu), um den Kernel zu kompilieren.
Sie * declare * 'user_input' Funktion in Header-Datei, aber ** definiert nie ** es. Deshalb erhalten Sie den Fehler vom Linker. – Tsyvarev
Es ist definiert in [kernel.c] (https://github.com/sofferjacob/Sierra-Kernel/blob/testing/kernel/sierra/kernel.c) –
Sie zeigt nicht diese Quelle in der Frage Post. Wenn Sie über [kernel/sierra/kernel.c] (https://github.com/offerjacob/Sierra-Kernel/blob/testing/kernel/sierra/kernel.c) sprechen, definiert es 'user_input' als ** verschachtelt Funktion **, so dass es außerhalb von 'main()' nicht zugänglich ist. – Tsyvarev