如何在xv6操作系统上使用ulib. c中其他.c文件中定义的函数?

xa9qqrwz  于 2023-04-11  发布在  其他
关注(0)|答案(1)|浏览(187)

我正在xv6操作系统上做一个票证锁。这是我的代码

void
lock_init(struct lock_t* lk) {
  lk->ticket = 0;
  lk->turn = 0;
}

extern void pushcli(void);
extern void popcli(void);

void
lock_acquire(struct lock_t* lk) {
  pushcli();
  uint myturn = xchg(&lk->ticket, lk->ticket + 1);
  while (lk->turn != myturn)
    ;
  __sync_synchronize();
}

void
lock_release(struct lock_t* lk) {
  __sync_synchronize();
  xchg(&lk->turn, lk->turn + 1);
  popcli();
}

但是,当我输入make qemu时,出现了一个错误:

gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -fno-pie -no-pie   -c -o ulib.o ulib.c
ld -m    elf_i386 -N -e main -Ttext 0 -o _cat cat.o ulib.o usys.o printf.o umalloc.o
ld: ulib.o: in function `lock_acquire':
/home/kamichanw/os-lab/Xv6-Syscall/src/ulib.c:120: undefined reference to `pushcli'
ld: ulib.o: in function `lock_release':
/home/kamichanw/os-lab/Xv6-Syscall/src/ulib.c:131: undefined reference to `popcli'

pushclipopcli是在spinlock.c中定义的函数。下面是xv6源代码:xv6 source code
我猜问题出在Makefile上,但我没有修复它的线索。

oxcyiej7

oxcyiej71#

看起来你试图在ulib. c文件中使用spinlock. c中的pushcli()和popcli(),但在编译过程中它们没有正确链接。让我来帮助你。
要解决这个问题,您需要编辑xv 6目录中的Makefile。请按照以下步骤操作:
打开Makefile。找到UPROGS行,并将程序名(如_ticketlocktest)添加到列表中。这会告诉Makefile构建用户程序。找到构建用户程序的模式规则。它应该看起来像这样:

%: %.o $(ULIB) $(UUSYS)
    ... (other lines here)

更新规则以在链接时包含spinlock.o。更新后的规则应如下所示:

%: %.o $(ULIB) $(UUSYS) spinlock.o
    ... (other lines here, but with spinlock.o added)

保存Makefile,运行make clean,然后运行make qemu。这应该会将pushcli()和popcli()链接到你的程序并修复错误。请记住,这可能不是理想的解决方案,因为这些函数是为内核使用的,但它应该会让你解决链接问题。祝你好运!
回复:好吧,那么让我们尝试一种不同的方法来解决这个问题,而不干扰Makefile。你可以创建自己的函数来使用内联汇编在ulib. c文件中禁用和启用中断。下面是你如何做到的:

static inline void my_own_pushcli(void) {
  asm volatile("cli");
}

static inline void my_own_popcli(void) {
  asm volatile("sti");
}

现在,只需将lock_acquire和lock_release函数中的pushcli()和popcli()调用替换为my_own_pushcli()和my_own_popcli(),如下所示:

void lock_acquire(struct lock_t* lk) {
  my_own_pushcli();
  // ... the rest of your code
}

void lock_release(struct lock_t* lk) {
  // ... the rest of your code
  my_own_popcli();
}

这应该可以让你的代码编译,而不需要改变Makefile或链接其他.o文件。但是,嘿,只是一个提示:在用户程序中使用cli和sti可能不是最好的主意。当多个任务正在运行时,它可能会导致一些问题。因此,虽然这应该解决您当前的问题,但您可能需要查看用户程序的其他选项,如信号量,使用更安全。祝您好运,如果您需要更多帮助,请告诉我!

相关问题