Hello :) i got a serious problem to call my assembly function in my c program, it said that it's undefined reference.
here my assembly code :
[GLOBAL gdt_flush]
gdt_flush:
mov eax, [esp+4] ; Get the pointer to the GDT, passed as a parameter.
lgdt [eax] ; Load the new GDT pointer
mov ax, 0x10 ; 0x10 is the offset in the GDT to our data segment
mov ds, ax ; Load all data segment selectors
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
jmp 0x08:.flush ; 0x08 is the offset to our code segment: Far jump!
.flush:
ret
then my c code : my file where i put the call of the function :
#include <k/types.h>
#include "io.h"
#include "init_tables.h"
#include "events.h"
extern void gdt_flush(u32 gdt_ptr);
/* 1. SERIAL PORT */
void init_uart(void) //Initialize uart 16550 for 38400 bps
{
u8 ier = inb(SERIAL_PORT + 1);
u8 fcr = inb(SERIAL_PORT + 2);
u8 lcr = inb(SERIAL_PORT + 3);
u16 rate = 38400;
outb(SERIAL_PORT + 3, lcr | 1 << 7);
outb(SERIAL_PORT + 0, (115200 / rate) & 255); // = 0x3
outb(SERIAL_PORT + 1, (115200 / rate) >> 8); // = 0x0
outb(SERIAL_PORT + 3, lcr & ~(1 << 7));
outb(SERIAL_PORT + 2, fcr | 1 << 1);
outb(SERIAL_PORT + 2, fcr | 1 << 2);
outb(SERIAL_PORT + 2, fcr | 1 << 6);
outb(SERIAL_PORT + 2, fcr | 1 << 7);
outb(SERIAL_PORT + 1, ier | 1 << 1);
}
/* 2. MEMORY MANAGER */
static struct gdt_entry gdt[5];
static struct gdt_r gdt_r;
static void set_gdt_entry(unsigned index, u32 base_adress, u32 limit, u16 access, u16 flags)/* Function to initialize an index of the gtd_entry structure */
{
if (index >= SIZE_ARRAY(gdt))
printf("ARRAY SIZE INCORRECT\n");
gdt[index].seg_lim_15_00 = (limit & 0xFFFF); // set segment limit of 00-15
gdt[index].granularity = (limit >> 16) & 0x0F; // set segment of 16-19
gdt[index].granularity |= flags & 0xF0; // granularity, operand size, zero and avl -> flags
gdt[index].access_byte = access; //set up type, s, dpl, p
gdt[index].base_15_00 = (base_adress & 0xFFFF); //set up base 00-15 bit
gdt[index].base_23_16 = (base_adress >> 16) & 0xFF; //set up base 16-23 bit
gdt[index].base_31_24 = (base_adress >> 24) & 0xFF; //set up base 24-31 bit
}
static void gdt_load(void) /* Function to load our gtd and reload segment selectors*/
{
__asm__ volatile ("lgdt %[gdt_r]\n"
"mov %%cr0, %%eax\n"
"or $1, %%eax\n"
"mov %%eax, %%cr0\n"
"mov %[ds], %%ax\n"
"mov %%ax, %%ds\n"
"mov %%ax, %%es\n"
"mov %%ax, %%fs\n"
"mov %%ax, %%gs\n"
//"mov %%ax, %%ss\n"
"ljmp %[cs], $set_cs\n"
"set_cs:\n"
:
: [gdt_r]"m"(gdt_r), [cs]"i"(0x8), [ds]"i"(0x10)
: "%eax");
/*asm volatile(" lgdt %0\n" : : "m"(gdt_r) : "memory"); //LOAD GTD
asm volatile ("movl %cr0, %eax\n\t" // activate protected mode
"or %al, 1\n\t"
"movl %eax, %cr0\n\t"
"movw $0x10, %ax\n\t"
"movw %ax, %ds\n\t"
"movw %ax, %es\n\t"
"movw %ax, %fs\n\t"
"movw %ax, %gs\n\t"
"movw %ax, %ss\n\t"
"ljmp $0x08, $1f\n\t"
"1:\n\t");*/
}
static void init_gdt(void)
{
gdt_r.limit = sizeof(gdt) - 1;
gdt_r.base = (u32)&gdt;
set_gdt_entry(0, 0, 0, 0, 0); /* Null segment */
set_gdt_entry(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); /* Code segment */
set_gdt_entry(2, 0, 0xFFFFFFFF, 0x92, 0xCF); /* Data segment */
//set_gdt_entry(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); /* User mode code segment */
//set_gdt_entry(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); /* User mode data segment */
gdt_flush((u32)&gdt_r);
//gdt_load();
}
void init_kernel(void)
{
init_uart();
init_gdt();
//init_interrupt();
//load_idt();
//print_stack();
}
then my Makefile :
#
# Copyright (c) LSE
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY LSE AS IS AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL LSE BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
include ../config.mk
TARGET = k
OBJS = \
crt0.o \
k.o \
libvga.o \
list.o \
memory.o \
io.o \
init_tables.o \
#events.o
#isr.o
DEPS = $(OBJS:.o=.d)
all: $(TARGET)
$(TARGET): CPPFLAGS += -MMD -Iinclude -I ../libs/libc/include/
$(TARGET): CFLAGS += $(K_EXTRA_CFLAGS)
$(TARGET): LDFLAGS += -Wl,-Tk.lds
$(TARGET): LDLIBS = -L../libs/libc -lc
$(TARGET): $(OBJS) init_tables.s
install: $(TARGET)
$(INSTALL) $(TARGET) $(INSTALL_ROOT)/$(TARGET)
clean:
$(RM) $(OBJS) $(DEPS) $(TARGET)
-include $(DEPS)
Right now i put a gas file to be execute at the loading so i can't understand why it doesnt work and why i need to link these files. I was sure that the link is doing it automatically Can somebody help me ? Thanks a lot :)
User contributions licensed under CC BY-SA 3.0