3

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 :)

YoloSama
  • 53
  • 5
  • How are you linking your program? – Marc-André Brochu Oct 27 '20 at 15:38
  • by a makefile, i will put this sorry. @Marc-AndréBrochu – YoloSama Oct 27 '20 at 15:40
  • 2
    For code, makefiles, command line output don't post pictures, copy and paste the actual text into your question. It helps to see all of the Makefile and all of the error and output from things like Make to see what command line arguments were actually passed. – Michael Petch Oct 27 '20 at 15:46
  • @MichaelPetch yeah sure but it's look like too long i need to change it ? bc i put all the needed things – YoloSama Oct 27 '20 at 15:50
  • 1
    I have downvoted your question because it contains pictures of text. Do not post text as pictures. – fuz Oct 27 '20 at 15:51
  • But if I had to guess what is going on. You seem to have `init_tables.s` and `init_tables.c`. If you compile / assemble them in the same directory both those files will output to `init_tables.o` and one will be overwritten by another. If that is the case try changing the name of one of the files so they are output into different `.o` files. – Michael Petch Oct 27 '20 at 15:53
  • @fuz i have change everything right now you can check thank you – YoloSama Oct 27 '20 at 15:55
  • Where does your make file assemble the NASM code and where is that linked to the rest of the `.o` files – Michael Petch Oct 27 '20 at 15:57
  • @MichaelPetch i tried to change the name of the file it's doesn't change :/ but it was a good idea – YoloSama Oct 27 '20 at 15:58
  • @MichaelPetch i don't compile my nasm code anywhere in the makefile, it's a .S file it compile automaticaly no ?? – YoloSama Oct 27 '20 at 16:00
  • 4
    You need to modify your Makefile to assemble `init_tables.s` to `init_tables.o` with NASM or YASM since that is the assembler syntax you are using. the `.s` file should also be `.asm` as `.s` is more for GNU assembler (`as`) – Michael Petch Oct 27 '20 at 16:01
  • Your assembly code is still a picture. – fuz Oct 27 '20 at 16:06
  • @MichaelPetch ok i will try this ty very much for your help – YoloSama Oct 27 '20 at 16:08
  • @fuz i change it look – YoloSama Oct 27 '20 at 16:08
  • 1
    Depending on the compiler system the symbols of C sources might be prepended with the character "_" (underline). Check the symbol table of the generated object files (".o" extension) for example with `objdump`. If you find the external `gdt_flush` to be `_gdt_flush`, you know what to do... – the busybee Oct 27 '20 at 20:33

0 Answers0