mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 14:16:47 +00:00
parent
f3b05a97ec
commit
bc6f0a967c
1
.github/workflows/makefile.yml
vendored
1
.github/workflows/makefile.yml
vendored
@ -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
2
.gitignore
vendored
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
1
user/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/libs/
|
@ -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) dadk_run
|
||||||
|
$(MAKE) copy_services
|
||||||
|
|
||||||
$(MAKE) -C $@ all CFLAGS="$(CFLAGS)" tmp_output_dir="$(tmp_output_dir)" output_dir="$(output_dir)" sys_libs_dir="$(shell pwd)/libs"
|
@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
|
|
||||||
|
@ -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
|
||||||
|
3
user/apps/about/.gitignore
vendored
3
user/apps/about/.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
sys_version.h
|
sys_version.h
|
||||||
|
about
|
||||||
|
@ -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:
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,4 +38,4 @@ int main()
|
|||||||
print_ascii_logo();
|
print_ascii_logo();
|
||||||
print_copyright();
|
print_copyright();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -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,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:
|
||||||
|
@ -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;
|
||||||
|
@ -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程序的第二个选项参数
|
||||||
|
@ -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
1
user/apps/http_server/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
http_server
|
@ -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:
|
||||||
|
@ -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,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
|
|
@ -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);
|
|
||||||
}
|
|
@ -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);
|
|
@ -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");
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "cmd.h"
|
|
||||||
int shell_help(int argc, char **argv);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief cd命令的帮助信息
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void shell_help_cd();
|
|
@ -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;
|
|
||||||
}
|
|
@ -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);
|
|
@ -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");
|
|
||||||
}
|
|
@ -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
1
user/apps/test_bind/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
test_bind
|
@ -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:
|
||||||
|
@ -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_*) }
|
|
||||||
}
|
|
@ -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
1
user/apps/test_fstat/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
test_fstat
|
@ -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:
|
||||||
|
@ -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,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;
|
||||||
}
|
}
|
1
user/apps/test_gettimeofday/.gitignore
vendored
Normal file
1
user/apps/test_gettimeofday/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
test_gettimeofday
|
@ -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:
|
||||||
|
@ -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
1
user/apps/test_kvm/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
test_kvm
|
@ -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:
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
boot.bin: boot.s
|
|
||||||
nasm boot.s -o boot.bin
|
|
||||||
xxd boot.bin > boot.hex
|
|
Binary file not shown.
@ -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.
|
|
@ -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 = .;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -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
1
user/apps/test_mkfifo/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
test_mkfifo
|
@ -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:
|
||||||
|
@ -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,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"
|
||||||
|
@ -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
|
|
@ -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,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
1
user/apps/test_signal/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
test_signal
|
@ -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:
|
||||||
|
@ -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_*) }
|
|
||||||
}
|
|
@ -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)
|
||||||
|
3
user/apps/test_sqlite3/.gitignore
vendored
3
user/apps/test_sqlite3/.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
sqlite*.zip
|
sqlite*.zip
|
||||||
sqlite-*/
|
sqlite-*/
|
||||||
|
test_sqlite3
|
||||||
|
@ -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
|
|
||||||
|
@ -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:
|
||||||
|
@ -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,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;
|
||||||
|
0
user/dadk/config/.gitignore
vendored
0
user/dadk/config/.gitignore
vendored
24
user/dadk/config/about.dadk
Normal file
24
user/dadk/config/about.dadk
Normal 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": []
|
||||||
|
}
|
@ -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"
|
||||||
|
@ -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"
|
||||||
|
24
user/dadk/config/musl_1_2_4.dadk
Normal file
24
user/dadk/config/musl_1_2_4.dadk
Normal 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": []
|
||||||
|
}
|
@ -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"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -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"
|
||||||
|
@ -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__"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
@ -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"
|
||||||
|
24
user/dadk/config/test_kvm_0_1_0.dadk
Normal file
24
user/dadk/config/test_kvm_0_1_0.dadk
Normal 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": []
|
||||||
|
}
|
@ -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__"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
@ -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": []
|
|
||||||
}
|
|
@ -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"
|
||||||
|
@ -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"
|
||||||
|
@ -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"
|
||||||
|
@ -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"
|
|
||||||
]
|
|
||||||
}
|
|
@ -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
|
|
@ -1,7 +0,0 @@
|
|||||||
all: keyboard.o
|
|
||||||
|
|
||||||
CFLAGS += -I .
|
|
||||||
|
|
||||||
|
|
||||||
keyboard.o: keyboard.c
|
|
||||||
$(CC) $(CFLAGS) -c keyboard.c -o keyboard.o
|
|
@ -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;
|
|
||||||
}
|
|
@ -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);
|
|
@ -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]
|
|
2
user/libs/libc/.gitignore
vendored
2
user/libs/libc/.gitignore
vendored
@ -1,2 +0,0 @@
|
|||||||
target/
|
|
||||||
Cargo.lock
|
|
@ -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"
|
|
||||||
|
|
||||||
|
|
@ -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)
|
|
@ -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!");
|
|
||||||
}
|
|
||||||
}
|
|
@ -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
|
|
@ -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."
|
|
@ -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(){
|
|
||||||
|
|
||||||
}
|
|
@ -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. */
|
|
@ -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
|
|
@ -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"
|
|
||||||
}
|
|
@ -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 == ' ');
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
@ -1,2 +0,0 @@
|
|||||||
#include <errno.h>
|
|
||||||
int errno = 0;
|
|
@ -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);
|
|
||||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
Loading…
x
Reference in New Issue
Block a user