移除relibc和old libc以及旧的shell (#529)

移除relibc和old libc以及旧的shell
This commit is contained in:
裕依 2024-03-04 14:20:01 +08:00 committed by GitHub
parent f3b05a97ec
commit bc6f0a967c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
141 changed files with 334 additions and 8836 deletions

View File

@ -31,7 +31,6 @@ jobs:
ARCH: ${{ matrix.arch }} ARCH: ${{ matrix.arch }}
run: | run: |
printf "\n" >> kernel/src/include/bindings/bindings.rs printf "\n" >> kernel/src/include/bindings/bindings.rs
printf "\n" >> user/libs/libc/src/include/internal/bindings/bindings.rs
FMT_CHECK=1 make fmt FMT_CHECK=1 make fmt
kernel-static-test: kernel-static-test:

2
.gitignore vendored
View File

@ -10,8 +10,8 @@ kernel/kernel
*.o *.o
*.a *.a
*.s *.s
out
serial_opt.txt serial_opt.txt
user/sys_api_lib
docs/_build docs/_build
draft draft
cppcheck.xml cppcheck.xml

View File

@ -20,8 +20,6 @@ unsafe extern "C" fn x86_64_do_irq(trap_frame: &mut TrapFrame, vector: u32) {
if trap_frame.from_user() { if trap_frame.from_user() {
x86_64::registers::segmentation::GS::swap(); x86_64::registers::segmentation::GS::swap();
// 拒绝用户态中断
return;
} }
// 由于x86上面虚拟中断号与物理中断号是一一对应的所以这里直接使用vector作为中断号来查询irqdesc // 由于x86上面虚拟中断号与物理中断号是一一对应的所以这里直接使用vector作为中断号来查询irqdesc

View File

@ -115,7 +115,6 @@ mkdir -p ${root_folder}/bin/disk_mount/bin
mkdir -p ${root_folder}/bin/disk_mount/dev mkdir -p ${root_folder}/bin/disk_mount/dev
mkdir -p ${root_folder}/bin/disk_mount/proc mkdir -p ${root_folder}/bin/disk_mount/proc
mkdir -p ${root_folder}/bin/disk_mount/usr 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 touch ${root_folder}/bin/disk_mount/dev/keyboard.dev
cp -r ${root_folder}/bin/sysroot/* ${root_folder}/bin/disk_mount/ cp -r ${root_folder}/bin/sysroot/* ${root_folder}/bin/disk_mount/

1
user/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/libs/

View File

@ -2,24 +2,14 @@ user_sub_dirs = apps
SUBDIR_ROOTS := . SUBDIR_ROOTS := .
DIRS := . $(shell find $(SUBDIR_ROOTS) -type d) DIRS := . $(shell find $(SUBDIR_ROOTS) -type d)
GARBAGE_PATTERNS := *.o sys_api_lib *.a GARBAGE_PATTERNS := *.o *.a
GARBAGE := $(foreach DIR,$(DIRS),$(addprefix $(DIR)/,$(GARBAGE_PATTERNS))) GARBAGE := $(foreach DIR,$(DIRS),$(addprefix $(DIR)/,$(GARBAGE_PATTERNS)))
tmp_output_dir=$(ROOT_PATH)/bin/tmp/user
output_dir=$(ROOT_PATH)/bin/user
CFLAGS := $(GLOBAL_CFLAGS) -I $(shell pwd)/libs -I $(shell pwd)/libs/libc/src/include -I $(shell pwd)/libs/libc/src/include/export
current_CFLAGS := $(CFLAGS)
DADK_VERSION=$(shell dadk -V | awk 'END {print $$2}') DADK_VERSION=$(shell dadk -V | awk 'END {print $$2}')
# 最小的DADK版本 # 最小的DADK版本
MIN_DADK_VERSION = 0.1.6 MIN_DADK_VERSION = 0.1.8
DADK_CACHE_DIR = $(ROOT_PATH)/bin/dadk_cache DADK_CACHE_DIR = $(ROOT_PATH)/bin/dadk_cache
# 旧版的libc安装路径
OLD_LIBC_INSTALL_PATH=$(ROOT_PATH)/bin/sysroot/usr/old_libc
ECHO: ECHO:
@echo "$@" @echo "$@"
@ -56,58 +46,29 @@ dadk_run: install_dadk
.PHONY: dadk_clean .PHONY: dadk_clean
dadk_clean: install_dadk dadk_clean: install_dadk
@echo dadk_clean
# 不运行dadk clean的原因是把clean的工作交给应用程序自己去做这样可以节省编译时间 # 不运行dadk clean的原因是把clean的工作交给应用程序自己去做这样可以节省编译时间
#dadk --config-dir dadk/config --cache-dir $(DADK_CACHE_DIR) --dragonos-dir $(ROOT_PATH)/bin/sysroot clean src #dadk --config-dir dadk/config --cache-dir $(DADK_CACHE_DIR) --dragonos-dir $(ROOT_PATH)/bin/sysroot clean src
#dadk --config-dir dadk/config --cache-dir $(DADK_CACHE_DIR) --dragonos-dir $(ROOT_PATH)/bin/sysroot clean target #dadk --config-dir dadk/config --cache-dir $(DADK_CACHE_DIR) --dragonos-dir $(ROOT_PATH)/bin/sysroot clean target
$(user_sub_dirs): ECHO sys_api_lib all:
mkdir -p $(ROOT_PATH)/bin/sysroot
$(MAKE) -C $@ all CFLAGS="$(CFLAGS)" tmp_output_dir="$(tmp_output_dir)" output_dir="$(output_dir)" sys_libs_dir="$(shell pwd)/libs" $(MAKE) dadk_run
$(MAKE) copy_services
@echo 用户态程序编译完成
copy_services: dadk_run copy_services: dadk_run
cp -r services/* $(ROOT_PATH)/bin/sysroot/etc/reach/system/ cp -r services/* $(ROOT_PATH)/bin/sysroot/etc/reach/system/
app: $(user_sub_dirs) dadk_run copy_services
all: make_output_dir
$(MAKE) app
@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_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
# 打包系统库
mkdir -p $(ROOT_PATH)/bin/tmp/user/sys_api_lib_build_tmp
mkdir -p $(OLD_LIBC_INSTALL_PATH)/include
mkdir -p $(OLD_LIBC_INSTALL_PATH)/lib
$(AR) x libs/libc/target/x86_64-unknown-none/release/liblibc.a --output=$(ROOT_PATH)/bin/tmp/user/sys_api_lib_build_tmp
$(AR) crvs $(OLD_LIBC_INSTALL_PATH)/lib/libc.a $(shell find ./libs/* -name "*.o") $(shell find $(ROOT_PATH)/bin/tmp/user/sys_api_lib_build_tmp/* -name "*.o")
rm -rf $(ROOT_PATH)/bin/tmp/user/sys_api_lib_build_tmp
# $(shell find ./libs/* -name "*.o" | xargs -I {} cp {} $(ROOT_PATH)/bin/sysroot/usr/lib/)
$(shell cp -r $(ROOT_PATH)/user/libs/libc/src/include/export/* $(OLD_LIBC_INSTALL_PATH)/include/)
$(shell cp -r $(ROOT_PATH)/user/libs/libc/src/arch/x86_64/c*.o $(OLD_LIBC_INSTALL_PATH)/lib/)
.PHONY: clean .PHONY: clean
clean: clean:
rm -rf $(GARBAGE) rm -rf $(GARBAGE)
$(MAKE) dadk_clean $(MAKE) dadk_clean
$(MAKE) clean -C libs
@list='$(user_sub_dirs)'; for subdir in $$list; do \ @list='$(user_sub_dirs)'; for subdir in $$list; do \
echo "Clean in dir: $$subdir";\ echo "Clean in dir: $$subdir";\
cd $$subdir && $(MAKE) clean;\ cd $$subdir && $(MAKE) clean;\
@ -116,5 +77,4 @@ clean:
.PHONY: fmt .PHONY: fmt
fmt: fmt:
FMT_CHECK=$(FMT_CHECK) $(MAKE) -C libs FMT_CHECK=$(FMT_CHECK) $(MAKE) -C apps fmt
FMT_CHECK=$(FMT_CHECK) $(MAKE) -C apps

View File

@ -1,15 +1,13 @@
sub_dirs = $(wildcard */)
user_apps_sub_dirs=shell about test_kvm
ECHO:
@echo "$@"
$(user_apps_sub_dirs): ECHO
$(MAKE) -C $@ all CFLAGS="$(CFLAGS)" tmp_output_dir="$(tmp_output_dir)" output_dir="$(output_dir)" sys_libs_dir="$(sys_libs_dir)"
all: $(user_apps_sub_dirs)
.PHONY: clean .PHONY: clean
clean:
@list='$(sub_dirs)'; for subdir in $$list; do \
$(MAKE) -C $$subdir clean;\
done
.PHONY: fmt
fmt: fmt:
@echo "格式化代码: user/apps" @list='$(sub_dirs)'; for subdir in $$list; do \
FMT_CHECK=$(FMT_CHECK) $(MAKE) -C $$subdir fmt;\
done

View File

@ -1 +1,2 @@
sys_version.h sys_version.h
about

View File

@ -1,17 +1,26 @@
OLD_LIBC_INSTALL_PATH=$(ROOT_PATH)/bin/sysroot/usr/old_libc ifeq ($(ARCH), x86_64)
CROSS_COMPILE=x86_64-linux-musl-
else ifeq ($(ARCH), riscv64)
CROSS_COMPILE=riscv64-linux-musl-
endif
# 获得当前git提交的sha1,并截取前8位 # 获得当前git提交的sha1,并截取前8位
GIT_COMMIT_SHA1=$(shell git log -n 1 | head -n 1 | cut -d ' ' -f 2 | cut -c1-8) GIT_COMMIT_SHA1=$(shell git log -n 1 | head -n 1 | cut -d ' ' -f 2 | cut -c1-8)
CC=$(CROSS_COMPILE)gcc
all: about.o
$(LD) -b elf64-x86-64 -z muldefs -o $(tmp_output_dir)/about $(shell find . -name "*.o") $(OLD_LIBC_INSTALL_PATH)/lib/libc.a -T about.lds all: version_header about.c
$(CC) -static -o about about.c
$(OBJCOPY) -I elf64-x86-64 -R ".eh_frame" -R ".comment" -O elf64-x86-64 $(tmp_output_dir)/about $(output_dir)/about.elf .PHONY: install clean
install: all
mv about $(DADK_CURRENT_BUILD_DIR)/about.elf
about.o: version_header about.c clean:
$(CC) $(CFLAGS) -c about.c -o about.o rm about *.o
# 生成版本头文件sys_version.h # 生成版本头文件sys_version.h
version_header: about.c version_header: about.c
@echo "#define DRAGONOS_GIT_COMMIT_SHA1 \"$(GIT_COMMIT_SHA1)\"" > sys_version.h @echo "#define DRAGONOS_GIT_COMMIT_SHA1 \"$(GIT_COMMIT_SHA1)\"" > sys_version.h
fmt:

View File

@ -1,9 +1,7 @@
#include "sys_version.h" // 这是系统的版本头文件,在编译过程中自动生成 #include "sys_version.h" // 这是系统的版本头文件,在编译过程中自动生成
#include <math.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h> #include <unistd.h>
void print_ascii_logo() void print_ascii_logo()
{ {
printf(" ____ ___ ____ \n"); printf(" ____ ___ ____ \n");
@ -13,24 +11,25 @@ void print_ascii_logo()
printf("|____/ |_| \\__,_| \\__, | \\___/ |_| |_| \\___/ |____/ \n"); printf("|____/ |_| \\__,_| \\__, | \\___/ |_| |_| \\___/ |____/ \n");
printf(" |___/ \n"); printf(" |___/ \n");
} }
void print_copyright() void print_copyright()
{ {
printf(" DragonOS - An opensource operating system.\n"); printf(" DragonOS - An opensource operating system.\n");
printf(" Copyright: DragonOS Community. 2022-2024, All rights reserved.\n"); printf(" Copyright: DragonOS Community. 2022-2024, All rights reserved.\n");
printf(" Version: "); printf(" Version: ");
put_string("V0.1.8\n", COLOR_GREEN, COLOR_BLACK); printf("\033[1;32m%s\033[0m", "V0.1.8\n");
printf(" Git commit SHA1: %s\n", DRAGONOS_GIT_COMMIT_SHA1); printf(" Git commit SHA1: %s\n", DRAGONOS_GIT_COMMIT_SHA1);
printf(" Build time: %s %s\n", __DATE__, __TIME__); printf(" Build time: %s %s\n", __DATE__, __TIME__);
printf(" \nYou can visit the project via:\n"); printf(" \nYou can visit the project via:\n");
printf("\n"); printf("\n");
put_string(" Official Website: https://DragonOS.org\n", COLOR_INDIGO, COLOR_BLACK); printf("\x1B[1;36m%s\x1B[0m", " Official Website: https://DragonOS.org\n");
put_string(" GitHub: https://github.com/DragonOS-Community/DragonOS\n", COLOR_ORANGE, COLOR_BLACK); printf("\x1B[1;33m%s\x1B[0m", " GitHub: https://github.com/DragonOS-Community/DragonOS\n");
printf("\n"); printf("\n");
printf(" Maintainer: longjin <longjin@DragonOS.org>\n"); printf(" Maintainer: longjin <longjin@DragonOS.org>\n");
printf(" Get contact with the community: <contact@DragonOS.org>\n"); printf(" Get contact with the community: <contact@DragonOS.org>\n");
printf("\n"); printf("\n");
printf(" Join our development community:\n"); printf(" Join our development community:\n");
put_string(" https://bbs.dragonos.org.cn\n", COLOR_ORANGE, COLOR_BLACK); printf("\x1B[1;33m%s\x1B[0m", " https://bbs.dragonos.org.cn\n");
printf("\n"); printf("\n");
} }

View File

@ -1,54 +0,0 @@
OUTPUT_FORMAT("elf64-x86-64","elf64-x86-64","elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(_start)
SECTIONS
{
. = 0x800000;
.text :
{
_text = .;
*(.text)
*(.text.*)
_etext = .;
}
. = ALIGN(8);
.data :
{
_data = .;
*(.data)
*(.data.*)
_edata = .;
}
rodata_start_pa = .;
.rodata :
{
_rodata = .;
*(.rodata)
*(.rodata.*)
_erodata = .;
}
.bss :
{
_bss = .;
*(.bss)
*(.bss.*)
_ebss = .;
}
_end = .;
}

View File

@ -1,17 +1,20 @@
ifeq ($(ARCH), x86_64) ifeq ($(ARCH), x86_64)
export PREFIX=x86_64-linux-musl- CROSS_COMPILE=x86_64-linux-musl-
else ifeq ($(ARCH), riscv64) else ifeq ($(ARCH), riscv64)
export PREFIX=riscv64-linux-musl- CROSS_COMPILE=riscv64-linux-musl-
endif endif
CC=$(CROSS_COMPILE)gcc
export CC=$(PREFIX)gcc
all: dmesg all: main.c dmesg.c
mv dmesg $(DADK_CURRENT_BUILD_DIR)
dmesg: main.c
$(CC) -static -o dmesg main.c dmesg.c $(CC) -static -o dmesg main.c dmesg.c
.PHONY: install clean
install: all
mv dmesg $(DADK_CURRENT_BUILD_DIR)/dmesg
clean: clean:
rm dmesg *.o rm dmesg *.o
fmt:

View File

@ -1,4 +1,6 @@
#include "dmesg.h" #include "dmesg.h"
#include <stdio.h>
#include <string.h>
/** /**
* @brief dmesg程序的第一个选项参数 * @brief dmesg程序的第一个选项参数
@ -6,7 +8,7 @@
* @param arg dmesg命令第一个选项参数 * @param arg dmesg命令第一个选项参数
* @return int -1 * @return int -1
*/ */
int getopt(char *arg) int getoption(char *arg)
{ {
if (!strcmp(arg, "-h") || !strcmp(arg, "--help")) if (!strcmp(arg, "-h") || !strcmp(arg, "--help"))
return 0; return 0;

View File

@ -1,16 +1,12 @@
#pragma once #pragma once
#include <stdio.h>
#include <malloc.h>
#include <string.h>
/** /**
* @brief dmesg程序的第一个选项参数 * @brief dmesg程序的第一个选项参数
* *
* @param arg dmesg命令第一个选项参数 * @param arg dmesg命令第一个选项参数
* @return int -1 * @return int -1
*/ */
int getopt(char *arg); int getoption(char *arg);
/** /**
* @brief dmesg程序的第二个选项参数 * @brief dmesg程序的第二个选项参数

View File

@ -1,4 +1,8 @@
#include "dmesg.h" #include "dmesg.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/klog.h>
#include <unistd.h>
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
@ -30,7 +34,7 @@ int main(int argc, char **argv)
else else
{ {
// 获取第一个选项参数 // 获取第一个选项参数
opt = getopt(argv[1]); opt = getoption(argv[1]);
// 无效参数 // 无效参数
if (opt == -1) if (opt == -1)

1
user/apps/http_server/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
http_server

View File

@ -1,27 +1,20 @@
CC=$(DragonOS_GCC)/x86_64-elf-gcc ifeq ($(ARCH), x86_64)
LD=ld CROSS_COMPILE=x86_64-linux-musl-
OBJCOPY=objcopy else ifeq ($(ARCH), riscv64)
# 修改这里把它改为你的relibc的sysroot路径 CROSS_COMPILE=riscv64-linux-musl-
RELIBC_OPT=$(DADK_BUILD_CACHE_DIR_RELIBC_0_1_0) endif
CFLAGS=-I $(RELIBC_OPT)/include -D__dragonos__
tmp_output_dir=$(ROOT_PATH)/bin/tmp/user CC=$(CROSS_COMPILE)gcc
output_dir=$(DADK_BUILD_CACHE_DIR_HTTP_SERVER_0_1_0)
LIBC_OBJS:=$(shell find $(RELIBC_OPT)/lib -name "*.o" | sort ) .PHONY: all
LIBC_OBJS+=$(RELIBC_OPT)/lib/libc.a all: main.c
$(CC) -static -o http_server main.c
all: main.o .PHONY: install clean
mkdir -p $(tmp_output_dir) install: all
mv http_server $(DADK_CURRENT_BUILD_DIR)/http_server
$(LD) -b elf64-x86-64 -z muldefs -o $(tmp_output_dir)/http_server $(shell find . -name "*.o") $(LIBC_OBJS) -T link.lds
$(OBJCOPY) -I elf64-x86-64 -R ".eh_frame" -R ".comment" -O elf64-x86-64 $(tmp_output_dir)/http_server $(output_dir)/http_server.elf
mv $(output_dir)/http_server.elf $(output_dir)/http_server
main.o: main.c
$(CC) $(CFLAGS) -c main.c -o main.o
clean: clean:
rm -f *.o rm http_server *.o
fmt:

View File

@ -1,239 +0,0 @@
/* Script for -z combreloc */
/* Copyright (C) 2014-2020 Free Software Foundation, Inc.
Copying and distribution of this script, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. */
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64",
"elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(_start)
SECTIONS
{
/* Read-only sections, merged into text segment: */
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x20000000) + SIZEOF_HEADERS;
.interp : { *(.interp) }
.note.gnu.build-id : { *(.note.gnu.build-id) }
.hash : { *(.hash) }
.gnu.hash : { *(.gnu.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rela.dyn :
{
*(.rela.init)
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
*(.rela.fini)
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
*(.rela.ctors)
*(.rela.dtors)
*(.rela.got)
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
*(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*)
*(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*)
*(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*)
*(.rela.ifunc)
}
.rela.plt :
{
*(.rela.plt)
PROVIDE_HIDDEN (__rela_iplt_start = .);
*(.rela.iplt)
PROVIDE_HIDDEN (__rela_iplt_end = .);
}
. = ALIGN(CONSTANT (MAXPAGESIZE));
.init :
{
KEEP (*(SORT_NONE(.init)))
}
.plt : { *(.plt) *(.iplt) }
.plt.got : { *(.plt.got) }
.plt.sec : { *(.plt.sec) }
.text :
{
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text.exit .text.exit.*)
*(.text.startup .text.startup.*)
*(.text.hot .text.hot.*)
*(.text .stub .text.* .gnu.linkonce.t.*)
/* .gnu.warning sections are handled specially by elf.em. */
*(.gnu.warning)
}
.fini :
{
KEEP (*(SORT_NONE(.fini)))
}
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
. = ALIGN(CONSTANT (MAXPAGESIZE));
/* Adjust the address for the rodata segment. We want to adjust up to
the same address within the page on the next page up. */
. = SEGMENT_START("rodata-segment", ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)));
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
.rodata1 : { *(.rodata1) }
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) }
/* These sections are generated by the Sun/Oracle C++ compiler. */
.exception_ranges : ONLY_IF_RO { *(.exception_ranges*) }
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
/* Exception handling */
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }
.gnu_extab : ONLY_IF_RW { *(.gnu_extab) }
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
.exception_ranges : ONLY_IF_RW { *(.exception_ranges*) }
/* Thread Local Storage sections */
.tdata :
{
PROVIDE_HIDDEN (__tdata_start = .);
*(.tdata .tdata.* .gnu.linkonce.td.*)
}
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
}
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
}
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
}
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
}
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
}
.jcr : { KEEP (*(.jcr)) }
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
.dynamic : { *(.dynamic) }
.got : { *(.got) *(.igot) }
. = DATA_SEGMENT_RELRO_END (SIZEOF (.got.plt) >= 24 ? 24 : 0, .);
.got.plt : { *(.got.plt) *(.igot.plt) }
.data :
{
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
}
.data1 : { *(.data1) }
_edata = .; PROVIDE (edata = .);
. = .;
__bss_start = .;
.bss :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections.
FIXME: Why do we need it? When there is no .bss section, we do not
pad the .data section. */
. = ALIGN(. != 0 ? 64 / 8 : 1);
}
.lbss :
{
*(.dynlbss)
*(.lbss .lbss.* .gnu.linkonce.lb.*)
*(LARGE_COMMON)
}
. = ALIGN(64 / 8);
. = SEGMENT_START("ldata-segment", .);
.lrodata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
{
*(.lrodata .lrodata.* .gnu.linkonce.lr.*)
}
.ldata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
{
*(.ldata .ldata.* .gnu.linkonce.l.*)
. = ALIGN(. != 0 ? 64 / 8 : 1);
}
. = ALIGN(64 / 8);
_end = .; PROVIDE (end = .);
. = DATA_SEGMENT_END (.);
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
.gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* DWARF 3 */
.debug_pubtypes 0 : { *(.debug_pubtypes) }
.debug_ranges 0 : { *(.debug_ranges) }
/* DWARF Extension. */
.debug_macro 0 : { *(.debug_macro) }
.debug_addr 0 : { *(.debug_addr) }
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
}

View File

@ -1,18 +0,0 @@
OLD_LIBC_INSTALL_PATH=$(ROOT_PATH)/bin/sysroot/usr/old_libc
all: shell.o cmd.o cmd_help.o cmd_test.o
$(LD) -b elf64-x86-64 -z muldefs -o $(tmp_output_dir)/shell $(shell find . -name "*.o") $(OLD_LIBC_INSTALL_PATH)/lib/libc.a -T shell.lds
$(OBJCOPY) -I elf64-x86-64 -R ".eh_frame" -R ".comment" -O elf64-x86-64 $(tmp_output_dir)/shell $(output_dir)/shell.elf
shell.o: shell.c
$(CC) $(CFLAGS) -c shell.c -o shell.o
cmd.o: cmd.c
$(CC) $(CFLAGS) -c cmd.c -o cmd.o
cmd_test.o: cmd_test.c
$(CC) $(CFLAGS) -c cmd_test.c -o cmd_test.o
cmd_help.o: cmd_help.c
$(CC) $(CFLAGS) -c cmd_help.c -o cmd_help.o

View File

@ -1,679 +0,0 @@
#include "cmd.h"
#include "cmd_help.h"
#include "cmd_test.h"
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <libsystem/syscall.h>
#include <signal.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
#define MAX_PATH_LEN 4096
// 当前工作目录在main_loop中初始化
char *shell_current_path = NULL;
/**
* @brief shell
*
*/
struct built_in_cmd_t shell_cmds[] = {
{"cd", shell_cmd_cd},
{"cat", shell_cmd_cat},
{"exec", shell_cmd_exec},
{"ls", shell_cmd_ls},
{"mkdir", shell_cmd_mkdir},
{"pwd", shell_cmd_pwd},
{"rm", shell_cmd_rm},
{"rmdir", shell_cmd_rmdir},
{"reboot", shell_cmd_reboot},
{"touch", shell_cmd_touch},
{"about", shell_cmd_about},
{"free", shell_cmd_free},
{"help", shell_help},
{"pipe", shell_pipe_test},
{"pipe2", shell_pipe2_test},
{"kill", shell_cmd_kill},
};
// 总共的内建命令数量
const static int total_built_in_cmd_num = sizeof(shell_cmds) / sizeof(struct built_in_cmd_t);
/**
* @brief cwd与文件名进行拼接
*
* @param filename
* @param result_path_len
* @return char*
*/
static char *get_target_filepath(const char *filename, int *result_path_len)
{
char *file_path = NULL;
if (filename[0] != '/')
{
int cwd_len = strlen(shell_current_path);
// 计算文件完整路径的长度
*result_path_len = cwd_len + strlen(filename);
file_path = (char *)malloc(*result_path_len + 2);
memset(file_path, 0, *result_path_len + 2);
strncpy(file_path, shell_current_path, cwd_len);
// 在文件路径中加入斜杠
if (cwd_len > 1)
file_path[cwd_len] = '/';
// 拼接完整路径
strcat(file_path, filename);
}
else
{
*result_path_len = strlen(filename);
file_path = (char *)malloc(*result_path_len + 2);
memset(file_path, 0, *result_path_len + 2);
strncpy(file_path, filename, *result_path_len);
if (filename[(*result_path_len) - 1] != '/')
file_path[*result_path_len] = '/';
}
return file_path;
}
/**
* @brief
*
* @param main_cmd
* @return int
* -1
*/
int shell_find_cmd(char *main_cmd)
{
for (int i = 0; i < total_built_in_cmd_num; ++i)
{
if (strcmp(main_cmd, shell_cmds[i].name) == 0) // 找到对应的命令号
return i;
}
// 找不到该命令
return -1;
}
/**
* @brief shell内建的命令
*
* @param index
* @param argc
* @param argv
*/
void shell_run_built_in_command(int index, int argc, char **argv)
{
if (index >= total_built_in_cmd_num)
return;
// printf("run built-in command : %s\n", shell_cmds[index].name);
shell_cmds[index].func(argc, argv);
}
/**
* @brief cd命令:
*
* @param argc
* @param argv
* @return int
*/
int shell_cmd_cd(int argc, char **argv)
{
int current_dir_len = strlen(shell_current_path);
if (argc < 2)
{
shell_help_cd();
goto done;
}
// 进入当前文件夹
if (!strcmp(".", argv[1]))
goto done;
// 进入父目录
if (!strcmp("..", argv[1]))
{
// 当前已经是根目录
if (!strcmp("/", shell_current_path))
goto done;
// 返回到父目录
int index = current_dir_len - 1;
for (; index > 1; --index)
{
if (shell_current_path[index] == '/')
break;
}
shell_current_path[index] = '\0';
// printf("switch to \" %s \"\n", shell_current_path);
goto done;
}
int dest_len = strlen(argv[1]);
// 路径过长
if (dest_len >= SHELL_CWD_MAX_SIZE - 1)
{
printf("ERROR: Path too long!\n");
goto fail;
}
if (argv[1][0] == '/')
{
// ======进入绝对路径=====
int ec = chdir(argv[1]);
if (ec == -1)
ec = errno;
if (ec == 0)
{
// 获取新的路径字符串
char *new_path = (char *)malloc(MAX_PATH_LEN);
if (new_path==NULL) {
goto fail;
}
memset(new_path, 0, MAX_PATH_LEN);
getcwd(new_path, MAX_PATH_LEN);
// 释放原有的路径字符串的内存空间
free(shell_current_path);
shell_current_path = new_path;
return 0;
}
else
goto fail;
; // 出错则直接忽略
}
else // ======进入相对路径=====
{
int dest_offset = 0;
if (dest_len > 2)
{
if (argv[1][0] == '.' && argv[1][1] == '/') // 相对路径
dest_offset = 2;
}
int new_len = current_dir_len + dest_len - dest_offset;
if (new_len >= SHELL_CWD_MAX_SIZE - 1)
{
printf("ERROR: Path too long!\n");
goto fail;
}
// 拼接出新的字符串
char *new_path = (char *)malloc(new_len + 2);
memset(new_path, 0, new_len);
strncpy(new_path, shell_current_path, current_dir_len);
if (current_dir_len > 1)
new_path[current_dir_len] = '/';
strcat(new_path, argv[1] + dest_offset);
int x = chdir(new_path);
if (x == 0) // 成功切换目录
{
free(new_path);
free(shell_current_path);
char * pwd = malloc(MAX_PATH_LEN);
if (pwd==NULL) {
goto fail;
}
memset(pwd, 0, MAX_PATH_LEN);
getcwd(pwd, MAX_PATH_LEN);
shell_current_path = pwd;
goto done;
}
else
{
free(new_path);
printf("ERROR: Cannot switch to directory: %s\n", new_path);
goto fail;
}
}
fail:;
done:;
// 释放参数所占的内存
free(argv);
return 0;
}
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
int shell_cmd_ls(int argc, char **argv)
{
struct DIR *dir = opendir(shell_current_path);
if (dir == NULL)
return -1;
struct dirent *buf = NULL;
// printf("dir=%#018lx\n", dir);
while (1)
{
buf = readdir(dir);
if (buf == NULL)
break;
int color = COLOR_WHITE;
if (buf->d_type == DT_DIR)
color = COLOR_YELLOW;
else if (buf->d_type == DT_REG)
color = COLOR_INDIGO;
else if (buf->d_type == DT_BLK || buf->d_type == DT_CHR)
color = COLOR_GREEN;
char output_buf[256] = {0};
sprintf(output_buf, "%s ", buf->d_name);
put_string(output_buf, color, COLOR_BLACK);
}
printf("\n");
closedir(dir);
if (argv != NULL)
free(argv);
return 0;
}
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
int shell_cmd_pwd(int argc, char **argv)
{
if (shell_current_path)
printf("%s\n", shell_current_path);
if (argv != NULL)
free(argv);
return 0;
}
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
int shell_cmd_cat(int argc, char **argv)
{
int path_len = 0;
char *file_path = get_target_filepath(argv[1], &path_len);
// 打开文件
int fd = open(file_path, O_RDONLY);
if (fd <= 0)
{
printf("ERROR: Cannot open file: %s, fd=%d\n", file_path, fd);
return -1;
}
// 获取文件总大小
int file_size = lseek(fd, 0, SEEK_END);
// 将文件指针切换回文件起始位置
lseek(fd, 0, SEEK_SET);
char *buf = (char *)malloc(512);
while (file_size > 0)
{
memset(buf, 0, 512);
int l = read(fd, buf, 511);
if (l < 0)
{
printf("ERROR: Cannot read file: %s, errno = %d\n", file_path, errno);
return -1;
}
if (l == 0)
break;
buf[l] = '\0';
file_size -= l;
printf("%s", buf);
}
close(fd);
free(buf);
free(file_path);
if (argv != NULL)
free(argv);
return 0;
}
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
int shell_cmd_touch(int argc, char **argv)
{
int path_len = 0;
char *file_path;
bool alloc_full_path = false;
if (argv[1][0] == '/')
file_path = argv[1];
else
{
file_path = get_target_filepath(argv[1], &path_len);
alloc_full_path = true;
}
// 打开文件
int fd = open(file_path, O_CREAT);
switch (fd)
{
case -ENOENT:
put_string("Parent dir not exists.\n", COLOR_RED, COLOR_BLACK);
break;
default:
break;
}
close(fd);
if (argv != NULL)
free(argv);
if (alloc_full_path)
free(file_path);
return 0;
}
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
int shell_cmd_mkdir(int argc, char **argv)
{
int result_path_len = -1;
char *full_path = NULL;
bool alloc_full_path = false;
if (argv[1][0] == '/')
full_path = argv[1];
else
{
full_path = get_target_filepath(argv[1], &result_path_len);
alloc_full_path = true;
}
// printf("mkdir: full_path = %s\n", full_path);
int retval = mkdir(full_path, 0);
if (argv != NULL)
free(argv);
if (alloc_full_path)
free(full_path);
return retval;
}
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
int shell_cmd_rmdir(int argc, char **argv)
{
char *full_path = NULL;
int result_path_len = -1;
bool alloc_full_path = false;
if (argv[1][0] == '/')
full_path = argv[1];
else
{
full_path = get_target_filepath(argv[1], &result_path_len);
alloc_full_path = true;
}
int retval = rmdir(full_path);
if (retval != 0)
printf("Failed to remove %s, retval=%d\n", full_path, retval);
// printf("rmdir: path=%s, retval=%d\n", full_path, retval);
if (argv != NULL)
free(argv);
if (alloc_full_path)
free(full_path);
return retval;
}
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
int shell_cmd_rm(int argc, char **argv)
{
char *full_path = NULL;
int result_path_len = -1;
int retval = 0;
bool alloc_full_path = false;
if (argv[1][0] == '/')
full_path = argv[1];
else
{
full_path = get_target_filepath(argv[1], &result_path_len);
alloc_full_path = true;
}
retval = rm(full_path);
// printf("rmdir: path=%s, retval=%d\n", full_path, retval);
if (retval != 0)
printf("Failed to remove %s, retval=%d\n", full_path, retval);
if (alloc_full_path)
free(full_path);
if (argv != NULL)
free(argv);
return retval;
}
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
int shell_cmd_exec(int argc, char **argv)
{
pid_t pid = fork();
int retval = 0;
// printf(" pid=%d \n",pid);
if (pid == 0)
{
// 子进程
int path_len = 0;
char *file_path = get_target_filepath(argv[1], &path_len);
// printf("before execv, path=%s, argc=%d\n", file_path, argc);
char **real_argv = NULL;
if (argc > 1)
{
real_argv = &argv[1];
}
execv(file_path, real_argv);
// printf("after execv, path=%s, argc=%d\n", file_path, argc);
free(argv);
free(file_path);
exit(-1);
}
else
{
// 如果不指定后台运行,则等待退出
if (strcmp(argv[argc - 1], "&") != 0)
waitpid(pid, &retval, 0);
else
printf("[1] %d\n", pid); // 输出子进程的pid
free(argv);
}
}
int shell_cmd_about(int argc, char **argv)
{
if (argv != NULL)
free(argv);
int aac = 0;
char **aav;
unsigned char input_buffer[INPUT_BUFFER_SIZE] = {0};
strcpy(input_buffer, "exec /bin/about.elf\0");
parse_command(input_buffer, &aac, &aav);
return shell_cmd_exec(aac, aav);
}
int shell_cmd_kill(int argc, char **argv)
{
int retval = 0;
if (argc < 2)
{
printf("Usage: Kill <pid>\n");
retval = -EINVAL;
goto out;
}
retval = kill(atoi(argv[1]), SIGKILL);
out:;
free(argv);
return retval;
}
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
int shell_cmd_reboot(int argc, char **argv)
{
return syscall_invoke(SYS_REBOOT, 0, 0, 0, 0, 0, 0);
}
int shell_cmd_free(int argc, char **argv)
{
int retval = 0;
if (argc == 2 && strcmp("-m", argv[1]) != 0)
{
retval = -EINVAL;
printf("Invalid argument: %s\n", argv[1]);
goto done;
}
struct mstat_t mst = {0};
retval = mstat(&mst);
if (retval != 0)
{
printf("Failed: retval=%d", retval);
goto done;
}
printf("\ttotal\tused\tfree\tshared\tcache\tavailable\n");
printf("Mem:\t");
if (argc == 1) // 按照kb显示
{
printf("%ld\t%ld\t%ld\t%ld\t%ld\t%ld\t\n", mst.total, mst.used, mst.free, mst.shared,
mst.cache_used, mst.available);
}
else // 按照MB显示
{
printf("%ld\t%ld\t%ld\t%ld\t%ld\t%ld\t\n", mst.total >> 10, mst.used >> 10, mst.free >> 10, mst.shared >> 10,
mst.cache_used >> 10, mst.available >> 10);
}
done:;
if (argv != NULL)
free(argv);
return retval;
}
/**
* @brief shell命令
*
* @param buf
* @param argc
* @param argv
* @return int
*/
int parse_command(char *buf, int *argc, char ***argv)
{
// printf("parse command\n");
int index = 0; // 当前访问的是buf的第几位
// 去除命令前导的空格
while (index < INPUT_BUFFER_SIZE && buf[index] == ' ')
++index;
// 如果去除前导空格后第一项为0x00则归为空命令
if (!buf[index])
return -1;
// 计算参数数量
for (int i = index; i < (INPUT_BUFFER_SIZE - 1); ++i)
{
// 到达了字符串末尾
if (!buf[i])
break;
if (buf[i] != ' ' && (buf[i + 1] == ' ' || buf[i + 1] == '\0'))
++(*argc);
}
// printf("\nargc=%d\n", *argc);
// 为指向每个指令的指针分配空间
*argv = (char **)malloc(sizeof(char **) * (*argc + 1));
memset(*argv, 0, sizeof(char **) * (*argc + 1));
// 将每个命令都单独提取出来
for (int i = 0; i < *argc && index < INPUT_BUFFER_SIZE; ++i)
{
// 提取出命令,以空格作为分割
*((*argv) + i) = &buf[index];
while (index < (INPUT_BUFFER_SIZE - 1) && buf[index] && buf[index] != ' ')
++index;
buf[index++] = '\0';
// 删除命令间多余的空格
while (index < INPUT_BUFFER_SIZE && buf[index] == ' ')
++index;
// printf("%s\n", (*argv)[i]);
}
// 以第一个命令作为主命令,查找其在命令表中的编号
return shell_find_cmd(**argv);
}

View File

@ -1,154 +0,0 @@
#pragma once
// cwd字符串的最大大小
#define SHELL_CWD_MAX_SIZE 256
#define INPUT_BUFFER_SIZE 512
/**
* @brief shell内建命令结构体
*
*/
struct built_in_cmd_t
{
char *name;
int (*func)(int argc, char **argv);
};
extern struct built_in_cmd_t shell_cmds[];
/**
* @brief
*
* @param main_cmd
* @return int
*/
int shell_find_cmd(char *main_cmd);
/**
* @brief shell内建的命令
*
* @param index
* @param argc
* @param argv
*/
void shell_run_built_in_command(int index, int argc, char **argv);
/**
* @brief cd命令:
*
* @param argc
* @param argv
* @return int
*/
int shell_cmd_cd(int argc, char **argv);
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
int shell_cmd_ls(int argc, char **argv);
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
int shell_cmd_pwd(int argc, char **argv);
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
int shell_cmd_cat(int argc, char **argv);
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
int shell_cmd_touch(int argc, char **argv);
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
int shell_cmd_rm(int argc, char **argv);
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
int shell_cmd_mkdir(int argc, char **argv);
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
int shell_cmd_rmdir(int argc, char **argv);
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
int shell_cmd_exec(int argc, char **argv);
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
int shell_cmd_reboot(int argc, char **argv);
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
int shell_cmd_about(int argc, char **argv);
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
int shell_cmd_free(int argc, char **argv);
/**
* @brief shell命令
*
* @param buf
* @param argc
* @param argv
* @return int
*/
int parse_command(char *buf, int *argc, char ***argv);
int shell_cmd_kill(int argc, char **argv);

View File

@ -1,29 +0,0 @@
#include "cmd_help.h"
#include <stdio.h>
#include <stdlib.h>
struct help_table_item_t
{
void (*func)();
};
struct help_table_item_t help_table[] = {
{shell_help_cd},
};
static const int help_table_num = sizeof(help_table) / sizeof(struct help_table_item_t);
int shell_help(int argc, char **argv)
{
printf("Help:\n");
for (int i = 0; i < help_table_num; ++i)
help_table[i].func();
if (argc > 1)
free(argv);
return 0;
}
void shell_help_cd()
{
printf("Example of cd: cd [destination]\n");
}

View File

@ -1,10 +0,0 @@
#pragma once
#include "cmd.h"
int shell_help(int argc, char **argv);
/**
* @brief cd命令的帮助信息
*
*/
void shell_help_cd();

View File

@ -1,166 +0,0 @@
#include "cmd_test.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <fcntl.h>
#define buf_SIZE 256 // 定义消息的最大长度
int shell_pipe_test(int argc, char **argv)
{
int fd[2], i, n;
pid_t pid;
int ret = pipe(fd); // 创建一个管道
if (ret < 0)
{
printf("pipe error");
exit(1);
}
pid = fork(); // 创建一个子进程
if (pid < 0)
{
printf("fork error");
exit(1);
}
if (pid == 0)
{ // 子进程
close(fd[1]); // 关闭管道的写端
for (i = 0; i < 3; i++)
{ // 循环三次
char buf[buf_SIZE] = {0};
n = read(fd[0], buf, buf_SIZE); // 从管道的读端读取一条消息
if (n > 0)
{
printf("Child process received message: %s\n", buf); // 打印收到的消息
if (strcmp(buf, "quit") == 0)
{ // 如果收到的消息是"quit"
printf("Child process exits.\n"); // 打印退出信息
break; // 跳出循环
}
else
{ // 如果收到的消息不是"quit"
printf("Child process is doing something...\n"); // 模拟子进程做一些操作
usleep(100);
}
}
}
close(fd[0]); // 关闭管道的读端
exit(0);
}
else
{ // 父进程
close(fd[0]); // 关闭管道的读端
for (i = 0; i < 3; i++)
{ // 循环三次
char *msg = "hello world";
if (i == 1)
{
msg = "how are you";
usleep(1000);
}
if (i == 2)
{
msg = "quit";
usleep(1000);
}
n = strlen(msg);
printf("Parent process send:%s\n", msg);
write(fd[1], msg, n); // 向管道的写端写入一条消息
if (strcmp(msg, "quit") == 0)
{ // 如果发送的消息是"quit"
printf("Parent process exits.\n"); // 打印退出信息
break; // 跳出循环
}
}
close(fd[1]); // 关闭管道的写端
wait(NULL); // 等待子进程结束
}
return 0;
}
int shell_pipe2_test(int argc, char **argv)
{
int fd[2], i, n;
pid_t pid;
int ret = pipe2(fd, O_NONBLOCK); // 创建一个管道
if (ret < 0)
{
printf("pipe error\n");
exit(1);
}
pid = fork(); // 创建一个子进程
if (pid < 0)
{
printf("fork error\n");
exit(1);
}
if (pid == 0)
{ // 子进程
close(fd[1]); // 关闭管道的写端
for (i = 0; i < 10; i++)
{
char buf[buf_SIZE] = {0};
n = read(fd[0], buf, buf_SIZE); // 从管道的读端读取一条消息
if (n > 0)
{
printf("Child process received message: %s\n", buf); // 打印收到的消息
if (strcmp(buf, "quit") == 0)
{ // 如果收到的消息是"quit"
printf("Child process exits.\n"); // 打印退出信息
break; // 跳出循环
}
else
{ // 如果收到的消息不是"quit"
printf("Child process is doing something...\n"); // 模拟子进程做一些操作
// usleep(1000);
}
}
else
{
printf("read error,buf is empty\n");
}
}
close(fd[0]); // 关闭管道的读端
exit(0);
}
else
{ // 父进程
close(fd[0]); // 关闭管道的读端
for (i = 0; i < 100; i++)
{
char *msg = "hello world";
if (i < 99 & i > 0)
{
msg = "how are you";
// usleep(1000);
}
if (i == 99)
{
msg = "quit";
// usleep(1000);
}
n = strlen(msg);
printf("Parent process send:%s\n", msg);
int r = write(fd[1], msg, n); // 向管道的写端写入一条消息
if (r < 0)
{
printf("write error,buf is full\n");
}
if (strcmp(msg, "quit") == 0)
{ // 如果发送的消息是"quit"
printf("Parent process exits.\n"); // 打印退出信息
break; // 跳出循环
}
}
close(fd[1]); // 关闭管道的写端
wait(NULL); // 等待子进程结束
}
return 0;
}

View File

@ -1,5 +0,0 @@
#pragma once
#include "cmd.h"
int shell_pipe_test(int argc, char **argv);
int shell_pipe2_test(int argc, char **argv);

View File

@ -1,272 +0,0 @@
#include "cmd.h"
#include <fcntl.h>
#include <libKeyboard/keyboard.h>
#include <printf.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#define pause_cpu() asm volatile("pause\n\t");
#define MEM_HISTORY 1024
/**
* @brief
*
* @param fd
* @param buf
* @return
*/
int shell_readline(int fd, char *buf);
void print_ascii_logo();
extern char *shell_current_path;
// 保存的历史命令(瞬时更改)
char history_commands[MEM_HISTORY][INPUT_BUFFER_SIZE];
// 真正的历史命令
char real_history_commands[MEM_HISTORY][INPUT_BUFFER_SIZE];
int count_history;
// 现在对应的命令
int current_command_index;
/**
* @brief shell主循环
*
* @param kb_fd
*/
void main_loop(int kb_fd)
{
count_history = 0;
current_command_index = 0;
unsigned char input_buffer[INPUT_BUFFER_SIZE] = {0};
// 初始化当前工作目录的路径
shell_current_path = (char *)malloc(3);
memset(shell_current_path, 0, 3);
shell_current_path[0] = '/';
shell_current_path[1] = '\0';
// shell命令行的主循环
while (true)
{
int argc = 0;
char **argv;
printf("[DragonOS] %s # ", shell_current_path);
memset(input_buffer, 0, INPUT_BUFFER_SIZE);
// 添加初始光标
put_string(" ", COLOR_BLACK, COLOR_WHITE);
// 循环读取每一行到buffer
count_history++;
int count = shell_readline(kb_fd, input_buffer);
if (!count || current_command_index < count_history - 1)
count_history--;
if (count)
{
strcpy(real_history_commands[count_history - 1], input_buffer);
count_history++;
memset(history_commands, 0, sizeof(history_commands));
for (int i = 0; i <= count_history - 2; i++)
strcpy(history_commands[i], real_history_commands[i]);
current_command_index = count_history - 1;
}
if (count)
{
char command_origin[strlen(input_buffer)];
strcpy(command_origin, input_buffer);
int cmd_num = parse_command(input_buffer, &argc, &argv);
printf("\n");
if (cmd_num >= 0)
shell_run_built_in_command(cmd_num, argc, argv);
}
else
printf("\n");
}
}
int main()
{
// 打开键盘文件
// char kb_file_path[] = "/dev/char/ps2_keyboard";
// int kb_fd = open(kb_file_path, 0);
print_ascii_logo();
// printf("before mkdir\n");
// mkdir("/aaac", 0);
// printf("after mkdir\n");
main_loop(0);
while (1)
;
}
/**
* @brief
*
* @param count
* @param buf
*/
void clear_command(int count, char *buf)
{
for (int i = 0; i < count; i++)
printf("%c", '\b');
memset(buf, 0, sizeof(buf));
}
/**
* @brief ()
*
* @param buf
* @param type 1,,-1,
*/
void change_command(char *buf, int type)
{
current_command_index -= type;
// 处理边界
if (current_command_index < 0)
current_command_index++;
if (current_command_index >= count_history - 1)
{
// 初始只含一条空历史记录,需单独考虑
if (count_history == 1)
{
// 防止出现多条空历史记录
if (current_command_index > 1)
current_command_index = 1;
}
else
current_command_index = count_history - 2;
}
strcpy(buf, history_commands[current_command_index]);
printf("%s", buf);
put_string(" ", COLOR_BLACK, COLOR_WHITE);
}
/**
* @brief
*
* @param fd
* @param buf
* @return
*/
int shell_readline(int fd, char *buf)
{
int key = 0;
int count = 0;
while (1)
{
// key = keyboard_analyze_keycode(fd);
key = getchar();
// printf("key = %d\n", key);
if (key == 224)
{
key = getchar();
// printf("key = %d\n", key);
switch (key)
{
case 72:
// 向上方向键
if (count_history != 0)
{
// put_string(" ", COLOR_WHITE, COLOR_BLACK);
printf("%c", '\b');
clear_command(count, buf);
count = 0;
// 向历史
change_command(buf, 1);
count = strlen(buf);
}
key = 0xc8;
break;
case 80:
// 向下方向键
if (count_history != 0)
{
// put_string(" ", COLOR_WHITE, COLOR_BLACK);
printf("%c", '\b');
clear_command(count, buf);
count = 0;
// 向历史
change_command(buf, -1);
count = strlen(buf);
}
key = 0x50;
break;
default:
break;
}
}
if (key == '\n')
{
if (count > 0 && current_command_index >= count_history)
{
memset(history_commands[current_command_index - 1], 0,
sizeof(history_commands[current_command_index - 1]));
count_history--;
}
printf("%c", '\b');
return count;
}
if (key && key != 0xc8)
{
if (key == '\b')
{
if (count > 0)
{
// 回退去除先前光标
printf("%c", '\b');
// 去除字符
printf("%c", '\b');
buf[--count] = 0;
// 在最后一个字符处加光标
put_string(" ", COLOR_BLACK, COLOR_WHITE);
}
}
else
{
printf("%c", '\b');
buf[count++] = key;
printf("%c", key);
// 在最后一个字符处加光标
put_string(" ", COLOR_BLACK, COLOR_WHITE);
}
if (count > 0 && current_command_index >= count_history)
{
memset(history_commands[count_history], 0, sizeof(history_commands[count_history]));
strcpy(history_commands[count_history], buf);
}
else if (count > 0)
{
memset(history_commands[current_command_index], 0, sizeof(history_commands[current_command_index]));
strcpy(history_commands[current_command_index], buf);
}
}
// 输入缓冲区满了之后,直接返回
if (count >= INPUT_BUFFER_SIZE - 1)
{
printf("%c", '\b');
return count;
}
pause_cpu();
}
}
void print_ascii_logo()
{
printf("\n\n");
printf(" ____ ___ ____ \n");
printf("| _ \\ _ __ __ _ __ _ ___ _ __ / _ \\ / ___| \n");
printf("| | | || '__| / _` | / _` | / _ \\ | '_ \\ | | | |\\___ \\ \n");
printf("| |_| || | | (_| || (_| || (_) || | | || |_| | ___) |\n");
printf("|____/ |_| \\__,_| \\__, | \\___/ |_| |_| \\___/ |____/ \n");
printf(" |___/ \n");
printf("\n\n");
}

View File

@ -1,54 +0,0 @@
OUTPUT_FORMAT("elf64-x86-64","elf64-x86-64","elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(_start)
SECTIONS
{
. = 0x800000;
.text :
{
_text = .;
*(.text)
*(.text.*)
_etext = .;
}
. = ALIGN(8);
.data :
{
_data = .;
*(.data)
*(.data.*)
_edata = .;
}
rodata_start_pa = .;
.rodata :
{
_rodata = .;
*(.rodata)
*(.rodata.*)
_erodata = .;
}
.bss :
{
_bss = .;
*(.bss)
*(.bss.*)
_ebss = .;
}
_end = .;
}

1
user/apps/test_bind/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
test_bind

View File

@ -1,27 +1,20 @@
CC=$(DragonOS_GCC)/x86_64-elf-gcc ifeq ($(ARCH), x86_64)
LD=ld CROSS_COMPILE=x86_64-linux-musl-
OBJCOPY=objcopy else ifeq ($(ARCH), riscv64)
# 修改这里把它改为你的relibc的sysroot路径 CROSS_COMPILE=riscv64-linux-musl-
RELIBC_OPT=$(DADK_BUILD_CACHE_DIR_RELIBC_0_1_0) endif
CFLAGS=-I $(RELIBC_OPT)/include -D__dragonos__
tmp_output_dir=$(ROOT_PATH)/bin/tmp/user CC=$(CROSS_COMPILE)gcc
output_dir=$(DADK_BUILD_CACHE_DIR_TEST_BIND_0_1_0)
LIBC_OBJS:=$(shell find $(RELIBC_OPT)/lib -name "*.o" | sort ) .PHONY: all
LIBC_OBJS+=$(RELIBC_OPT)/lib/libc.a all: main.c
$(CC) -static -o test_bind main.c
all: main.o .PHONY: install clean
mkdir -p $(tmp_output_dir) install: all
mv test_bind $(DADK_CURRENT_BUILD_DIR)/test_bind
$(LD) -b elf64-x86-64 -z muldefs -o $(tmp_output_dir)/test_bind $(shell find . -name "*.o") $(LIBC_OBJS) -T link.lds
$(OBJCOPY) -I elf64-x86-64 -R ".eh_frame" -R ".comment" -O elf64-x86-64 $(tmp_output_dir)/test_bind $(output_dir)/test_bind.elf
mv $(output_dir)/test_bind.elf $(output_dir)/test_bind
main.o: main.c
$(CC) $(CFLAGS) -c main.c -o main.o
clean: clean:
rm -f *.o rm test_bind *.o
fmt:

View File

@ -1,239 +0,0 @@
/* Script for -z combreloc */
/* Copyright (C) 2014-2020 Free Software Foundation, Inc.
Copying and distribution of this script, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. */
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64",
"elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(_start)
SECTIONS
{
/* Read-only sections, merged into text segment: */
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x20000000) + SIZEOF_HEADERS;
.interp : { *(.interp) }
.note.gnu.build-id : { *(.note.gnu.build-id) }
.hash : { *(.hash) }
.gnu.hash : { *(.gnu.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rela.dyn :
{
*(.rela.init)
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
*(.rela.fini)
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
*(.rela.ctors)
*(.rela.dtors)
*(.rela.got)
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
*(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*)
*(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*)
*(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*)
*(.rela.ifunc)
}
.rela.plt :
{
*(.rela.plt)
PROVIDE_HIDDEN (__rela_iplt_start = .);
*(.rela.iplt)
PROVIDE_HIDDEN (__rela_iplt_end = .);
}
. = ALIGN(CONSTANT (MAXPAGESIZE));
.init :
{
KEEP (*(SORT_NONE(.init)))
}
.plt : { *(.plt) *(.iplt) }
.plt.got : { *(.plt.got) }
.plt.sec : { *(.plt.sec) }
.text :
{
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text.exit .text.exit.*)
*(.text.startup .text.startup.*)
*(.text.hot .text.hot.*)
*(.text .stub .text.* .gnu.linkonce.t.*)
/* .gnu.warning sections are handled specially by elf.em. */
*(.gnu.warning)
}
.fini :
{
KEEP (*(SORT_NONE(.fini)))
}
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
. = ALIGN(CONSTANT (MAXPAGESIZE));
/* Adjust the address for the rodata segment. We want to adjust up to
the same address within the page on the next page up. */
. = SEGMENT_START("rodata-segment", ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)));
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
.rodata1 : { *(.rodata1) }
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) }
/* These sections are generated by the Sun/Oracle C++ compiler. */
.exception_ranges : ONLY_IF_RO { *(.exception_ranges*) }
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
/* Exception handling */
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }
.gnu_extab : ONLY_IF_RW { *(.gnu_extab) }
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
.exception_ranges : ONLY_IF_RW { *(.exception_ranges*) }
/* Thread Local Storage sections */
.tdata :
{
PROVIDE_HIDDEN (__tdata_start = .);
*(.tdata .tdata.* .gnu.linkonce.td.*)
}
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
}
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
}
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
}
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
}
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
}
.jcr : { KEEP (*(.jcr)) }
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
.dynamic : { *(.dynamic) }
.got : { *(.got) *(.igot) }
. = DATA_SEGMENT_RELRO_END (SIZEOF (.got.plt) >= 24 ? 24 : 0, .);
.got.plt : { *(.got.plt) *(.igot.plt) }
.data :
{
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
}
.data1 : { *(.data1) }
_edata = .; PROVIDE (edata = .);
. = .;
__bss_start = .;
.bss :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections.
FIXME: Why do we need it? When there is no .bss section, we do not
pad the .data section. */
. = ALIGN(. != 0 ? 64 / 8 : 1);
}
.lbss :
{
*(.dynlbss)
*(.lbss .lbss.* .gnu.linkonce.lb.*)
*(LARGE_COMMON)
}
. = ALIGN(64 / 8);
. = SEGMENT_START("ldata-segment", .);
.lrodata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
{
*(.lrodata .lrodata.* .gnu.linkonce.lr.*)
}
.ldata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
{
*(.ldata .ldata.* .gnu.linkonce.l.*)
. = ALIGN(. != 0 ? 64 / 8 : 1);
}
. = ALIGN(64 / 8);
_end = .; PROVIDE (end = .);
. = DATA_SEGMENT_END (.);
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
.gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* DWARF 3 */
.debug_pubtypes 0 : { *(.debug_pubtypes) }
.debug_ranges 0 : { *(.debug_ranges) }
/* DWARF Extension. */
.debug_macro 0 : { *(.debug_macro) }
.debug_addr 0 : { *(.debug_addr) }
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
}

View File

@ -2,7 +2,6 @@
#include <fcntl.h> #include <fcntl.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>

1
user/apps/test_fstat/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
test_fstat

View File

@ -1,26 +1,20 @@
CC=$(DragonOS_GCC)/x86_64-elf-gcc ifeq ($(ARCH), x86_64)
LD=ld CROSS_COMPILE=x86_64-linux-musl-
OBJCOPY=objcopy else ifeq ($(ARCH), riscv64)
# 修改这里把它改为你的relibc的sysroot路径 CROSS_COMPILE=riscv64-linux-musl-
RELIBC_OPT=$(DADK_BUILD_CACHE_DIR_RELIBC_0_1_0) endif
CFLAGS=-I $(RELIBC_OPT)/include -D__dragonos__
tmp_output_dir=$(ROOT_PATH)/bin/tmp/user CC=$(CROSS_COMPILE)gcc
output_dir=$(DADK_BUILD_CACHE_DIR_TEST_FSTAT_0_1_0)
LIBC_OBJS:=$(shell find $(RELIBC_OPT)/lib -name "*.o" | sort ) .PHONY: all
LIBC_OBJS+=$(RELIBC_OPT)/lib/libc.a all: main.c
$(CC) -static -o test_fstat main.c
all: main.o .PHONY: install clean
mkdir -p $(tmp_output_dir) install: all
mv test_fstat $(DADK_CURRENT_BUILD_DIR)/test_fstat
$(LD) -b elf64-x86-64 -z muldefs -o $(tmp_output_dir)/test_fstat $(shell find . -name "*.o") $(LIBC_OBJS) -T link.lds
$(OBJCOPY) -I elf64-x86-64 -R ".eh_frame" -R ".comment" -O elf64-x86-64 $(tmp_output_dir)/test_fstat $(output_dir)/test_fstat.elf
mv $(output_dir)/test_fstat.elf $(output_dir)/test_fstat
main.o: main.c
$(CC) $(CFLAGS) -c main.c -o main.o
clean: clean:
rm -f *.o rm test_fstat *.o
fmt:

View File

@ -1,239 +0,0 @@
/* Script for -z combreloc */
/* Copyright (C) 2014-2020 Free Software Foundation, Inc.
Copying and distribution of this script, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. */
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64",
"elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(_start)
SECTIONS
{
/* Read-only sections, merged into text segment: */
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x20000000) + SIZEOF_HEADERS;
.interp : { *(.interp) }
.note.gnu.build-id : { *(.note.gnu.build-id) }
.hash : { *(.hash) }
.gnu.hash : { *(.gnu.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rela.dyn :
{
*(.rela.init)
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
*(.rela.fini)
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
*(.rela.ctors)
*(.rela.dtors)
*(.rela.got)
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
*(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*)
*(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*)
*(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*)
*(.rela.ifunc)
}
.rela.plt :
{
*(.rela.plt)
PROVIDE_HIDDEN (__rela_iplt_start = .);
*(.rela.iplt)
PROVIDE_HIDDEN (__rela_iplt_end = .);
}
. = ALIGN(CONSTANT (MAXPAGESIZE));
.init :
{
KEEP (*(SORT_NONE(.init)))
}
.plt : { *(.plt) *(.iplt) }
.plt.got : { *(.plt.got) }
.plt.sec : { *(.plt.sec) }
.text :
{
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text.exit .text.exit.*)
*(.text.startup .text.startup.*)
*(.text.hot .text.hot.*)
*(.text .stub .text.* .gnu.linkonce.t.*)
/* .gnu.warning sections are handled specially by elf.em. */
*(.gnu.warning)
}
.fini :
{
KEEP (*(SORT_NONE(.fini)))
}
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
. = ALIGN(CONSTANT (MAXPAGESIZE));
/* Adjust the address for the rodata segment. We want to adjust up to
the same address within the page on the next page up. */
. = SEGMENT_START("rodata-segment", ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)));
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
.rodata1 : { *(.rodata1) }
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) }
/* These sections are generated by the Sun/Oracle C++ compiler. */
.exception_ranges : ONLY_IF_RO { *(.exception_ranges*) }
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
/* Exception handling */
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }
.gnu_extab : ONLY_IF_RW { *(.gnu_extab) }
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
.exception_ranges : ONLY_IF_RW { *(.exception_ranges*) }
/* Thread Local Storage sections */
.tdata :
{
PROVIDE_HIDDEN (__tdata_start = .);
*(.tdata .tdata.* .gnu.linkonce.td.*)
}
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
}
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
}
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
}
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
}
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
}
.jcr : { KEEP (*(.jcr)) }
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
.dynamic : { *(.dynamic) }
.got : { *(.got) *(.igot) }
. = DATA_SEGMENT_RELRO_END (SIZEOF (.got.plt) >= 24 ? 24 : 0, .);
.got.plt : { *(.got.plt) *(.igot.plt) }
.data :
{
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
}
.data1 : { *(.data1) }
_edata = .; PROVIDE (edata = .);
. = .;
__bss_start = .;
.bss :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections.
FIXME: Why do we need it? When there is no .bss section, we do not
pad the .data section. */
. = ALIGN(. != 0 ? 64 / 8 : 1);
}
.lbss :
{
*(.dynlbss)
*(.lbss .lbss.* .gnu.linkonce.lb.*)
*(LARGE_COMMON)
}
. = ALIGN(64 / 8);
. = SEGMENT_START("ldata-segment", .);
.lrodata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
{
*(.lrodata .lrodata.* .gnu.linkonce.lr.*)
}
.ldata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
{
*(.ldata .ldata.* .gnu.linkonce.l.*)
. = ALIGN(. != 0 ? 64 / 8 : 1);
}
. = ALIGN(64 / 8);
_end = .; PROVIDE (end = .);
. = DATA_SEGMENT_END (.);
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
.gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* DWARF 3 */
.debug_pubtypes 0 : { *(.debug_pubtypes) }
.debug_ranges 0 : { *(.debug_ranges) }
/* DWARF Extension. */
.debug_macro 0 : { *(.debug_macro) }
.debug_addr 0 : { *(.debug_addr) }
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
}

View File

@ -1,35 +1,34 @@
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
int main() int main()
{ {
int fd = open("/bin/about.elf", O_RDONLY); int fd = open("/bin/about.elf", O_RDONLY);
if (fd == -1) if (fd == -1)
return 0; return 0;
printf("fd = %d\n", fd); printf("fd = %d\n", fd);
struct stat *st = (struct stat *)malloc(sizeof(struct stat)); struct stat *st = (struct stat *)malloc(sizeof(struct stat));
fstat(fd, st); fstat(fd, st);
printf("stat size = %d\n", sizeof(struct stat)); printf("stat size = %lu\n", sizeof(struct stat));
// FIXME 打印数据时内存出错 // FIXME 打印数据时内存出错
printf("====================\n"); printf("====================\n");
printf("st address: %#018lx\n", st); printf("st address: %p\n", st);
printf("st_dev = %d\n", (*st).st_dev); printf("st_dev = %lu\n", (*st).st_dev);
printf("st_ino = %d\n", (*st).st_ino); printf("st_ino = %lu\n", (*st).st_ino);
printf("st_mode = %d\n", (*st).st_mode); printf("st_mode = %d\n", (*st).st_mode);
printf("st_nlink = %d\n", (*st).st_nlink); printf("st_nlink = %lu\n", (*st).st_nlink);
printf("st_uid = %d\n", (*st).st_uid); printf("st_uid = %d\n", (*st).st_uid);
printf("st_gid = %d\n", (*st).st_gid); printf("st_gid = %d\n", (*st).st_gid);
printf("st_rdev = %d\n", (*st).st_rdev); printf("st_rdev = %lu\n", (*st).st_rdev);
printf("st_size = %d\n", (*st).st_size); printf("st_size = %ld\n", (*st).st_size);
printf("st_blksize = %d\n", (*st).st_blksize); printf("st_blksize = %ld\n", (*st).st_blksize);
printf("st_blocks = %d\n", (*st).st_blocks); printf("st_blocks = %ld\n", (*st).st_blocks);
printf("st_atim.sec= %d\tst_atim.nsec= %d\n", (*st).st_atim.tv_sec, (*st).st_atim.tv_nsec); printf("st_atim.sec= %ld\tst_atim.nsec= %ld\n", (*st).st_atim.tv_sec, (*st).st_atim.tv_nsec);
printf("st_mtim.sec= %d\tst_mtim.nsec= %d\n", (*st).st_mtim.tv_sec, (*st).st_mtim.tv_nsec); printf("st_mtim.sec= %ld\tst_mtim.nsec= %ld\n", (*st).st_mtim.tv_sec, (*st).st_mtim.tv_nsec);
printf("st_ctim.sec= %d\tst_ctim.nsec= %d\n", (*st).st_ctim.tv_sec, (*st).st_ctim.tv_nsec); printf("st_ctim.sec= %ld\tst_ctim.nsec= %ld\n", (*st).st_ctim.tv_sec, (*st).st_ctim.tv_nsec);
return 0; return 0;
} }

View File

@ -0,0 +1 @@
test_gettimeofday

View File

@ -1,25 +1,20 @@
CC=$(DragonOS_GCC)/x86_64-elf-gcc ifeq ($(ARCH), x86_64)
LD=ld CROSS_COMPILE=x86_64-linux-musl-
OBJCOPY=objcopy else ifeq ($(ARCH), riscv64)
# 修改这里把它改为你的relibc的sysroot路径 CROSS_COMPILE=riscv64-linux-musl-
RELIBC_OPT=$(DADK_BUILD_CACHE_DIR_RELIBC_0_1_0) endif
CFLAGS=-I $(RELIBC_OPT)/include -D__dragonos__
tmp_output_dir=$(ROOT_PATH)/bin/tmp/user CC=$(CROSS_COMPILE)gcc
output_dir=$(DADK_BUILD_CACHE_DIR_TEST_GETTIMEOFDAY_0_1_0)
LIBC_OBJS:=$(shell find $(RELIBC_OPT)/lib -name "*.o" | sort ) .PHONY: all
LIBC_OBJS+=$(RELIBC_OPT)/lib/libc.a all: main.c
$(CC) -static -o test_gettimeofday main.c
all: main.o .PHONY: install clean
mkdir -p $(tmp_output_dir) install: all
mv test_gettimeofday $(DADK_CURRENT_BUILD_DIR)/test_gettimeofday
$(LD) -b elf64-x86-64 -z muldefs -o $(tmp_output_dir)/test_gettimeofday $(shell find . -name "*.o") $(LIBC_OBJS) -T link.lds
$(OBJCOPY) -I elf64-x86-64 -R ".eh_frame" -R ".comment" -O elf64-x86-64 $(tmp_output_dir)/test_gettimeofday $(output_dir)/test_gettimeofday.elf
mv $(output_dir)/test_gettimeofday.elf $(output_dir)/test_gettimeofday
main.o: main.c
$(CC) $(CFLAGS) -c main.c -o main.o
clean: clean:
rm -f *.o rm test_gettimeofday *.o
fmt:

View File

@ -1,239 +0,0 @@
/* Script for -z combreloc */
/* Copyright (C) 2014-2020 Free Software Foundation, Inc.
Copying and distribution of this script, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. */
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64",
"elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(_start)
SECTIONS
{
/* Read-only sections, merged into text segment: */
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x20000000) + SIZEOF_HEADERS;
.interp : { *(.interp) }
.note.gnu.build-id : { *(.note.gnu.build-id) }
.hash : { *(.hash) }
.gnu.hash : { *(.gnu.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rela.dyn :
{
*(.rela.init)
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
*(.rela.fini)
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
*(.rela.ctors)
*(.rela.dtors)
*(.rela.got)
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
*(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*)
*(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*)
*(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*)
*(.rela.ifunc)
}
.rela.plt :
{
*(.rela.plt)
PROVIDE_HIDDEN (__rela_iplt_start = .);
*(.rela.iplt)
PROVIDE_HIDDEN (__rela_iplt_end = .);
}
. = ALIGN(CONSTANT (MAXPAGESIZE));
.init :
{
KEEP (*(SORT_NONE(.init)))
}
.plt : { *(.plt) *(.iplt) }
.plt.got : { *(.plt.got) }
.plt.sec : { *(.plt.sec) }
.text :
{
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text.exit .text.exit.*)
*(.text.startup .text.startup.*)
*(.text.hot .text.hot.*)
*(.text .stub .text.* .gnu.linkonce.t.*)
/* .gnu.warning sections are handled specially by elf.em. */
*(.gnu.warning)
}
.fini :
{
KEEP (*(SORT_NONE(.fini)))
}
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
. = ALIGN(CONSTANT (MAXPAGESIZE));
/* Adjust the address for the rodata segment. We want to adjust up to
the same address within the page on the next page up. */
. = SEGMENT_START("rodata-segment", ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)));
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
.rodata1 : { *(.rodata1) }
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) }
/* These sections are generated by the Sun/Oracle C++ compiler. */
.exception_ranges : ONLY_IF_RO { *(.exception_ranges*) }
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
/* Exception handling */
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }
.gnu_extab : ONLY_IF_RW { *(.gnu_extab) }
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
.exception_ranges : ONLY_IF_RW { *(.exception_ranges*) }
/* Thread Local Storage sections */
.tdata :
{
PROVIDE_HIDDEN (__tdata_start = .);
*(.tdata .tdata.* .gnu.linkonce.td.*)
}
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
}
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
}
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
}
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
}
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
}
.jcr : { KEEP (*(.jcr)) }
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
.dynamic : { *(.dynamic) }
.got : { *(.got) *(.igot) }
. = DATA_SEGMENT_RELRO_END (SIZEOF (.got.plt) >= 24 ? 24 : 0, .);
.got.plt : { *(.got.plt) *(.igot.plt) }
.data :
{
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
}
.data1 : { *(.data1) }
_edata = .; PROVIDE (edata = .);
. = .;
__bss_start = .;
.bss :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections.
FIXME: Why do we need it? When there is no .bss section, we do not
pad the .data section. */
. = ALIGN(. != 0 ? 64 / 8 : 1);
}
.lbss :
{
*(.dynlbss)
*(.lbss .lbss.* .gnu.linkonce.lb.*)
*(LARGE_COMMON)
}
. = ALIGN(64 / 8);
. = SEGMENT_START("ldata-segment", .);
.lrodata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
{
*(.lrodata .lrodata.* .gnu.linkonce.lr.*)
}
.ldata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
{
*(.ldata .ldata.* .gnu.linkonce.l.*)
. = ALIGN(. != 0 ? 64 / 8 : 1);
}
. = ALIGN(64 / 8);
_end = .; PROVIDE (end = .);
. = DATA_SEGMENT_END (.);
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
.gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* DWARF 3 */
.debug_pubtypes 0 : { *(.debug_pubtypes) }
.debug_ranges 0 : { *(.debug_ranges) }
/* DWARF Extension. */
.debug_macro 0 : { *(.debug_macro) }
.debug_addr 0 : { *(.debug_addr) }
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
}

1
user/apps/test_kvm/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
test_kvm

View File

@ -1,9 +1,20 @@
OLD_LIBC_INSTALL_PATH=$(ROOT_PATH)/bin/sysroot/usr/old_libc ifeq ($(ARCH), x86_64)
CROSS_COMPILE=x86_64-linux-musl-
else ifeq ($(ARCH), riscv64)
CROSS_COMPILE=riscv64-linux-musl-
endif
all: main.o CC=$(CROSS_COMPILE)gcc
$(LD) -b elf64-x86-64 -z muldefs -o $(tmp_output_dir)/test_kvm $(shell find . -name "*.o") $(OLD_LIBC_INSTALL_PATH)/lib/libc.a -T link.lds .PHONY: all
all: main.c
$(CC) -static -o test_kvm main.c
$(OBJCOPY) -I elf64-x86-64 -R ".eh_frame" -R ".comment" -O elf64-x86-64 $(tmp_output_dir)/test_kvm $(output_dir)/test_kvm.elf .PHONY: install clean
main.o: main.c install: all
$(CC) $(CFLAGS) -c main.c -o main.o mv test_kvm $(DADK_CURRENT_BUILD_DIR)/test_kvm
clean:
rm test_kvm *.o
fmt:

View File

@ -1,3 +0,0 @@
boot.bin: boot.s
nasm boot.s -o boot.bin
xxd boot.bin > boot.hex

View File

@ -1,32 +0,0 @@
00000000: 8cc8 8ed8 8ec0 e802 00eb feb8 1e00 89c5 ................
00000010: b910 00b8 0113 bb0c 00b2 00cd 10c3 4865 ..............He
00000020: 6c6c 6f2c 204f 5320 776f 726c 6421 0000 llo, OS world!..
00000030: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000040: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000050: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000060: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000070: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000080: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000090: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000000a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000000b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000000c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000000d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000000e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000000f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000100: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000110: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000120: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000130: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000140: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000150: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000160: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000170: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000180: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000190: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000001a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000001b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000001c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000001d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000001e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000001f0: 0000 0000 0000 0000 0000 0000 0000 55aa ..............U.

View File

@ -1,54 +0,0 @@
OUTPUT_FORMAT("elf64-x86-64","elf64-x86-64","elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(_start)
SECTIONS
{
. = 0x800000;
.text :
{
_text = .;
*(.text)
*(.text.*)
_etext = .;
}
. = ALIGN(8);
.data :
{
_data = .;
*(.data)
*(.data.*)
_edata = .;
}
rodata_start_pa = .;
.rodata :
{
_rodata = .;
*(.rodata)
*(.rodata.*)
_erodata = .;
}
.bss :
{
_bss = .;
*(.bss)
*(.bss.*)
_ebss = .;
}
_end = .;
}

View File

@ -14,10 +14,11 @@
* 1.DragonOS的控制台输入 exec bin/test_kvm.elf * 1.DragonOS的控制台输入 exec bin/test_kvm.elf
* *
*/ */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <unistd.h>
#define KVM_CREATE_VCPU 0x00 #define KVM_CREATE_VCPU 0x00
#define KVM_SET_USER_MEMORY_REGION 0x01 #define KVM_SET_USER_MEMORY_REGION 0x01

1
user/apps/test_mkfifo/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
test_mkfifo

View File

@ -1,26 +1,20 @@
CC=$(DragonOS_GCC)/x86_64-elf-gcc ifeq ($(ARCH), x86_64)
LD=ld CROSS_COMPILE=x86_64-linux-musl-
OBJCOPY=objcopy else ifeq ($(ARCH), riscv64)
# 修改这里把它改为你的relibc的sysroot路径 CROSS_COMPILE=riscv64-linux-musl-
RELIBC_OPT=$(DADK_BUILD_CACHE_DIR_RELIBC_0_1_0) endif
CFLAGS=-I $(RELIBC_OPT)/include -D__dragonos__
tmp_output_dir=$(ROOT_PATH)/bin/tmp/user CC=$(CROSS_COMPILE)gcc
output_dir=$(DADK_BUILD_CACHE_DIR_TEST_MKFIFO_0_1_0)
LIBC_OBJS:=$(shell find $(RELIBC_OPT)/lib -name "*.o" | sort ) .PHONY: all
LIBC_OBJS+=$(RELIBC_OPT)/lib/libc.a all: main.c
$(CC) -static -o test_mkfifo main.c
all: main.o .PHONY: install clean
mkdir -p $(tmp_output_dir) install: all
mv test_mkfifo $(DADK_CURRENT_BUILD_DIR)/test_mkfifo
$(LD) -b elf64-x86-64 -z muldefs -o $(tmp_output_dir)/test_mkfifo $(shell find . -name "*.o") $(LIBC_OBJS) -T link.lds
$(OBJCOPY) -I elf64-x86-64 -R ".eh_frame" -R ".comment" -O elf64-x86-64 $(tmp_output_dir)/test_mkfifo $(output_dir)/test_mkfifo.elf
mv $(output_dir)/test_mkfifo.elf $(output_dir)/test_mkfifo
main.o: main.c
$(CC) $(CFLAGS) -c main.c -o main.o
clean: clean:
rm -f *.o rm test_mkfifo *.o
fmt:

View File

@ -1,239 +0,0 @@
/* Script for -z combreloc */
/* Copyright (C) 2014-2020 Free Software Foundation, Inc.
Copying and distribution of this script, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. */
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64",
"elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(_start)
SECTIONS
{
/* Read-only sections, merged into text segment: */
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x20000000) + SIZEOF_HEADERS;
.interp : { *(.interp) }
.note.gnu.build-id : { *(.note.gnu.build-id) }
.hash : { *(.hash) }
.gnu.hash : { *(.gnu.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rela.dyn :
{
*(.rela.init)
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
*(.rela.fini)
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
*(.rela.ctors)
*(.rela.dtors)
*(.rela.got)
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
*(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*)
*(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*)
*(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*)
*(.rela.ifunc)
}
.rela.plt :
{
*(.rela.plt)
PROVIDE_HIDDEN (__rela_iplt_start = .);
*(.rela.iplt)
PROVIDE_HIDDEN (__rela_iplt_end = .);
}
. = ALIGN(CONSTANT (MAXPAGESIZE));
.init :
{
KEEP (*(SORT_NONE(.init)))
}
.plt : { *(.plt) *(.iplt) }
.plt.got : { *(.plt.got) }
.plt.sec : { *(.plt.sec) }
.text :
{
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text.exit .text.exit.*)
*(.text.startup .text.startup.*)
*(.text.hot .text.hot.*)
*(.text .stub .text.* .gnu.linkonce.t.*)
/* .gnu.warning sections are handled specially by elf.em. */
*(.gnu.warning)
}
.fini :
{
KEEP (*(SORT_NONE(.fini)))
}
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
. = ALIGN(CONSTANT (MAXPAGESIZE));
/* Adjust the address for the rodata segment. We want to adjust up to
the same address within the page on the next page up. */
. = SEGMENT_START("rodata-segment", ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)));
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
.rodata1 : { *(.rodata1) }
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) }
/* These sections are generated by the Sun/Oracle C++ compiler. */
.exception_ranges : ONLY_IF_RO { *(.exception_ranges*) }
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
/* Exception handling */
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }
.gnu_extab : ONLY_IF_RW { *(.gnu_extab) }
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
.exception_ranges : ONLY_IF_RW { *(.exception_ranges*) }
/* Thread Local Storage sections */
.tdata :
{
PROVIDE_HIDDEN (__tdata_start = .);
*(.tdata .tdata.* .gnu.linkonce.td.*)
}
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
}
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
}
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
}
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
}
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
}
.jcr : { KEEP (*(.jcr)) }
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
.dynamic : { *(.dynamic) }
.got : { *(.got) *(.igot) }
. = DATA_SEGMENT_RELRO_END (SIZEOF (.got.plt) >= 24 ? 24 : 0, .);
.got.plt : { *(.got.plt) *(.igot.plt) }
.data :
{
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
}
.data1 : { *(.data1) }
_edata = .; PROVIDE (edata = .);
. = .;
__bss_start = .;
.bss :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections.
FIXME: Why do we need it? When there is no .bss section, we do not
pad the .data section. */
. = ALIGN(. != 0 ? 64 / 8 : 1);
}
.lbss :
{
*(.dynlbss)
*(.lbss .lbss.* .gnu.linkonce.lb.*)
*(LARGE_COMMON)
}
. = ALIGN(64 / 8);
. = SEGMENT_START("ldata-segment", .);
.lrodata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
{
*(.lrodata .lrodata.* .gnu.linkonce.lr.*)
}
.ldata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
{
*(.ldata .ldata.* .gnu.linkonce.l.*)
. = ALIGN(. != 0 ? 64 / 8 : 1);
}
. = ALIGN(64 / 8);
_end = .; PROVIDE (end = .);
. = DATA_SEGMENT_END (.);
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
.gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* DWARF 3 */
.debug_pubtypes 0 : { *(.debug_pubtypes) }
.debug_ranges 0 : { *(.debug_ranges) }
/* DWARF Extension. */
.debug_macro 0 : { *(.debug_macro) }
.debug_addr 0 : { *(.debug_addr) }
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
}

View File

@ -1,11 +1,11 @@
#include <fcntl.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h> #include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <unistd.h>
#define BUFFER_SIZE 256 #define BUFFER_SIZE 256
#define PIPE_NAME "/bin/fifo" #define PIPE_NAME "/bin/fifo"

View File

@ -1,24 +0,0 @@
CC=$(DragonOS_GCC)/x86_64-elf-gcc
LD=ld
OBJCOPY=objcopy
# 修改这里把它改为你的relibc的sysroot路径
RELIBC_OPT=$(DADK_BUILD_CACHE_DIR_RELIBC_0_1_0)
CFLAGS=-I $(RELIBC_OPT)/include -D__dragonos__
tmp_output_dir=$(ROOT_PATH)/bin/tmp/user
output_dir=$(DADK_BUILD_CACHE_DIR_TEST_RELIBC_0_1_0)
LIBC_OBJS:=$(shell find $(RELIBC_OPT)/lib -name "*.o" | sort )
LIBC_OBJS+=$(RELIBC_OPT)/lib/libc.a
all: main.o
mkdir -p $(tmp_output_dir)
$(LD) -b elf64-x86-64 -z muldefs -o $(tmp_output_dir)/test $(shell find . -name "*.o") $(LIBC_OBJS) -T link.lds
$(OBJCOPY) -I elf64-x86-64 -R ".eh_frame" -R ".comment" -O elf64-x86-64 $(tmp_output_dir)/test $(output_dir)/test.elf
main.o: main.c
$(CC) $(CFLAGS) -c main.c -o main.o
clean:
rm -f *.o

View File

@ -1,239 +0,0 @@
/* Script for -z combreloc */
/* Copyright (C) 2014-2020 Free Software Foundation, Inc.
Copying and distribution of this script, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. */
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64",
"elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(_start)
SECTIONS
{
/* Read-only sections, merged into text segment: */
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x20000000) + SIZEOF_HEADERS;
.interp : { *(.interp) }
.note.gnu.build-id : { *(.note.gnu.build-id) }
.hash : { *(.hash) }
.gnu.hash : { *(.gnu.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rela.dyn :
{
*(.rela.init)
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
*(.rela.fini)
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
*(.rela.ctors)
*(.rela.dtors)
*(.rela.got)
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
*(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*)
*(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*)
*(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*)
*(.rela.ifunc)
}
.rela.plt :
{
*(.rela.plt)
PROVIDE_HIDDEN (__rela_iplt_start = .);
*(.rela.iplt)
PROVIDE_HIDDEN (__rela_iplt_end = .);
}
. = ALIGN(CONSTANT (MAXPAGESIZE));
.init :
{
KEEP (*(SORT_NONE(.init)))
}
.plt : { *(.plt) *(.iplt) }
.plt.got : { *(.plt.got) }
.plt.sec : { *(.plt.sec) }
.text :
{
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text.exit .text.exit.*)
*(.text.startup .text.startup.*)
*(.text.hot .text.hot.*)
*(.text .stub .text.* .gnu.linkonce.t.*)
/* .gnu.warning sections are handled specially by elf.em. */
*(.gnu.warning)
}
.fini :
{
KEEP (*(SORT_NONE(.fini)))
}
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
. = ALIGN(CONSTANT (MAXPAGESIZE));
/* Adjust the address for the rodata segment. We want to adjust up to
the same address within the page on the next page up. */
. = SEGMENT_START("rodata-segment", ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)));
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
.rodata1 : { *(.rodata1) }
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) }
/* These sections are generated by the Sun/Oracle C++ compiler. */
.exception_ranges : ONLY_IF_RO { *(.exception_ranges*) }
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
/* Exception handling */
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }
.gnu_extab : ONLY_IF_RW { *(.gnu_extab) }
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
.exception_ranges : ONLY_IF_RW { *(.exception_ranges*) }
/* Thread Local Storage sections */
.tdata :
{
PROVIDE_HIDDEN (__tdata_start = .);
*(.tdata .tdata.* .gnu.linkonce.td.*)
}
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
}
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
}
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
}
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
}
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
}
.jcr : { KEEP (*(.jcr)) }
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
.dynamic : { *(.dynamic) }
.got : { *(.got) *(.igot) }
. = DATA_SEGMENT_RELRO_END (SIZEOF (.got.plt) >= 24 ? 24 : 0, .);
.got.plt : { *(.got.plt) *(.igot.plt) }
.data :
{
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
}
.data1 : { *(.data1) }
_edata = .; PROVIDE (edata = .);
. = .;
__bss_start = .;
.bss :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections.
FIXME: Why do we need it? When there is no .bss section, we do not
pad the .data section. */
. = ALIGN(. != 0 ? 64 / 8 : 1);
}
.lbss :
{
*(.dynlbss)
*(.lbss .lbss.* .gnu.linkonce.lb.*)
*(LARGE_COMMON)
}
. = ALIGN(64 / 8);
. = SEGMENT_START("ldata-segment", .);
.lrodata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
{
*(.lrodata .lrodata.* .gnu.linkonce.lr.*)
}
.ldata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
{
*(.ldata .ldata.* .gnu.linkonce.l.*)
. = ALIGN(. != 0 ? 64 / 8 : 1);
}
. = ALIGN(64 / 8);
_end = .; PROVIDE (end = .);
. = DATA_SEGMENT_END (.);
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
.gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* DWARF 3 */
.debug_pubtypes 0 : { *(.debug_pubtypes) }
.debug_ranges 0 : { *(.debug_ranges) }
/* DWARF Extension. */
.debug_macro 0 : { *(.debug_macro) }
.debug_addr 0 : { *(.debug_addr) }
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
}

View File

@ -1,242 +0,0 @@
#include <arpa/inet.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define CONN_QUEUE_SIZE 20
#define BUFFER_SIZE 1024
#define SERVER_PORT 12580
int server_sockfd;
int conn;
void signal_handler(int signo)
{
printf("Server is exiting...\n");
close(conn);
close(server_sockfd);
exit(0);
}
static char logo[] =
" ____ ___ ____ \n| _ \\ _ __ __ _ __ _ ___ _ __ / _ \\ / ___| "
"\n| | | || '__| / _` | / _` | / _ \\ | '_ \\ | | | |\\___ \\ \n| |_| || | | (_| || (_| || (_) || | | || |_| | "
"___) |\n|____/ |_| \\__,_| \\__, | \\___/ |_| |_| \\___/ |____/ \n |___/ \n";
void tcp_server()
{
printf("TCP Server is running...\n");
server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
printf("socket() ok, server_sockfd=%d\n", server_sockfd);
struct sockaddr_in server_sockaddr;
server_sockaddr.sin_family = AF_INET;
server_sockaddr.sin_port = htons(SERVER_PORT);
server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(server_sockfd, (struct sockaddr *)&server_sockaddr, sizeof(server_sockaddr)))
{
perror("Server bind error.\n");
exit(1);
}
printf("TCP Server is listening...\n");
if (listen(server_sockfd, CONN_QUEUE_SIZE) == -1)
{
perror("Server listen error.\n");
exit(1);
}
printf("listen() ok\n");
char buffer[BUFFER_SIZE];
struct sockaddr_in client_addr;
socklen_t client_length = sizeof(client_addr);
/*
Await a connection on socket FD.
When a connection arrives, open a new socket to communicate with it,
set *ADDR (which is *ADDR_LEN bytes long) to the address of the connecting
peer and *ADDR_LEN to the address's actual length, and return the
new socket's descriptor, or -1 for errors.
*/
conn = accept(server_sockfd, (struct sockaddr *)&client_addr, &client_length);
printf("Connection established.\n");
if (conn < 0)
{
printf("Create connection failed, code=%d\n", conn);
exit(1);
}
send(conn, logo, sizeof(logo), 0);
while (1)
{
memset(buffer, 0, sizeof(buffer));
int len = recv(conn, buffer, sizeof(buffer), 0);
if (len <= 0)
{
printf("Receive data failed! len=%d\n", len);
break;
}
if (strcmp(buffer, "exit\n") == 0)
{
break;
}
printf("Received: %s\n", buffer);
send(conn, buffer, len, 0);
}
close(conn);
close(server_sockfd);
}
void udp_server()
{
printf("UDP Server is running...\n");
server_sockfd = socket(AF_INET, SOCK_DGRAM, 0);
printf("socket() ok, server_sockfd=%d\n", server_sockfd);
struct sockaddr_in server_sockaddr;
server_sockaddr.sin_family = AF_INET;
server_sockaddr.sin_port = htons(SERVER_PORT);
server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(server_sockfd, (struct sockaddr *)&server_sockaddr, sizeof(server_sockaddr)))
{
perror("Server bind error.\n");
exit(1);
}
printf("UDP Server is listening...\n");
char buffer[BUFFER_SIZE];
struct sockaddr_in client_addr;
socklen_t client_length = sizeof(client_addr);
while (1)
{
memset(buffer, 0, sizeof(buffer));
int len = recvfrom(server_sockfd, buffer, sizeof(buffer), 0, (struct sockaddr *)&client_addr, &client_length);
if (len <= 0)
{
printf("Receive data failed! len=%d", len);
break;
}
if (strcmp(buffer, "exit\n") == 0)
{
break;
}
printf("Received: %s", buffer);
sendto(server_sockfd, buffer, len, 0, (struct sockaddr *)&client_addr, client_length);
printf("Send: %s", buffer);
}
close(conn);
close(server_sockfd);
}
void tcp_client()
{
printf("Client is running...\n");
int client_sockfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in server_addr = {0};
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(12581);
server_addr.sin_addr.s_addr = inet_addr("192.168.199.129");
printf("to connect\n");
if (connect(client_sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
{
perror("Failed to establish connection to server\n");
exit(1);
}
printf("connected to server\n");
char sendbuf[BUFFER_SIZE] = {0};
char recvbuf[BUFFER_SIZE] = {0};
int x = recv(client_sockfd, recvbuf, sizeof(recvbuf), 0);
fputs(recvbuf, stdout);
memset(recvbuf, 0, sizeof(recvbuf));
while (1)
{
fgets(sendbuf, sizeof(sendbuf), stdin);
sendbuf[0] = 'a';
// printf("to send\n");
send(client_sockfd, sendbuf, strlen(sendbuf), 0);
// printf("send ok\n");
if (strcmp(sendbuf, "exit\n") == 0)
{
break;
}
int x = recv(client_sockfd, recvbuf, sizeof(recvbuf), 0);
if (x < 0)
{
printf("recv error, retval=%d\n", x);
break;
}
fputs(recvbuf, stdout);
memset(recvbuf, 0, sizeof(recvbuf));
memset(sendbuf, 0, sizeof(sendbuf));
}
close(client_sockfd);
}
void udp_client()
{
struct sockaddr_in addr;
int sockfd, len = 0;
int addr_len = sizeof(struct sockaddr_in);
char buffer[256];
/* 建立socket注意必须是SOCK_DGRAM */
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
perror("socket");
exit(1);
}
/* 填写sockaddr_in*/
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(12581);
addr.sin_addr.s_addr = inet_addr("192.168.199.129");
printf("to send logo\n");
sendto(sockfd, logo, sizeof(logo), 0, (struct sockaddr *)&addr, addr_len);
printf("send logo ok\n");
while (1)
{
bzero(buffer, sizeof(buffer));
printf("Please enter a string to send to server: \n");
/* 从标准输入设备取得字符串*/
len = read(STDIN_FILENO, buffer, sizeof(buffer));
printf("to send: %d\n", len);
/* 将字符串传送给server端*/
sendto(sockfd, buffer, len, 0, (struct sockaddr *)&addr, addr_len);
/* 接收server端返回的字符串*/
len = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr *)&addr, &addr_len);
printf("Receive from server: %s\n", buffer);
}
return 0;
}
void main()
{
// signal(SIGKILL, signal_handler);
// signal(SIGINT, signal_handler);
tcp_server();
// udp_server();
// tcp_client();
// udp_client();
}

1
user/apps/test_signal/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
test_signal

View File

@ -1,25 +1,20 @@
CC=$(DragonOS_GCC)/x86_64-elf-gcc ifeq ($(ARCH), x86_64)
LD=ld CROSS_COMPILE=x86_64-linux-musl-
OBJCOPY=objcopy else ifeq ($(ARCH), riscv64)
# 修改这里把它改为你的relibc的sysroot路径 CROSS_COMPILE=riscv64-linux-musl-
RELIBC_OPT=$(DADK_BUILD_CACHE_DIR_RELIBC_0_1_0) endif
CFLAGS=-I $(RELIBC_OPT)/include -D__dragonos__
tmp_output_dir=$(ROOT_PATH)/bin/tmp/user CC=$(CROSS_COMPILE)gcc
output_dir=$(DADK_BUILD_CACHE_DIR_TEST_SIGNAL_0_1_0)
.PHONY: all
all: main.c
$(CC) -static -o test_signal main.c
LIBC_OBJS:=$(shell find $(RELIBC_OPT)/lib -name "*.o" | sort ) .PHONY: install clean
LIBC_OBJS+=$(RELIBC_OPT)/lib/libc.a install: all
mv test_signal $(DADK_CURRENT_BUILD_DIR)/test_signal
all: main.o
$(LD) -b elf64-x86-64 -z muldefs -o $(tmp_output_dir)/test_signal $(shell find . -name "*.o") $(LIBC_OBJS) -T link.lds
$(OBJCOPY) -I elf64-x86-64 -R ".eh_frame" -R ".comment" -O elf64-x86-64 $(tmp_output_dir)/test_signal $(output_dir)/test_signal.elf
mv $(output_dir)/test_signal.elf $(output_dir)/test_signal
main.o: main.c
$(CC) $(CFLAGS) -c main.c -o main.o
clean: clean:
rm -f *.o rm test_signal *.o
fmt:

View File

@ -1,239 +0,0 @@
/* Script for -z combreloc */
/* Copyright (C) 2014-2020 Free Software Foundation, Inc.
Copying and distribution of this script, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. */
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64",
"elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(_start)
SECTIONS
{
/* Read-only sections, merged into text segment: */
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x20000000) + SIZEOF_HEADERS;
.interp : { *(.interp) }
.note.gnu.build-id : { *(.note.gnu.build-id) }
.hash : { *(.hash) }
.gnu.hash : { *(.gnu.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rela.dyn :
{
*(.rela.init)
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
*(.rela.fini)
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
*(.rela.ctors)
*(.rela.dtors)
*(.rela.got)
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
*(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*)
*(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*)
*(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*)
*(.rela.ifunc)
}
.rela.plt :
{
*(.rela.plt)
PROVIDE_HIDDEN (__rela_iplt_start = .);
*(.rela.iplt)
PROVIDE_HIDDEN (__rela_iplt_end = .);
}
. = ALIGN(CONSTANT (MAXPAGESIZE));
.init :
{
KEEP (*(SORT_NONE(.init)))
}
.plt : { *(.plt) *(.iplt) }
.plt.got : { *(.plt.got) }
.plt.sec : { *(.plt.sec) }
.text :
{
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text.exit .text.exit.*)
*(.text.startup .text.startup.*)
*(.text.hot .text.hot.*)
*(.text .stub .text.* .gnu.linkonce.t.*)
/* .gnu.warning sections are handled specially by elf.em. */
*(.gnu.warning)
}
.fini :
{
KEEP (*(SORT_NONE(.fini)))
}
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
. = ALIGN(CONSTANT (MAXPAGESIZE));
/* Adjust the address for the rodata segment. We want to adjust up to
the same address within the page on the next page up. */
. = SEGMENT_START("rodata-segment", ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)));
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
.rodata1 : { *(.rodata1) }
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) }
/* These sections are generated by the Sun/Oracle C++ compiler. */
.exception_ranges : ONLY_IF_RO { *(.exception_ranges*) }
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
/* Exception handling */
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }
.gnu_extab : ONLY_IF_RW { *(.gnu_extab) }
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
.exception_ranges : ONLY_IF_RW { *(.exception_ranges*) }
/* Thread Local Storage sections */
.tdata :
{
PROVIDE_HIDDEN (__tdata_start = .);
*(.tdata .tdata.* .gnu.linkonce.td.*)
}
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
}
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
}
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
}
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
}
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
}
.jcr : { KEEP (*(.jcr)) }
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
.dynamic : { *(.dynamic) }
.got : { *(.got) *(.igot) }
. = DATA_SEGMENT_RELRO_END (SIZEOF (.got.plt) >= 24 ? 24 : 0, .);
.got.plt : { *(.got.plt) *(.igot.plt) }
.data :
{
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
}
.data1 : { *(.data1) }
_edata = .; PROVIDE (edata = .);
. = .;
__bss_start = .;
.bss :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections.
FIXME: Why do we need it? When there is no .bss section, we do not
pad the .data section. */
. = ALIGN(. != 0 ? 64 / 8 : 1);
}
.lbss :
{
*(.dynlbss)
*(.lbss .lbss.* .gnu.linkonce.lb.*)
*(LARGE_COMMON)
}
. = ALIGN(64 / 8);
. = SEGMENT_START("ldata-segment", .);
.lrodata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
{
*(.lrodata .lrodata.* .gnu.linkonce.lr.*)
}
.ldata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
{
*(.ldata .ldata.* .gnu.linkonce.l.*)
. = ALIGN(. != 0 ? 64 / 8 : 1);
}
. = ALIGN(64 / 8);
_end = .; PROVIDE (end = .);
. = DATA_SEGMENT_END (.);
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
.gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* DWARF 3 */
.debug_pubtypes 0 : { *(.debug_pubtypes) }
.debug_ranges 0 : { *(.debug_ranges) }
/* DWARF Extension. */
.debug_macro 0 : { *(.debug_macro) }
.debug_addr 0 : { *(.debug_addr) }
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
}

View File

@ -17,13 +17,11 @@
* *
*/ */
#include <math.h>
#include <signal.h> #include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h>
#include <unistd.h>
bool handle_ok = false; bool handle_ok = false;
int count = 0; int count = 0;
void handler(int sig) void handler(int sig)

View File

@ -1,2 +1,3 @@
sqlite*.zip sqlite*.zip
sqlite-*/ sqlite-*/
test_sqlite3

View File

@ -1,34 +1,23 @@
CC=$(DragonOS_GCC)/x86_64-elf-gcc ifeq ($(ARCH), x86_64)
LD=ld CROSS_COMPILE=x86_64-linux-musl-
OBJCOPY=objcopy else ifeq ($(ARCH), riscv64)
CROSS_COMPILE=riscv64-linux-musl-
endif
SQLITE_FILENAME=sqlite-amalgamation-3420000 SQLITE_FILENAME=sqlite-amalgamation-3420000
SQLITE3_DIR=$(shell pwd)/$(SQLITE_FILENAME) SQLITE3_DIR=$(shell pwd)/$(SQLITE_FILENAME)
CC=$(CROSS_COMPILE)gcc
RELIBC_OPT=$(DADK_BUILD_CACHE_DIR_RELIBC_0_1_0) .PHONY: all
CFLAGS=-I $(RELIBC_OPT)/include -I $(SQLITE3_DIR) -D__dragonos__ -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_FLOATING_POINT -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_DEBUG all: main.c $(SQLITE3_DIR)/sqlite3.c
$(CC) -I $(SQLITE3_DIR) -static -o test_sqlite3 main.c $(SQLITE3_DIR)/sqlite3.c
tmp_output_dir=$(ROOT_PATH)/bin/tmp/user .PHONY: install clean download_sqlite3 __download_sqlite3
output_dir=$(DADK_BUILD_CACHE_DIR_TEST_SQLITE3_3_42_0) install: all
mv test_sqlite3 $(DADK_CURRENT_BUILD_DIR)/test_sqlite3
LIBC_OBJS:=$(shell find $(RELIBC_OPT)/lib -name "*.o" | sort ) clean:
LIBC_OBJS+=$(RELIBC_OPT)/lib/libc.a rm test_sqlite3 *.o
.PHONY: all clean download_sqlite3 __download_sqlite3
all: main.o sqlite3.o
mkdir -p $(tmp_output_dir)
$(LD) -b elf64-x86-64 -z muldefs -o $(tmp_output_dir)/test_sqlite3 $(shell find . -name "*.o") $(LIBC_OBJS)
$(OBJCOPY) -I elf64-x86-64 -R ".eh_frame" -R ".comment" -O elf64-x86-64 $(tmp_output_dir)/test_sqlite3 $(output_dir)/test_sqlite3.elf
mv $(output_dir)/test_sqlite3.elf $(output_dir)/test_sqlite3
main.o: main.c
$(CC) $(CFLAGS) -c main.c -o main.o
sqlite3.o: $(SQLITE3_DIR)/sqlite3.c
$(CC) $(CFLAGS) -c $(SQLITE3_DIR)/sqlite3.c -o sqlite3.o
__download_sqlite3: __download_sqlite3:
@echo "Download sqlite3 from https://mirrors.dragonos.org.cn/pub/third_party/sqlite/$(SQLITE_FILENAME).zip" @echo "Download sqlite3 from https://mirrors.dragonos.org.cn/pub/third_party/sqlite/$(SQLITE_FILENAME).zip"
@ -40,5 +29,4 @@ download_sqlite3:
# 如果文件夹不存在,则下载,否则不下载 # 如果文件夹不存在,则下载,否则不下载
@test -d $(SQLITE3_DIR) || $(MAKE) __download_sqlite3 @test -d $(SQLITE3_DIR) || $(MAKE) __download_sqlite3
clean: fmt:
rm -f *.o

View File

@ -1,25 +1,20 @@
CC=$(DragonOS_GCC)/x86_64-elf-gcc ifeq ($(ARCH), x86_64)
LD=ld CROSS_COMPILE=x86_64-linux-musl-
OBJCOPY=objcopy else ifeq ($(ARCH), riscv64)
# 修改这里把它改为你的relibc的sysroot路径 CROSS_COMPILE=riscv64-linux-musl-
RELIBC_OPT=$(DADK_BUILD_CACHE_DIR_RELIBC_0_1_0) endif
CFLAGS=-I $(RELIBC_OPT)/include -D__dragonos__
tmp_output_dir=$(ROOT_PATH)/bin/tmp/user CC=$(CROSS_COMPILE)gcc
output_dir=$(DADK_BUILD_CACHE_DIR_TEST_UART_0_1_0)
LIBC_OBJS:=$(shell find $(RELIBC_OPT)/lib -name "*.o" | sort ) .PHONY: all
LIBC_OBJS+=$(RELIBC_OPT)/lib/libc.a all: main.c
$(CC) -static -o test_uart main.c
all: main.o .PHONY: install clean
mkdir -p $(tmp_output_dir) install: all
mv test_uart $(DADK_CURRENT_BUILD_DIR)/test_uart
$(LD) -b elf64-x86-64 -z muldefs -o $(tmp_output_dir)/test_uart $(shell find . -name "*.o") $(LIBC_OBJS) -T link.lds
$(OBJCOPY) -I elf64-x86-64 -R ".eh_frame" -R ".comment" -O elf64-x86-64 $(tmp_output_dir)/test_uart $(output_dir)/test_uart.elf
mv $(output_dir)/test_uart.elf $(output_dir)/test_uart
main.o: main.c
$(CC) $(CFLAGS) -c main.c -o main.o
clean: clean:
rm -f *.o rm test_uart *.o
fmt:

View File

@ -1,239 +0,0 @@
/* Script for -z combreloc */
/* Copyright (C) 2014-2020 Free Software Foundation, Inc.
Copying and distribution of this script, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. */
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64",
"elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(_start)
SECTIONS
{
/* Read-only sections, merged into text segment: */
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x20000000) + SIZEOF_HEADERS;
.interp : { *(.interp) }
.note.gnu.build-id : { *(.note.gnu.build-id) }
.hash : { *(.hash) }
.gnu.hash : { *(.gnu.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rela.dyn :
{
*(.rela.init)
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
*(.rela.fini)
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
*(.rela.ctors)
*(.rela.dtors)
*(.rela.got)
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
*(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*)
*(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*)
*(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*)
*(.rela.ifunc)
}
.rela.plt :
{
*(.rela.plt)
PROVIDE_HIDDEN (__rela_iplt_start = .);
*(.rela.iplt)
PROVIDE_HIDDEN (__rela_iplt_end = .);
}
. = ALIGN(CONSTANT (MAXPAGESIZE));
.init :
{
KEEP (*(SORT_NONE(.init)))
}
.plt : { *(.plt) *(.iplt) }
.plt.got : { *(.plt.got) }
.plt.sec : { *(.plt.sec) }
.text :
{
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text.exit .text.exit.*)
*(.text.startup .text.startup.*)
*(.text.hot .text.hot.*)
*(.text .stub .text.* .gnu.linkonce.t.*)
/* .gnu.warning sections are handled specially by elf.em. */
*(.gnu.warning)
}
.fini :
{
KEEP (*(SORT_NONE(.fini)))
}
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
. = ALIGN(CONSTANT (MAXPAGESIZE));
/* Adjust the address for the rodata segment. We want to adjust up to
the same address within the page on the next page up. */
. = SEGMENT_START("rodata-segment", ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)));
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
.rodata1 : { *(.rodata1) }
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) }
/* These sections are generated by the Sun/Oracle C++ compiler. */
.exception_ranges : ONLY_IF_RO { *(.exception_ranges*) }
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
/* Exception handling */
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }
.gnu_extab : ONLY_IF_RW { *(.gnu_extab) }
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
.exception_ranges : ONLY_IF_RW { *(.exception_ranges*) }
/* Thread Local Storage sections */
.tdata :
{
PROVIDE_HIDDEN (__tdata_start = .);
*(.tdata .tdata.* .gnu.linkonce.td.*)
}
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
}
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
}
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
}
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
}
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
}
.jcr : { KEEP (*(.jcr)) }
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
.dynamic : { *(.dynamic) }
.got : { *(.got) *(.igot) }
. = DATA_SEGMENT_RELRO_END (SIZEOF (.got.plt) >= 24 ? 24 : 0, .);
.got.plt : { *(.got.plt) *(.igot.plt) }
.data :
{
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
}
.data1 : { *(.data1) }
_edata = .; PROVIDE (edata = .);
. = .;
__bss_start = .;
.bss :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections.
FIXME: Why do we need it? When there is no .bss section, we do not
pad the .data section. */
. = ALIGN(. != 0 ? 64 / 8 : 1);
}
.lbss :
{
*(.dynlbss)
*(.lbss .lbss.* .gnu.linkonce.lb.*)
*(LARGE_COMMON)
}
. = ALIGN(64 / 8);
. = SEGMENT_START("ldata-segment", .);
.lrodata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
{
*(.lrodata .lrodata.* .gnu.linkonce.lr.*)
}
.ldata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
{
*(.ldata .ldata.* .gnu.linkonce.l.*)
. = ALIGN(. != 0 ? 64 / 8 : 1);
}
. = ALIGN(64 / 8);
_end = .; PROVIDE (end = .);
. = DATA_SEGMENT_END (.);
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
.gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* DWARF 3 */
.debug_pubtypes 0 : { *(.debug_pubtypes) }
.debug_ranges 0 : { *(.debug_ranges) }
/* DWARF Extension. */
.debug_macro 0 : { *(.debug_macro) }
.debug_addr 0 : { *(.debug_addr) }
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
}

View File

@ -1,6 +1,5 @@
#include <fcntl.h> #include <fcntl.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
@ -21,11 +20,11 @@ int main() {
} }
} }
} }
printf("fd: %ld", fd); printf("fd: %d", fd);
// 写入字符串 // 写入字符串
char *str = "------fuck-----"; char *str = "------fuck-----";
int len = write(fd, str, strlen(str)); int len = write(fd, str, strlen(str));
printf("len: %ld", len); printf("len: %d", len);
// 关闭文件 // 关闭文件
close(fd); close(fd);
return 0; return 0;

View File

View File

@ -0,0 +1,24 @@
{
"name": "about",
"version": "0.1.0",
"description": "",
"rust_target": null,
"task_type": {
"BuildFromSource": {
"Local": {
"path": "apps/about"
}
}
},
"depends": [],
"build": {
"build_command": "make install"
},
"install": {
"in_dragonos_path": "/bin"
},
"clean": {
"clean_command": "make clean"
},
"envs": []
}

View File

@ -9,9 +9,9 @@
} }
} }
}, },
"depends": [ ], "depends": [],
"build": { "build": {
"build_command": "make" "build_command": "make install -j $(nproc)"
}, },
"install": { "install": {
"in_dragonos_path": "/bin" "in_dragonos_path": "/bin"

View File

@ -9,14 +9,9 @@
} }
} }
}, },
"depends": [ "depends": [],
{
"name": "relibc",
"version": "0.1.0"
}
],
"build": { "build": {
"build_command": "make" "build_command": "make install"
}, },
"install": { "install": {
"in_dragonos_path": "/bin" "in_dragonos_path": "/bin"

View File

@ -0,0 +1,24 @@
{
"name": "musl",
"version": "1.2.4",
"description": "musl libc",
"rust_target": null,
"task_type": {
"BuildFromSource": {
"Archive": {
"url": "https://mirrors.dragonos.org.cn/pub/third_party/musl/musl-1.2.4.tar.gz"
}
}
},
"depends": [],
"build": {
"build_command": "touch config.mak && DESTDIR=$DADK_CURRENT_BUILD_DIR make install -j $(nproc)"
},
"install": {
"in_dragonos_path": "/"
},
"clean": {
"clean_command": "make clean"
},
"envs": []
}

View File

@ -1,29 +0,0 @@
{
"name": "relibc",
"version": "0.1.0",
"description": "从GitHub克隆最新的relibc来编译",
"task_type": {
"BuildFromSource": {
"Git": {
"url": "https://git.mirrors.dragonos.org.cn/DragonOS-Community/relibc.git",
"revision": "27e779dc23"
}
}
},
"depends": [],
"build": {
"build_command": "bash init_dragonos_toolchain.sh && DESTDIR=$DADK_BUILD_CACHE_DIR_RELIBC_0_1_0 make install -j $(nproc)"
},
"install": {
"in_dragonos_path": "/usr"
},
"clean": {
"clean_command": "make clean"
},
"envs": [
{
"key": "TARGET",
"value": "x86_64-unknown-dragonos"
}
]
}

View File

@ -9,14 +9,9 @@
} }
} }
}, },
"depends": [ "depends": [],
{
"name": "relibc",
"version": "0.1.0"
}
],
"build": { "build": {
"build_command": "make" "build_command": "make install"
}, },
"install": { "install": {
"in_dragonos_path": "/bin" "in_dragonos_path": "/bin"

View File

@ -9,25 +9,14 @@
} }
} }
}, },
"depends": [ "depends": [],
{
"name": "relibc",
"version": "0.1.0"
}
],
"build": { "build": {
"build_command": "make" "build_command": "make install"
}, },
"install": { "install": {
"in_dragonos_path": "/bin" "in_dragonos_path": "/bin"
}, },
"clean": { "clean": {
"clean_command": "make clean" "clean_command": "make clean"
}, }
"envs": [
{
"key": "__dragonos__",
"value": "__dragonos__"
}
]
} }

View File

@ -9,14 +9,9 @@
} }
} }
}, },
"depends": [ "depends": [],
{
"name": "relibc",
"version": "0.1.0"
}
],
"build": { "build": {
"build_command": "make" "build_command": "make install"
}, },
"install": { "install": {
"in_dragonos_path": "/bin" "in_dragonos_path": "/bin"

View File

@ -0,0 +1,24 @@
{
"name": "test_kvm",
"version": "0.1.0",
"description": "测试kvm的程序",
"rust_target": null,
"task_type": {
"BuildFromSource": {
"Local": {
"path": "apps/test_kvm"
}
}
},
"depends": [],
"build": {
"build_command": "make install"
},
"install": {
"in_dragonos_path": "/bin"
},
"clean": {
"clean_command": "make clean"
},
"envs": []
}

View File

@ -9,25 +9,14 @@
} }
} }
}, },
"depends": [ "depends": [],
{
"name": "relibc",
"version": "0.1.0"
}
],
"build": { "build": {
"build_command": "make" "build_command": "make install"
}, },
"install": { "install": {
"in_dragonos_path": "/bin" "in_dragonos_path": "/bin"
}, },
"clean": { "clean": {
"clean_command": "make clean" "clean_command": "make clean"
}, }
"envs": [
{
"key": "__dragonos__",
"value": "__dragonos__"
}
]
} }

View File

@ -1,28 +0,0 @@
{
"name": "test_relibc",
"version": "0.1.0",
"description": "一个用来测试relibc能够正常运行的app",
"task_type": {
"BuildFromSource": {
"Local": {
"path": "apps/test_relibc"
}
}
},
"depends": [
{
"name": "relibc",
"version": "0.1.0"
}
],
"build": {
"build_command": "make"
},
"install": {
"in_dragonos_path": "/bin"
},
"clean": {
"clean_command": "make clean"
},
"envs": []
}

View File

@ -9,14 +9,9 @@
} }
} }
}, },
"depends": [ "depends": [],
{
"name": "relibc",
"version": "0.1.0"
}
],
"build": { "build": {
"build_command": "make" "build_command": "make install"
}, },
"install": { "install": {
"in_dragonos_path": "/bin" "in_dragonos_path": "/bin"

View File

@ -9,14 +9,9 @@
} }
} }
}, },
"depends": [ "depends": [],
{
"name": "relibc",
"version": "0.1.0"
}
],
"build": { "build": {
"build_command": "make download_sqlite3 && make -j $(nproc)" "build_command": "make download_sqlite3 && make install"
}, },
"install": { "install": {
"in_dragonos_path": "/bin" "in_dragonos_path": "/bin"

View File

@ -9,14 +9,9 @@
} }
} }
}, },
"depends": [ "depends": [],
{
"name": "relibc",
"version": "0.1.0"
}
],
"build": { "build": {
"build_command": "make" "build_command": "make install"
}, },
"install": { "install": {
"in_dragonos_path": "/bin" "in_dragonos_path": "/bin"

View File

@ -1,35 +0,0 @@
{
"arch": "x86_64",
"code-model": "kernel",
"cpu": "x86-64",
"os": "dragonos",
"target-endian": "little",
"target-pointer-width": "64",
"target-family": [
"unix"
],
"env": "musl",
"target-c-int-width": "32",
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"disable-redzone": true,
"features": "-3dnow,-3dnowa,-avx,-avx2",
"linker": "rust-lld",
"linker-flavor": "ld.lld",
"llvm-target": "x86_64-unknown-none",
"max-atomic-width": 64,
"panic-strategy": "abort",
"position-independent-executables": true,
"relro-level": "full",
"stack-probes": {
"kind": "inline-or-call",
"min-llvm-version-for-inline": [
16,
0,
0
]
},
"static-position-independent-executables": true,
"supported-sanitizers": [
"kcfi"
]
}

View File

@ -1,24 +0,0 @@
user_libs_sub_dirs=libc libsystem libKeyboard
ECHO:
@echo "$@"
$(user_libs_sub_dirs): ECHO
$(MAKE) -C $@ all CFLAGS="$(CFLAGS) -I $(shell pwd)"
all: $(user_libs_sub_dirs)
clean:
@list='$(user_libs_sub_dirs)'; for subdir in $$list; do \
echo "Clean in dir: $$subdir";\
cd $$subdir && $(MAKE) clean;\
cd .. ;\
done
.PHONY: clean
fmt:
@echo "格式化代码: user/libs"
FMT_CHECK=$(FMT_CHECK) $(MAKE) -C libc fmt

View File

@ -1,7 +0,0 @@
all: keyboard.o
CFLAGS += -I .
keyboard.o: keyboard.c
$(CC) $(CFLAGS) -c keyboard.c -o keyboard.o

View File

@ -1,533 +0,0 @@
#include "keyboard.h"
#include <unistd.h>
// 功能键标志变量
static bool shift_l = 0, shift_r = 0, ctrl_l = 0, ctrl_r = 0, alt_l = 0, alt_r = 0;
static bool gui_l = 0, gui_r = 0, apps = 0, insert = 0, home = 0, pgup = 0, del = 0, end = 0, pgdn = 0, arrow_u = 0, arrow_l = 0, arrow_d = 0, arrow_r = 0;
static bool kp_forward_slash = 0, kp_en = 0;
// 键盘扫描码有三种:
// 0xE1开头的PauseBreak键
// 0xE0开头的功能键
// 1byte的普通按键
// pause break键的扫描码没错它就是这么长
unsigned char pause_break_scan_code[] = {0xe1, 0x1d, 0x45, 0xe1, 0x9d, 0xc5};
// 第一套键盘扫描码 及其对应的字符
uint32_t keycode_map_normal[NUM_SCAN_CODES * MAP_COLS] =
{
/*scan-code unShift Shift */
/*--------------------------------------------------------------*/
/*0x00*/ 0,
0,
/*0x01*/ 0,
0, // ESC
/*0x02*/ '1',
'!',
/*0x03*/ '2',
'@',
/*0x04*/ '3',
'#',
/*0x05*/ '4',
'$',
/*0x06*/ '5',
'%',
/*0x07*/ '6',
'^',
/*0x08*/ '7',
'&',
/*0x09*/ '8',
'*',
/*0x0a*/ '9',
'(',
/*0x0b*/ '0',
')',
/*0x0c*/ '-',
'_',
/*0x0d*/ '=',
'+',
/*0x0e*/ '\b',
'\b', // BACKSPACE
/*0x0f*/ '\t',
'\t', // TAB
/*0x10*/ 'q',
'Q',
/*0x11*/ 'w',
'W',
/*0x12*/ 'e',
'E',
/*0x13*/ 'r',
'R',
/*0x14*/ 't',
'T',
/*0x15*/ 'y',
'Y',
/*0x16*/ 'u',
'U',
/*0x17*/ 'i',
'I',
/*0x18*/ 'o',
'O',
/*0x19*/ 'p',
'P',
/*0x1a*/ '[',
'{',
/*0x1b*/ ']',
'}',
/*0x1c*/ '\n',
'\n', // ENTER
/*0x1d*/ 0x1d,
0x1d, // CTRL Left
/*0x1e*/ 'a',
'A',
/*0x1f*/ 's',
'S',
/*0x20*/ 'd',
'D',
/*0x21*/ 'f',
'F',
/*0x22*/ 'g',
'G',
/*0x23*/ 'h',
'H',
/*0x24*/ 'j',
'J',
/*0x25*/ 'k',
'K',
/*0x26*/ 'l',
'L',
/*0x27*/ ';',
':',
/*0x28*/ '\'',
'"',
/*0x29*/ '`',
'~',
/*0x2a*/ 0x2a,
0x2a, // SHIFT Left
/*0x2b*/ '\\',
'|',
/*0x2c*/ 'z',
'Z',
/*0x2d*/ 'x',
'X',
/*0x2e*/ 'c',
'C',
/*0x2f*/ 'v',
'V',
/*0x30*/ 'b',
'B',
/*0x31*/ 'n',
'N',
/*0x32*/ 'm',
'M',
/*0x33*/ ',',
'<',
/*0x34*/ '.',
'>',
/*0x35*/ '/',
'?',
/*0x36*/ 0x36,
0x36, // SHIFT Right
/*0x37*/ '*',
'*',
/*0x38*/ 0x38,
0x38, // ALT Left
/*0x39*/ ' ',
' ',
/*0x3a*/ 0,
0, // CAPS LOCK
/*0x3b*/ 0,
0, // F1
/*0x3c*/ 0,
0, // F2
/*0x3d*/ 0,
0, // F3
/*0x3e*/ 0,
0, // F4
/*0x3f*/ 0,
0, // F5
/*0x40*/ 0,
0, // F6
/*0x41*/ 0,
0, // F7
/*0x42*/ 0,
0, // F8
/*0x43*/ 0,
0, // F9
/*0x44*/ 0,
0, // F10
/*0x45*/ 0,
0, // NUM LOCK
/*0x46*/ 0,
0, // SCROLL LOCK
/*0x47*/ '7',
0, /*PAD HONE*/
/*0x48*/ '8',
0, /*PAD UP*/
/*0x49*/ '9',
0, /*PAD PAGEUP*/
/*0x4a*/ '-',
0, /*PAD MINUS*/
/*0x4b*/ '4',
0, /*PAD LEFT*/
/*0x4c*/ '5',
0, /*PAD MID*/
/*0x4d*/ '6',
0, /*PAD RIGHT*/
/*0x4e*/ '+',
0, /*PAD PLUS*/
/*0x4f*/ '1',
0, /*PAD END*/
/*0x50*/ '2',
0, /*PAD DOWN*/
/*0x51*/ '3',
0, /*PAD PAGEDOWN*/
/*0x52*/ '0',
0, /*PAD INS*/
/*0x53*/ '.',
0, /*PAD DOT*/
/*0x54*/ 0,
0,
/*0x55*/ 0,
0,
/*0x56*/ 0,
0,
/*0x57*/ 0,
0, // F11
/*0x58*/ 0,
0, // F12
/*0x59*/ 0,
0,
/*0x5a*/ 0,
0,
/*0x5b*/ 0,
0,
/*0x5c*/ 0,
0,
/*0x5d*/ 0,
0,
/*0x5e*/ 0,
0,
/*0x5f*/ 0,
0,
/*0x60*/ 0,
0,
/*0x61*/ 0,
0,
/*0x62*/ 0,
0,
/*0x63*/ 0,
0,
/*0x64*/ 0,
0,
/*0x65*/ 0,
0,
/*0x66*/ 0,
0,
/*0x67*/ 0,
0,
/*0x68*/ 0,
0,
/*0x69*/ 0,
0,
/*0x6a*/ 0,
0,
/*0x6b*/ 0,
0,
/*0x6c*/ 0,
0,
/*0x6d*/ 0,
0,
/*0x6e*/ 0,
0,
/*0x6f*/ 0,
0,
/*0x70*/ 0,
0,
/*0x71*/ 0,
0,
/*0x72*/ 0,
0,
/*0x73*/ 0,
0,
/*0x74*/ 0,
0,
/*0x75*/ 0,
0,
/*0x76*/ 0,
0,
/*0x77*/ 0,
0,
/*0x78*/ 0,
0,
/*0x79*/ 0,
0,
/*0x7a*/ 0,
0,
/*0x7b*/ 0,
0,
/*0x7c*/ 0,
0,
/*0x7d*/ 0,
0,
/*0x7e*/ 0,
0,
/*0x7f*/ 0,
0,
};
/**
* @brief
*
*/
int keyboard_analyze_keycode(int fd)
{
bool flag_make = false;
int c = keyboard_get_scancode(fd);
// 循环队列为空
if (c == -1)
return 0;
unsigned char scancode = (unsigned char)c;
int key = 0;
if (scancode == 0xE1) // Pause Break
{
key = PAUSE_BREAK;
// 清除缓冲区中剩下的扫描码
for (int i = 1; i < 6; ++i)
if (keyboard_get_scancode(fd) != pause_break_scan_code[i])
{
key = 0;
break;
}
}
else if (scancode == 0xE0) // 功能键, 有多个扫描码
{
// 获取下一个扫描码
scancode = keyboard_get_scancode(fd);
switch (scancode)
{
case 0x2a: // print screen 按键被按下
if (keyboard_get_scancode(fd) == 0xe0)
if (keyboard_get_scancode(fd) == 0x37)
{
key = PRINT_SCREEN;
flag_make = true;
}
break;
case 0xb7: // print screen 按键被松开
if (keyboard_get_scancode(fd) == 0xe0)
if (keyboard_get_scancode(fd) == 0xaa)
{
key = PRINT_SCREEN;
flag_make = false;
}
break;
case 0x1d: // 按下右边的ctrl
ctrl_r = true;
key = OTHER_KEY;
break;
case 0x9d: // 松开右边的ctrl
ctrl_r = false;
key = OTHER_KEY;
break;
case 0x38: // 按下右边的alt
alt_r = true;
key = OTHER_KEY;
break;
case 0xb8: // 松开右边的alt
alt_r = false;
key = OTHER_KEY;
break;
case 0x5b:
gui_l = true;
key = OTHER_KEY;
break;
case 0xdb:
gui_l = false;
key = OTHER_KEY;
break;
case 0x5c:
gui_r = true;
key = OTHER_KEY;
break;
case 0xdc:
gui_r = false;
key = OTHER_KEY;
break;
case 0x5d:
apps = true;
key = OTHER_KEY;
break;
case 0xdd:
apps = false;
key = OTHER_KEY;
break;
case 0x52:
insert = true;
key = OTHER_KEY;
break;
case 0xd2:
insert = false;
key = OTHER_KEY;
break;
case 0x47:
home = true;
key = OTHER_KEY;
break;
case 0xc7:
home = false;
key = OTHER_KEY;
break;
case 0x49:
pgup = true;
key = OTHER_KEY;
break;
case 0xc9:
pgup = false;
key = OTHER_KEY;
break;
case 0x53:
del = true;
key = OTHER_KEY;
break;
case 0xd3:
del = false;
key = OTHER_KEY;
break;
case 0x4f:
end = true;
key = OTHER_KEY;
break;
case 0xcf:
end = false;
key = OTHER_KEY;
break;
case 0x51:
pgdn = true;
key = OTHER_KEY;
break;
case 0xd1:
pgdn = false;
key = OTHER_KEY;
break;
case 0x48:
arrow_u = true;
key = OTHER_KEY;
break;
case 0xc8:
arrow_u = false;
key = OTHER_KEY;
return 0xc8;
break;
case 0x4b:
arrow_l = true;
key = OTHER_KEY;
break;
case 0xcb:
arrow_l = false;
key = OTHER_KEY;
break;
case 0x50:
arrow_d = true;
key = OTHER_KEY;
return 0x50;
break;
case 0xd0:
arrow_d = false;
key = OTHER_KEY;
break;
case 0x4d:
arrow_r = true;
key = OTHER_KEY;
break;
case 0xcd:
arrow_r = false;
key = OTHER_KEY;
break;
case 0x35: // 数字小键盘的 / 符号
kp_forward_slash = true;
key = OTHER_KEY;
break;
case 0xb5:
kp_forward_slash = false;
key = OTHER_KEY;
break;
case 0x1c:
kp_en = true;
key = OTHER_KEY;
break;
case 0x9c:
kp_en = false;
key = OTHER_KEY;
break;
default:
key = OTHER_KEY;
break;
}
}
if (key == 0) // 属于第三类扫描码
{
// 判断按键是被按下还是抬起
flag_make = ((scancode & FLAG_BREAK) ? 0 : 1);
// 计算扫描码位于码表的第几行
uint32_t *key_row = &keycode_map_normal[(scancode & 0x7f) * MAP_COLS];
unsigned char col = 0;
// shift被按下
if (shift_l || shift_r)
col = 1;
key = key_row[col];
switch (scancode & 0x7f)
{
case 0x2a:
shift_l = flag_make;
key = 0;
break;
case 0x36:
shift_r = flag_make;
key = 0;
break;
case 0x1d:
ctrl_l = flag_make;
key = 0;
break;
case 0x38:
ctrl_r = flag_make;
key = 0;
break;
default:
if (!flag_make)
key = 0;
break;
}
if (key)
return key;
}
return 0;
}
/**
* @brief
*
*/
int keyboard_get_scancode(int fd)
{
unsigned int ret = 0;
read(fd, &ret, 1);
return ret;
}

View File

@ -1,22 +0,0 @@
#pragma once
// 128个按键, 每个按键包含普通按键和shift+普通按键两种状态
#define NUM_SCAN_CODES 0x80
#define MAP_COLS 2
#define PAUSE_BREAK 1
#define PRINT_SCREEN 2
#define OTHER_KEY 4 // 除了上面两个按键以外的功能按键(不包括下面的第三类按键)
#define FLAG_BREAK 0X80
/**
* @brief
*
*/
int keyboard_get_scancode(int fd);
/**
* @brief
*
*/
int keyboard_analyze_keycode(int fd);

View File

@ -1,11 +0,0 @@
[build]
target = "src/arch/x86_64/x86_64-unknown-none.json"
[unstable]
build-std = ["core", "compiler_builtins", "alloc"]
build-std-features = ["compiler-builtins-mem"]
[target.'cfg(target_os = "none")']
runner = "bootimage runner"
[env]

View File

@ -1,2 +0,0 @@
target/
Cargo.lock

View File

@ -1,18 +0,0 @@
[package]
name = "libc"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
crate-type = ["staticlib"]
# 运行时依赖项
[dependencies]
x86_64 = "0.14.10"
# 构建时依赖项
[build-dependencies]
bindgen = "0.61.0"

View File

@ -1,11 +0,0 @@
all:
$(MAKE) CFLAGS="$(CFLAGS)" -C src all
clean:
rm -f Cargo.lock
$(MAKE) -C src clean
.PHONY: fmt
fmt:
cargo fmt --all $(FMT_CHECK)

View File

@ -1,45 +0,0 @@
extern crate bindgen;
// use ::std::env;
use std::path::PathBuf;
fn main() {
// Tell cargo to look for shared libraries in the specified directory
println!("cargo:rustc-link-search=src");
println!("cargo:rerun-if-changed=src/include/internal/bindings/wrapper.h");
// let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
let out_path = PathBuf::from(String::from("src/include/internal/bindings/"));
// The bindgen::Builder is the main entry point
// to bindgen, and lets you build up options for
// the resulting bindings.
{
let bindings = bindgen::Builder::default()
.clang_arg("-I./src/include")
.clang_arg("-I./src/include/export") // todo: 当引入多种架构之后需要修改这里对于不同的架构编译时include不同的路径
// The input header we would like to generate
// bindings for.
.header("src/include/internal/bindings/wrapper.h")
.clang_arg("--target=x86_64-none-none")
.clang_arg("-v")
// 使用core并将c语言的类型改为core::ffi而不是使用std库。
.use_core()
.ctypes_prefix("::core::ffi")
.generate_inline_functions(true)
.raw_line("#![allow(dead_code)]")
.raw_line("#![allow(non_upper_case_globals)]")
.raw_line("#![allow(non_camel_case_types)]")
// Tell cargo to invalidate the built crate whenever any of the
// included header files changed.
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
// Finish the builder and generate the bindings.
.generate()
// Unwrap the Result and panic on failure.
.expect("Unable to generate bindings");
bindings
.write_to_file(out_path.join("bindings.rs"))
.expect("Couldn't write bindings!");
}
}

View File

@ -1,38 +0,0 @@
GARBAGE_PATTERNS := *.o *.s~ *.s *.S~ *.c~ *.h~ kernel
GARBAGE := $(foreach DIR,$(DIRS),$(addprefix $(DIR)/,$(GARBAGE_PATTERNS)))
all: libc
CFLAGS += -I .
libc_sub_dirs=math sys
ifeq ($(ARCH), 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:
@echo "$@"
$(libc_objs): ECHO
$(CC) $(CFLAGS) -c $@ -o $@.o
clean:
cargo clean
rm -rf $(GARBAGE)
@list='$(libc_sub_dirs)'; for subdir in $$list; do \
echo "Clean in dir: $$subdir";\
cd $$subdir && $(MAKE) clean;\
cd .. ;\
done
libc: $(libc_objs) $(libc_sub_dirs) libc_rust
libc_rust:
cargo +nightly-2023-08-15 build --release --target ./arch/x86_64/x86_64-unknown-none.json

View File

@ -1,25 +0,0 @@
libc_arch_objs:= $(shell find ./*.c)
ECHO:
@echo "$@"
$(libc_arch_objs): ECHO
$(CC) $(CFLAGS) -c $@ -o $@.o
# 由于目前使用的是raw的gcc所以不需要crti.o和crtn.o待更换为x86_64-dragonos-gcc后再改这里
# all: $(libc_arch_objs) crti.o crtn.o
all: $(libc_arch_objs)
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."

View File

@ -1,23 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
extern int main(int, char **);
extern void _init();
extern void _libc_init();
void _start(int argc, char **argv)
{
// Run the global constructors.
_init();
_libc_init();
int retval = main(argc, argv);
exit(retval);
}
void _init(){
}
void _fini(){
}

View File

@ -1,13 +0,0 @@
.section .init
.global _init
_init:
push %rbp
movq %rsp, %rbp
/* gcc will nicely put the contents of crtbegin.o's .init section here. */
.section .fini
.global _fini
_fini:
push %rbp
movq %rsp, %rbp
/* gcc will nicely put the contents of crtbegin.o's .fini section here. */

View File

@ -1,9 +0,0 @@
.section .init
/* gcc will nicely put the contents of crtend.o's .init section here. */
popq %rbp
ret
.section .fini
/* gcc will nicely put the contents of crtend.o's .fini section here. */
popq %rbp
ret

View File

@ -1,15 +0,0 @@
{
"llvm-target": "x86_64-unknown-none",
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
"arch": "x86_64",
"target-endian": "little",
"target-pointer-width": "64",
"target-c-int-width": "32",
"os": "none",
"linker": "rust-lld",
"linker-flavor": "ld.lld",
"executables": true,
"features": "-mmx,-sse,+soft-float",
"disable-redzone": true,
"panic-strategy": "abort"
}

View File

@ -1,75 +0,0 @@
#include <ctype.h>
int isprint(int c)
{
if (c >= 0x20 && c <= 0x7e)
{
return 1;
}
return 0;
}
int islower(int c)
{
if (c >= 'a' && c <= 'z')
{
return 1;
}
return 0;
}
int isupper(int c)
{
if (c >= 'A' && c <= 'Z')
{
return 1;
}
return 0;
}
int isalpha(int c)
{
if (islower(c) || isupper(c))
{
return 1;
}
return 0;
}
int isdigit(int c)
{
if (c >= '0' && c <= '9')
{
return 1;
}
return 0;
}
int toupper(int c)
{
if (c >= 'a' && c <= 'z')
{
return c - 'a' + 'A';
}
return c;
}
int tolower(int c)
{
if (c >= 'A' && c <= 'Z')
{
return c - 'A' + 'a';
}
return c;
}
int isspace(int c)
{
return (c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v' || c == ' ');
}

View File

@ -1,8 +0,0 @@
/* Register a function to be called by exit or when a shared library
is unloaded. This function is only called from code generated by
the C++ compiler. */
int __cxa_atexit(void (*func)(void *), void *arg, void *d)
{
// todo: 使用rust实现这个函数。参考http://redox.longjin666.cn/xref/relibc/src/cxa.rs?r=c7d499d4&mo=323&fi=15#15
return 0;
}

View File

@ -1,78 +0,0 @@
#include <dirent.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <libsystem/syscall.h>
/**
* @brief
*
* @param dirname
* @return DIR*
*/
struct DIR *opendir(const char *path)
{
int fd = open(path, O_DIRECTORY);
if (fd < 0) // 目录打开失败
{
printf("Failed to open dir\n");
return NULL;
}
// printf("open dir: %s\n", path);
// 分配DIR结构体
struct DIR *dirp = (struct DIR *)malloc(sizeof(struct DIR));
// printf("dirp = %#018lx", dirp);
memset(dirp, 0, sizeof(struct DIR));
dirp->fd = fd;
dirp->buf_len = DIR_BUF_SIZE;
dirp->buf_pos = 0;
return dirp;
}
/**
* @brief
*
* @param dirp DIR结构体指针
* @return int 0 -1
+--------+--------------------------------+
| errno | |
+--------+--------------------------------+
| 0 | |
| -EBADF | dirp不指向一个打开了的目录 |
| -EINTR | |
+--------+--------------------------------+
*/
int closedir(struct DIR *dirp)
{
int retval = close(dirp->fd);
free(dirp);
return retval;
}
int64_t getdents(int fd, struct dirent *dirent, long count)
{
return syscall_invoke(SYS_GET_DENTS, fd, (uint64_t)dirent, count, 0, 0, 0);
}
/**
* @brief
*
* @param dir
* @return struct dirent*
*/
struct dirent *readdir(struct DIR *dir)
{
// printf("dir->buf = %#018lx\n", (dir->buf));
memset((dir->buf), 0, DIR_BUF_SIZE);
// printf("memeset_ok\n");
int len = getdents(dir->fd, (struct dirent *)dir->buf, DIR_BUF_SIZE);
// printf("len=%d\n", len);
if (len > 0)
return (struct dirent *)dir->buf;
else
return NULL;
}

View File

@ -1,2 +0,0 @@
#include <errno.h>
int errno = 0;

View File

@ -1,28 +0,0 @@
#include <fcntl.h>
#include <libsystem/syscall.h>
/**
* @brief
*
* @param path
* @param options
* @param ...
* @return int
*/
int open(const char *path, int options, ...)
{
return syscall_invoke(SYS_OPEN, (uint64_t)path, options, 0, 0, 0, 0);
}
/**
* @brief ioctl的接口
*
* @param fd
* @param cmd
* @param ...
* @return int 0
*/
int ioctl(int fd, int cmd, uint64_t data, ...)
{
return syscall_invoke(SYS_IOCTL, fd, cmd, data, 0, 0, 0);
}

View File

@ -1,20 +0,0 @@
#pragma once
#pragma once
#ifdef __cplusplus
# define __BEGIN_HEADER \
extern "C" \
{
# define __END_HEADER \
}
#else
# define __BEGIN_HEADER
# define __END_HEADER
#endif

View File

@ -1,44 +0,0 @@
#pragma once
#include <sys/types.h>
#pragma once
#include <__libc__.h>
#if defined(__cplusplus)
extern "C" {
#endif
// int isalnum(int c);
int isalpha(int c);
int isdigit(int c);
int islower(int c);
int isprint(int c);
// int isgraph(int c);
// int iscntrl(int c);
// int isgraph(int c);
// int ispunct(int c);
int isspace(int c);
int isupper(int c);
// int isxdigit(int c);
int isascii(int c);
int tolower(int c);
int toupper(int c);
#define _U 01
#define _L 02
#define _N 04
#define _S 010
#define _P 020
#define _C 040
#define _X 0100
#define _B 0200
extern char _ctype_[256];
#if defined(__cplusplus)
} /* extern "C" */
#endif

View File

@ -1,117 +0,0 @@
#pragma once
#include <sys/types.h>
#if defined(__cplusplus)
extern "C" {
#endif
/*
* This is a header for the common implementation of dirent
* to fs on-disk file type conversion. Although the fs on-disk
* bits are specific to every file system, in practice, many
* file systems use the exact same on-disk format to describe
* the lower 3 file type bits that represent the 7 POSIX file
* types.
*
* It is important to note that the definitions in this
* header MUST NOT change. This would break both the
* userspace ABI and the on-disk format of filesystems
* using this code.
*
* All those file systems can use this generic code for the
* conversions.
*/
/*
* struct dirent file types
* exposed to user via getdents(2), readdir(3)
*
* These match bits 12..15 of stat.st_mode
* (ie "(i_mode >> 12) & 15").
*/
// 完整含义请见 http://www.gnu.org/software/libc/manual/html_node/Directory-Entries.html
#define S_DT_SHIFT 12
#define S_DT(mode) (((mode) & S_IFMT) >> S_DT_SHIFT)
#define S_DT_MASK (S_IFMT >> S_DT_SHIFT)
/* these are defined by POSIX and also present in glibc's dirent.h */
#define DT_UNKNOWN 0
// 命名管道或者FIFO
#define DT_FIFO 1
// 字符设备
#define DT_CHR 2
// 目录
#define DT_DIR 4
// 块设备
#define DT_BLK 6
// 常规文件
#define DT_REG 8
// 符号链接
#define DT_LNK 10
// 是一个socket
#define DT_SOCK 12
// 这个是抄Linux的还不知道含义
#define DT_WHT 14
#define DT_MAX (S_DT_MASK + 1) /* 16 */
#define DIR_BUF_SIZE 256
/**
* @brief
*
*/
struct DIR
{
int fd;
int buf_pos;
int buf_len;
char buf[DIR_BUF_SIZE];
// todo: 加一个指向dirent结构体的指针
};
struct dirent
{
ino_t d_ino; // 文件序列号
off_t d_off; // dir偏移量
unsigned short d_reclen; // 目录下的记录数
unsigned char d_type; // entry的类型
char d_name[]; // 文件entry的名字(是一个零长数组)
};
/**
* @brief
*
* @param dirname
* @return DIR*
*/
struct DIR *opendir(const char *dirname);
/**
* @brief
*
* @param dirp DIR结构体指针
* @return int 0 -1
+--------+--------------------------------+
| errno | |
+--------+--------------------------------+
| 0 | |
| -EBADF | dirp不指向一个打开了的目录 |
| -EINTR | |
+--------+--------------------------------+
*/
int closedir(struct DIR *dirp);
/**
* @brief
*
* @param dir
* @return struct dirent*
*/
struct dirent* readdir(struct DIR* dir);
#if defined(__cplusplus)
} /* extern "C" */
#endif

Some files were not shown because too many files have changed in this diff Show More