OSDev.org

The Place to Start for Operating System Developers
It is currently Tue Mar 19, 2024 12:35 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 9 posts ] 
Author Message
 Post subject: extern char getkb() apparently has no effect(MEATY SKELETON)
PostPosted: Mon Feb 08, 2016 2:38 pm 
Offline
Member
Member

Joined: Sat Dec 19, 2015 10:48 am
Posts: 42
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.



Quote:
#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[i] = 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[i]);
}

//void terminal_writestring(const char* data)
//{
// terminal_write(data, strlen(data));
//}


Top
 Profile  
 
 Post subject: Re: extern char getkb() apparently has no effect(MEATY SKELE
PostPosted: Mon Feb 08, 2016 2:51 pm 
Offline
Member
Member
User avatar

Joined: Thu Mar 27, 2014 3:57 am
Posts: 568
Location: Moscow, Russia
"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


Top
 Profile  
 
 Post subject: Re: extern char getkb() apparently has no effect(MEATY SKELE
PostPosted: Tue Feb 09, 2016 4:14 am 
Offline
Member
Member

Joined: Sat Dec 19, 2015 10:48 am
Posts: 42
The assembly file is as follows:
Code:
;   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:
#  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'


Top
 Profile  
 
 Post subject: Re: extern char getkb() apparently has no effect(MEATY SKELE
PostPosted: Tue Feb 09, 2016 6:00 am 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4591
Location: Chichester, UK
What is your OBJ_LINK_LIST?


Top
 Profile  
 
 Post subject: Re: extern char getkb() apparently has no effect(MEATY SKELE
PostPosted: Tue Feb 09, 2016 9:16 am 
Offline
Member
Member

Joined: Sat Dec 19, 2015 10:48 am
Posts: 42
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


Top
 Profile  
 
 Post subject: Re: extern char getkb() apparently has no effect(MEATY SKELE
PostPosted: Tue Feb 09, 2016 9:21 am 
Offline
Member
Member
User avatar

Joined: Thu Mar 27, 2014 3:57 am
Posts: 568
Location: Moscow, Russia
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


Top
 Profile  
 
 Post subject: Re: extern char getkb() apparently has no effect(MEATY SKELE
PostPosted: Tue Feb 09, 2016 10:04 am 
Offline
Member
Member

Joined: Sat Dec 19, 2015 10:48 am
Posts: 42
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.


Top
 Profile  
 
 Post subject: Re: extern char getkb() apparently has no effect(MEATY SKELE
PostPosted: Tue Feb 09, 2016 10:07 am 
Offline
Member
Member

Joined: Mon Jan 03, 2011 6:58 pm
Posts: 283
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.


Top
 Profile  
 
 Post subject: Re: extern char getkb() apparently has no effect(MEATY SKELE
PostPosted: Tue Feb 09, 2016 11:44 am 
Offline
Member
Member
User avatar

Joined: Thu Mar 27, 2014 3:57 am
Posts: 568
Location: Moscow, Russia
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


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 9 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Google [Bot], SemrushBot [Bot] and 13 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group