Skip to content

Commit

Permalink
完善libc,构建了OS-specific工具链,编译了基于gcc-11.3.0的DragonOS userland compiler,移…
Browse files Browse the repository at this point in the history
…植了mpfr,gmp,mpc库 (DragonOS-Community#134)

* 修改include路径

* 添加了创建libsysapi.a和/bin/sysroot/usr/include/+lib/的代码

* 修补.gitignore

* 删除多余项

* 优化脚本可读性

* 新增crt0 crti crtn

* 编译binutils所需的东西

* fflush()和fprintf()的简单实现

* 应用程序启动前,调用初始化libc的函数

* 自动创建sysroot

* 添加了stderr的初始化

* 修改了stderr的初始化

* 内核添加对stdio的简略处理

* 格式化代码

* 修正打开stdio文件描述符的问题

* bugfix: 修复fprintf忘记释放buf的问题

* 修复shell错误地把入口设置为main而不是_start的问题

* 新增__cxa_atexit  (gcc要求libc提供这个)

* 增加putchar puts

* 更新写入磁盘镜像的脚本,默认无参数时,使用legacy方式安装

* 更新编译脚本

* stdio增加eof的定义

* 新增extern cplusplus

* mpfr gmp mpc 构建脚本

* 更新libsysapi.a为libc.a

* 加上ferror fopen fclose

* 更新移植的软件的构建脚本

* 更改build_gcc_toolchain.sh中的-save参数名为-save-cache

Co-authored-by: longjin <[email protected]>
  • Loading branch information
guanjinquan and fslongjin authored Jan 6, 2023
1 parent 61de2cd commit 2224c93
Show file tree
Hide file tree
Showing 49 changed files with 746 additions and 70 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ kernel/kernel
.DS_Store

*.o
*.a
*.s
serial_opt.txt
user/sys_api_lib
Expand Down
6 changes: 1 addition & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@ ifeq ($(DEBUG), DEBUG)
GLOBAL_CFLAGS += -g
endif

# ifeq ($(DragonOS_GCC), )
# $(error 尚未安装DragonOS交叉编译器, 请使用tools文件夹下的build_gcc_toolchain.sh脚本安装)
# endif

export CC=$(DragonOS_GCC)/x86_64-elf-gcc
export LD=ld
Expand All @@ -52,8 +49,7 @@ kernel:

.PHONY: user
user:
mkdir -p bin/user/
mkdir -p bin/tmp/user

@if [ -z $$DragonOS_GCC ]; then echo "\033[31m [错误]尚未安装DragonOS交叉编译器, 请使用tools文件夹下的build_gcc_toolchain.sh脚本安装 \033[0m"; exit 1; fi
$(MAKE) -C ./user all || (sh -c "echo 用户程序编译失败" && exit 1)

Expand Down
6 changes: 4 additions & 2 deletions kernel/src/process/fork.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned
// 唤醒进程
process_wakeup(tsk);

//创建对应procfs文件
// 创建对应procfs文件
procfs_register_pid(tsk->pid);

return retval;
Expand Down Expand Up @@ -188,8 +188,10 @@ int process_copy_files(uint64_t clone_flags, struct process_control_block *pcb)
if (clone_flags & CLONE_FS)
return retval;

// TODO: 这里是临时性的特殊处理stdio,待文件系统重构及tty设备实现后,需要改写这里
process_open_stdio(current_pcb);
// 为新进程拷贝新的文件描述符
for (int i = 0; i < PROC_MAX_FD_NUM; ++i)
for (int i = 3; i < PROC_MAX_FD_NUM; ++i)
{
if (current_pcb->fds[i] == NULL)
continue;
Expand Down
27 changes: 23 additions & 4 deletions kernel/src/process/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,8 @@ ul do_execve(struct pt_regs *regs, char *path, char *argv[], char *envp[])

// 关闭之前的文件描述符
process_exit_files(current_pcb);

process_open_stdio(current_pcb);

// 清除进程的vfork标志位
current_pcb->flags &= ~PF_VFORK;
Expand Down Expand Up @@ -640,6 +642,10 @@ void process_init()

// 初始化init进程的signal相关的信息
initial_proc_init_signal(current_pcb);

// TODO: 这里是临时性的特殊处理stdio,待文件系统重构及tty设备实现后,需要改写这里
process_open_stdio(current_pcb);

// 临时设置IDLE进程的的虚拟运行时间为0,防止下面的这些内核线程的虚拟运行时间出错
current_pcb->virtual_runtime = 0;
barrier();
Expand Down Expand Up @@ -724,11 +730,13 @@ int process_wakeup_immediately(struct process_control_block *pcb)
*/
uint64_t process_exit_files(struct process_control_block *pcb)
{
// TODO: 当stdio不再被以-1来特殊处理时,在这里要释放stdio文件的内存

// 不与父进程共享文件描述符
if (!(pcb->flags & PF_VFORK))
{

for (int i = 0; i < PROC_MAX_FD_NUM; ++i)
for (int i = 3; i < PROC_MAX_FD_NUM; ++i)
{
if (pcb->fds[i] == NULL)
continue;
Expand Down Expand Up @@ -843,15 +851,15 @@ int process_release_pcb(struct process_control_block *pcb)
int process_fd_alloc(struct vfs_file_t *file)
{
int fd_num = -1;
struct vfs_file_t **f = current_pcb->fds;

for (int i = 0; i < PROC_MAX_FD_NUM; ++i)
{
// kdebug("currentpcb->fds[%d]=%#018lx", i, current_pcb->fds[i]);
/* 找到指针数组中的空位 */
if (f[i] == NULL)
if (current_pcb->fds[i] == NULL)
{
fd_num = i;
f[i] = file;
current_pcb->fds[i] = file;
break;
}
}
Expand Down Expand Up @@ -882,3 +890,14 @@ void process_set_pcb_name(struct process_control_block *pcb, const char *pcb_nam
{
__set_pcb_name(pcb, pcb_name);
}

void process_open_stdio(struct process_control_block *pcb)
{
// TODO: 这里是临时性的特殊处理stdio,待文件系统重构及tty设备实现后,需要改写这里
// stdin
pcb->fds[0] = -1UL;
// stdout
pcb->fds[1] = -1UL;
// stderr
pcb->fds[2] = -1UL;
}
4 changes: 3 additions & 1 deletion kernel/src/process/process.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,4 +220,6 @@ extern int process_try_to_wake_up(struct process_control_block *_pcb, uint64_t _
* @return false 唤醒失败
*/
extern int process_wake_up_state(struct process_control_block *pcb, uint64_t state);
void __switch_to(struct process_control_block *prev, struct process_control_block *next);
void __switch_to(struct process_control_block *prev, struct process_control_block *next);

void process_open_stdio(struct process_control_block * pcb);
36 changes: 31 additions & 5 deletions kernel/src/syscall/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
#include <driver/disk/ahci/ahci.h>
#include <exception/gate.h>
#include <exception/irq.h>
#include <filesystem/vfs/VFS.h>
#include <filesystem/fat32/fat32.h>
#include <filesystem/vfs/VFS.h>
#include <mm/slab.h>
#include <process/process.h>
#include <time/sleep.h>
Expand All @@ -19,10 +19,10 @@ extern uint64_t sys_mstat(struct pt_regs *regs);
extern uint64_t sys_open(struct pt_regs *regs);
extern uint64_t sys_unlink_at(struct pt_regs *regs);
extern uint64_t sys_kill(struct pt_regs *regs);
extern uint64_t sys_sigaction(struct pt_regs * regs);
extern uint64_t sys_rt_sigreturn(struct pt_regs * regs);
extern uint64_t sys_getpid(struct pt_regs * regs);
extern uint64_t sys_sched(struct pt_regs * regs);
extern uint64_t sys_sigaction(struct pt_regs *regs);
extern uint64_t sys_rt_sigreturn(struct pt_regs *regs);
extern uint64_t sys_getpid(struct pt_regs *regs);
extern uint64_t sys_sched(struct pt_regs *regs);

/**
* @brief 导出系统调用处理函数的符号
Expand Down Expand Up @@ -173,6 +173,18 @@ uint64_t sys_read(struct pt_regs *regs)
if (count < 0)
return -EINVAL;

switch (fd_num)
{
case 0: // stdin
return 0;
break;
case 1: // stdout
return 0;
break;
case 2: // stderr
return 0;
break;
}
struct vfs_file_t *file_ptr = current_pcb->fds[fd_num];
uint64_t ret = 0;
if (file_ptr->file_ops && file_ptr->file_ops->read)
Expand Down Expand Up @@ -212,6 +224,20 @@ uint64_t sys_write(struct pt_regs *regs)
if (count < 0)
return -EINVAL;

switch (fd_num)
{
case 0: // stdin
return 0;
break;
case 1: // stdout
printk("%s", buf);
return count;
break;
case 2: // stderr
printk("%s", buf);
return count;
break;
}
struct vfs_file_t *file_ptr = current_pcb->fds[fd_num];
uint64_t ret = 0;
if (file_ptr->file_ops && file_ptr->file_ops->write)
Expand Down
21 changes: 14 additions & 7 deletions tools/build_gcc_toolchain.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,15 @@ KEEP_BINUTILS=0
KEEP_GCC=0
CHANGE_SOURCE=0
FORCE=0
SAVE_CACHE=0
while true; do
if [ ! -n "$1" ]; then
break
fi
case "$1" in
"-save-cache")
SAVE_CACHE=1
;;
"-rebuild")
echo "清除${INSTALL_POS}目录下的所有信息"
rm -rf "${INSTALL_POS}"
Expand All @@ -40,6 +44,7 @@ while true; do
;;
"-help")
echo "脚本选项如下:"
echo "-save-cache: 保留最后的下载压缩包"
echo "-rebuild: 清除上一次安装的全部信息, 即删掉$INSTALL_POS目录下的所有内容, 然后重新构建gcc工具链."
echo "-kg(keep-gcc): 您确保${STRUCTURE}-gcc已被编译安装, 本次调用脚本不重复编译安装gcc. 如果没有安装,脚本仍然会自动安装."
echo "-kb(keep-binutils): 您确保binutils已被编译安装, 本次调用脚本不重复编译安装binutils. 如果没有安装,脚本仍然会自动安装."
Expand Down Expand Up @@ -167,13 +172,15 @@ source "$HOME/.bashrc"
if [ -n "$(find $PREFIX/bin/* -name $TARGET_GCC)" ] &&
[ -n "$(find $PREFIX/bin/* -name $TARGET_LD)" ] &&
[ -n "$(find $PREFIX/bin/* -name $TARGET_AS)" ]; then
# 删除临时文件
rm -rf "$BIN_UTILS"
rm -rf "$BIN_UTILS_TAR"
rm -rf "build-binutils"
rm -rf "$GCC_FILE"
rm -rf "$GCC_FILE_TAR"
rm -rf "build-gcc"
if [ ${SAVE_CACHE} -eq 0 ]; then
# 删除临时文件
rm -rf "$BIN_UTILS"
rm -rf "$BIN_UTILS_TAR"
rm -rf "build-binutils"
rm -rf "$GCC_FILE"
rm -rf "$GCC_FILE_TAR"
rm -rf "build-gcc"
fi

echo -e "\033[42;37m [构建成功] Build Successfully.(请重新打开另一个Shell窗口或者重新打开你的IDE以获取新的环境变量) \033[0m"
else
Expand Down
5 changes: 4 additions & 1 deletion tools/write_disk_image.sh
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,10 @@ cp ${kernel} ${root_folder}/bin/disk_mount/boot
mkdir -p ${root_folder}/bin/disk_mount/bin
mkdir -p ${root_folder}/bin/disk_mount/dev
mkdir -p ${root_folder}/bin/disk_mount/proc
mkdir -p ${root_folder}/bin/disk_mount/usr
cp -r ${root_folder}/bin/user/* ${root_folder}/bin/disk_mount/bin
touch ${root_folder}/bin/disk_mount/dev/keyboard.dev
cp -r ${root_folder}/bin/sysroot/usr/* ${root_folder}/bin/disk_mount/usr/

# 设置 grub 相关数据
if [ ${ARCH} == "i386" ] || [ ${ARCH} == "x86_64" ]; then
Expand Down Expand Up @@ -121,7 +123,8 @@ case "$1" in
esac
;;
*)
echo "参数错误"
#传统bios
${GRUB_PATH_I386_LEGACY_INSTALL} --target=i386-pc --boot-directory=${boot_folder} /dev/$LOOP_DEVICE
;;

esac
Expand Down
22 changes: 19 additions & 3 deletions user/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ user_sub_dirs = apps

SUBDIR_ROOTS := .
DIRS := . $(shell find $(SUBDIR_ROOTS) -type d)
GARBAGE_PATTERNS := *.o *.s~ *.s *.S~ *.c~ *.h~ sys_api_lib
GARBAGE_PATTERNS := *.o *.s~ *.s *.S~ *.c~ *.h~ sys_api_lib *.a
GARBAGE := $(foreach DIR,$(DIRS),$(addprefix $(DIR)/,$(GARBAGE_PATTERNS)))


Expand All @@ -22,16 +22,32 @@ $(user_sub_dirs): ECHO sys_api_lib
app: $(user_sub_dirs)

all: app

$(shell if [ ! -e $(tmp_output_dir) ];then mkdir -p $(tmp_output_dir); fi)
$(shell if [ ! -e $(output_dir) ];then mkdir -p $(output_dir); fi)

@echo 用户态程序编译完成

make_output_dir: ECHO
mkdir -p $(ROOT_PATH)/bin/user/
mkdir -p $(ROOT_PATH)/bin/tmp/user
mkdir -p $(ROOT_PATH)/bin/sysroot/usr/include
mkdir -p $(ROOT_PATH)/bin/sysroot/usr/lib

$(shell if [ ! -e $(tmp_output_dir) ];then mkdir -p $(tmp_output_dir); fi)
$(shell if [ ! -e $(output_dir) ];then mkdir -p $(output_dir); fi)
# 系统库
sys_api_lib:
$(MAKE) -C libs all CFLAGS="$(CFLAGS)" tmp_output_dir="$(tmp_output_dir)" output_dir="$(output_dir)" sys_libs_dir="$(shell pwd)/libs"

sys_api_lib_stage_1: make_output_dir
@echo Building sys_api_lib...
$(MAKE) -C libs all CFLAGS="$(CFLAGS)" tmp_output_dir="$(tmp_output_dir)" output_dir="$(output_dir)" sys_libs_dir="$(shell pwd)/libs"


sys_api_lib: sys_api_lib_stage_1
$(AR) crvs $(ROOT_PATH)/bin/sysroot/usr/lib/libc.a $(shell find ./libs/* -name "*.o")
$(shell find ./libs/* -name "*.o" | xargs -I {} cp {} $(ROOT_PATH)/bin/sysroot/usr/lib/)
$(shell cp -r $(ROOT_PATH)/user/libs/libc/src/include/* $(ROOT_PATH)/bin/sysroot/usr/include/)
$(shell cp -r $(ROOT_PATH)/user/libs/libc/src/arch/x86_64/c*.o $(ROOT_PATH)/bin/sysroot/usr/lib/)

clean:
rm -rf $(GARBAGE)
Expand Down
2 changes: 1 addition & 1 deletion user/apps/shell/shell.lds
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

OUTPUT_FORMAT("elf64-x86-64","elf64-x86-64","elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(main)
ENTRY(_start)

SECTIONS
{
Expand Down
13 changes: 5 additions & 8 deletions user/libs/libc/src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@ CFLAGS += -I .
libc_sub_dirs=math sys

ifeq ($(ARCH), __x86_64__)
libc_sub_dirs += sysdeps/x86_64
libc_sub_dirs += arch/x86_64
endif

$(libc_sub_dirs): ECHO
$(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS) -I $(shell pwd)"

libc_objs:= $(shell find ./*.c)

ECHO:
Expand All @@ -29,13 +32,7 @@ clean:
cd .. ;\
done

libc: $(libc_objs) libc_rust
@list='$(libc_sub_dirs)'; for subdir in $$list; do \
echo "make all in $$subdir";\
cd $$subdir;\
$(MAKE) all CFLAGS="$(CFLAGS) -I $(shell pwd)";\
cd ..;\
done
libc: $(libc_objs) $(libc_sub_dirs) libc_rust

libc_rust:
rustup default nightly
Expand Down
23 changes: 23 additions & 0 deletions user/libs/libc/src/arch/x86_64/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
libc_arch_objs:= $(shell find ./*.c)

ECHO:
@echo "$@"


$(libc_arch_objs): ECHO
$(CC) $(CFLAGS) -c $@ -o $@.o

all: $(libc_arch_objs) crti.o crtn.o
mv crt0.c.o crt0.o

crti.o: crti.S
$(CC) -E crti.S > _crti.s # 预处理
$(AS) $(ASFLAGS) -o crti.o _crti.s

crtn.o: crtn.S
$(CC) -E crtn.S > _crtn.s # 预处理
$(AS) $(ASFLAGS) -o crtn.o _crtn.s

clean:

echo "Done."
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
#include <stdlib.h>

extern int main(int, char **);
extern void _init();
extern void _libc_init();

void _start(int argc, char **argv)
{
// printf("before main\n");
// Run the global constructors.
_init();
_libc_init();
int retval = main(argc, argv);
// printf("before exit, code=%d\n", retval);
exit(retval);
}
Loading

0 comments on commit 2224c93

Please sign in to comment.