extern char getkb() apparently has no effect(MEATY SKELETON)

Programming, for all ages and all languages.
Post Reply
bilsch01
Member
Member
Posts: 42
Joined: Sat Dec 19, 2015 10:48 am

extern char getkb() apparently has no effect(MEATY SKELETON)

Post by bilsch01 »

Please see the modified version of file tty.c below from MEATY SKELETON.
This question concerns 1) the statement at the beginning:
extern char getkb();
and 2) the third function from the bottom: void terminal_getkb(void).

Label getkb is the entry point to an assembly routine.
The function line: c = getkb()
gets the error: undefined reference to `getkb'
as though the statement: extern char getkb() has no effect.
It should not get that error even if the assembly routine is deleted.

If the compile or link lines in the makefile were wrong I would expect
a different message like: file foo.bar not found. I suspect I cannot
use the line: extern char getkb(void) in this code because it violates
something about these OS programming files.
MY QUESTION: why the error: undefined reference to getkb

TIA Bill S.


#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <kernel/vga.h>

extern char getkb(void);
char c='A';

size_t terminal_row;
size_t terminal_column;
uint8_t terminal_color;
uint16_t* terminal_buffer;

void terminal_initialize(void)
{
terminal_row = 0;
terminal_column = 0;
terminal_color = make_color(COLOR_MAGENTA, COLOR_BLACK);
terminal_buffer = VGA_MEMORY;
for ( size_t y = 0; y < VGA_HEIGHT; y++ )
{
for ( size_t x = 0; x < VGA_WIDTH; x++ )
{
const size_t index = y * VGA_WIDTH + x;
terminal_buffer[index] = make_vgaentry(' ', terminal_color);
}
}
}

void scrolldn(){
for (size_t i = 0; i<VGA_WIDTH*VGA_HEIGHT; i++)
terminal_buffer = terminal_buffer[i+VGA_WIDTH];
}

void terminal_setcolor(uint8_t color)
{
terminal_color = color;
}

void terminal_putentryat(char c, uint8_t color, size_t x, size_t y)
{
const size_t index = y * VGA_WIDTH + x;
terminal_buffer[index] = make_vgaentry(c, color);
}

void terminal_putchar(char c) {
if (c != '\n'){
terminal_putentryat(c, terminal_color, terminal_column, terminal_row);
if (++terminal_column == VGA_WIDTH) {
terminal_column = 0;
if (++terminal_row == VGA_HEIGHT)
scrolldn();
}
}
else
{
terminal_column = 0;
terminal_row++;
if (terminal_row == VGA_HEIGHT)
scrolldn();
}
}

void terminal_getkb(void)
{
while (1)
{ c = getkb();
terminal_putchar(c);
}
}

void terminal_write(const char* data, size_t size)
{
for ( size_t i = 0; i < size; i++ )
terminal_putchar(data);
}

//void terminal_writestring(const char* data)
//{
// terminal_write(data, strlen(data));
//}
User avatar
Roman
Member
Member
Posts: 568
Joined: Thu Mar 27, 2014 3:57 am
Location: Moscow, Russia
Contact:

Re: extern char getkb() apparently has no effect(MEATY SKELE

Post by Roman »

"undefined reference" is a linker error, not a compiler error. It has nothing to do with your C code directly. It means that there is an unresolved symbol during linking.
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
- Alan Kay
bilsch01
Member
Member
Posts: 42
Joined: Sat Dec 19, 2015 10:48 am

Re: extern char getkb() apparently has no effect(MEATY SKELE

Post by bilsch01 »

The assembly file is as follows:

Code: Select all

;	kb1.asm		nasm -f elf32 kb1.asm -o kb1.o
global getkb

SECTION	.text

getkb:
		push bp
		mov bp,sp
lup2:
		mov cx,0xffff
lup1:
		dec cx
		nop
		nop
		nop
		cmp cx,0	;0 means 65536 loops
		jne lup1
		mov ah,1	;check for key
		int 0x16
		jnz lup2	;zf=1 if no key avail
		mov ah,0
		int 0x16	;get ASCII byte in al
		pop bp
		iret
And the pertinent lines from the makefile are:

Code: Select all

#  this rule added by bilsch01
$(ARCHDIR)/tty.o: $(ARCHDIR)/kb1.o $(ARCHDIR)/tty.o
	i686-elf-gcc -c $(ARCHDIR)/kb1.o $(ARCHDIR)/tty.o -o $(ARCHDIR)/tty.o $(CFLAGS) $(CPPFLAGS)

myos.kernel: $(OBJ_LINK_LIST) $(ARCHDIR)/linker.ld
	$(CC) -T $(ARCHDIR)/linker.ld -o $@ $(CFLAGS) $(OBJ_LINK_LIST) $(LDFLAGS) $(LIBS)

%.o: %.c
	$(CC) -c $< -o $@ -std=gnu11 $(CFLAGS) $(CPPFLAGS)

%.o: %.S
	$(CC) -c $< -o $@ $(CFLAGS) $(CPPFLAGS)
The added line results in a newer tty.o than the version of tty.c therefore the newer tty.o does not get recompiled (thus not wiped out) by the next rule - as desired.

I do not see why the build gets the error: 'undefined reference to getkb'
User avatar
iansjack
Member
Member
Posts: 4685
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: extern char getkb() apparently has no effect(MEATY SKELE

Post by iansjack »

What is your OBJ_LINK_LIST?
bilsch01
Member
Member
Posts: 42
Joined: Sat Dec 19, 2015 10:48 am

Re: extern char getkb() apparently has no effect(MEATY SKELE

Post by bilsch01 »

OBJ_LINK_LIST:=\

$(CRTI_OBJ) \
$(CRTBEGIN_OBJ) \
$(OBJS) \
$(CRTEND_OBJ) \
$(CRTN_OBJ) \

which is:

myos/kernel/arch/i386/crti.o \
i686-elf-gcc $(CFLAGS) $(LDFLAGS) -print-file-name=crtbegin.o) \
myos/kernel/arch/i386/boot.o \
myos/kernel/arch/i386/tty.o \
myos/kernel/kernel/kernel.o \
i686-elf-gcc $(CFLAGS) $(LDFLAGS) -print-file-name=crtend.o) \
myos/kernel/arch/i386/crtn.o
User avatar
Roman
Member
Member
Posts: 568
Joined: Thu Mar 27, 2014 3:57 am
Location: Moscow, Russia
Contact:

Re: extern char getkb() apparently has no effect(MEATY SKELE

Post by Roman »

Obviously, you're missing kb1.o. By the way, your assembly code won't work, because BIOS interrupts are not available in 32-bit protected mode.
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
- Alan Kay
bilsch01
Member
Member
Posts: 42
Joined: Sat Dec 19, 2015 10:48 am

Re: extern char getkb() apparently has no effect(MEATY SKELE

Post by bilsch01 »

Ok. adding kb1.o works. Thanks. One more question: I'm not in protected mode yet so I expect this (still) real mode system to get my keyboard input and display it on the screen - just for the hell of it. But it doesn't do it.
FallenAvatar
Member
Member
Posts: 283
Joined: Mon Jan 03, 2011 6:58 pm

Re: extern char getkb() apparently has no effect(MEATY SKELE

Post by FallenAvatar »

If you are writing C code, you are in protected mode. If you aren't in protected mode, you can't use C.

- Monk

P.S. There are ways to write real mode C, all of which are out of date, broken, or just not recommended.
User avatar
Roman
Member
Member
Posts: 568
Joined: Thu Mar 27, 2014 3:57 am
Location: Moscow, Russia
Contact:

Re: extern char getkb() apparently has no effect(MEATY SKELE

Post by Roman »

The "Meaty skeleton" tutorial uses GRUB, which enables protected mode before booting a multiboot-compliant kernel. Although, you still must setup your own GDT, because the GDT setup by GRUB is unreliable.
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
- Alan Kay
Post Reply