我正在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'
pushcli
和popcli
是在spinlock.c
中定义的函数。下面是xv6源代码:xv6 source code
我猜问题出在Makefile
上,但我没有修复它的线索。
1条答案
按热度按时间oxcyiej71#
看起来你试图在ulib. c文件中使用spinlock. c中的pushcli()和popcli(),但在编译过程中它们没有正确链接。让我来帮助你。
要解决这个问题,您需要编辑xv 6目录中的Makefile。请按照以下步骤操作:
打开Makefile。找到UPROGS行,并将程序名(如_ticketlocktest)添加到列表中。这会告诉Makefile构建用户程序。找到构建用户程序的模式规则。它应该看起来像这样:
更新规则以在链接时包含spinlock.o。更新后的规则应如下所示:
保存Makefile,运行make clean,然后运行make qemu。这应该会将pushcli()和popcli()链接到你的程序并修复错误。请记住,这可能不是理想的解决方案,因为这些函数是为内核使用的,但它应该会让你解决链接问题。祝你好运!
回复:好吧,那么让我们尝试一种不同的方法来解决这个问题,而不干扰Makefile。你可以创建自己的函数来使用内联汇编在ulib. c文件中禁用和启用中断。下面是你如何做到的:
现在,只需将lock_acquire和lock_release函数中的pushcli()和popcli()调用替换为my_own_pushcli()和my_own_popcli(),如下所示:
这应该可以让你的代码编译,而不需要改变Makefile或链接其他.o文件。但是,嘿,只是一个提示:在用户程序中使用cli和sti可能不是最好的主意。当多个任务正在运行时,它可能会导致一些问题。因此,虽然这应该解决您当前的问题,但您可能需要查看用户程序的其他选项,如信号量,使用更安全。祝您好运,如果您需要更多帮助,请告诉我!