mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-18 20:36:31 +00:00
@ -1,15 +1,13 @@
|
||||
|
||||
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)
|
||||
sub_dirs = $(wildcard */)
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@list='$(sub_dirs)'; for subdir in $$list; do \
|
||||
$(MAKE) -C $$subdir clean;\
|
||||
done
|
||||
|
||||
.PHONY: 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_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
|
||||
$(CC) $(CFLAGS) -c about.c -o about.o
|
||||
clean:
|
||||
rm about *.o
|
||||
|
||||
# 生成版本头文件sys_version.h
|
||||
version_header: about.c
|
||||
@echo "#define DRAGONOS_GIT_COMMIT_SHA1 \"$(GIT_COMMIT_SHA1)\"" > sys_version.h
|
||||
|
||||
fmt:
|
||||
|
@ -1,9 +1,7 @@
|
||||
#include "sys_version.h" // 这是系统的版本头文件,在编译过程中自动生成
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void print_ascii_logo()
|
||||
{
|
||||
printf(" ____ ___ ____ \n");
|
||||
@ -13,24 +11,25 @@ void print_ascii_logo()
|
||||
printf("|____/ |_| \\__,_| \\__, | \\___/ |_| |_| \\___/ |____/ \n");
|
||||
printf(" |___/ \n");
|
||||
}
|
||||
|
||||
void print_copyright()
|
||||
{
|
||||
printf(" DragonOS - An opensource operating system.\n");
|
||||
printf(" Copyright: DragonOS Community. 2022-2024, All rights reserved.\n");
|
||||
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(" Build time: %s %s\n", __DATE__, __TIME__);
|
||||
printf(" \nYou can visit the project via:\n");
|
||||
printf("\n");
|
||||
put_string(" Official Website: https://DragonOS.org\n", COLOR_INDIGO, COLOR_BLACK);
|
||||
put_string(" GitHub: https://github.com/DragonOS-Community/DragonOS\n", COLOR_ORANGE, COLOR_BLACK);
|
||||
printf("\x1B[1;36m%s\x1B[0m", " Official Website: https://DragonOS.org\n");
|
||||
printf("\x1B[1;33m%s\x1B[0m", " GitHub: https://github.com/DragonOS-Community/DragonOS\n");
|
||||
printf("\n");
|
||||
printf(" Maintainer: longjin <longjin@DragonOS.org>\n");
|
||||
printf(" Get contact with the community: <contact@DragonOS.org>\n");
|
||||
printf("\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");
|
||||
}
|
||||
|
||||
@ -39,4 +38,4 @@ int main()
|
||||
print_ascii_logo();
|
||||
print_copyright();
|
||||
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)
|
||||
export PREFIX=x86_64-linux-musl-
|
||||
CROSS_COMPILE=x86_64-linux-musl-
|
||||
else ifeq ($(ARCH), riscv64)
|
||||
export PREFIX=riscv64-linux-musl-
|
||||
CROSS_COMPILE=riscv64-linux-musl-
|
||||
endif
|
||||
|
||||
CC=$(CROSS_COMPILE)gcc
|
||||
|
||||
export CC=$(PREFIX)gcc
|
||||
|
||||
all: dmesg
|
||||
mv dmesg $(DADK_CURRENT_BUILD_DIR)
|
||||
|
||||
dmesg: main.c
|
||||
all: 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:
|
||||
rm dmesg *.o
|
||||
rm dmesg *.o
|
||||
|
||||
fmt:
|
||||
|
@ -1,4 +1,6 @@
|
||||
#include "dmesg.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* @brief 识别dmesg程序的第一个选项参数
|
||||
@ -6,7 +8,7 @@
|
||||
* @param arg dmesg命令第一个选项参数
|
||||
* @return int 有效时返回对应选项码,无效时返回 -1
|
||||
*/
|
||||
int getopt(char *arg)
|
||||
int getoption(char *arg)
|
||||
{
|
||||
if (!strcmp(arg, "-h") || !strcmp(arg, "--help"))
|
||||
return 0;
|
||||
|
@ -1,16 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* @brief 识别dmesg程序的第一个选项参数
|
||||
*
|
||||
* @param arg dmesg命令第一个选项参数
|
||||
* @return int 有效时返回对应选项码,无效时返回 -1
|
||||
*/
|
||||
int getopt(char *arg);
|
||||
int getoption(char *arg);
|
||||
|
||||
/**
|
||||
* @brief 识别dmesg程序的第二个选项参数
|
||||
|
@ -1,4 +1,8 @@
|
||||
#include "dmesg.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/klog.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
@ -30,7 +34,7 @@ int main(int argc, char **argv)
|
||||
else
|
||||
{
|
||||
// 获取第一个选项参数
|
||||
opt = getopt(argv[1]);
|
||||
opt = getoption(argv[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
|
||||
LD=ld
|
||||
OBJCOPY=objcopy
|
||||
# 修改这里,把它改为你的relibc的sysroot路径
|
||||
RELIBC_OPT=$(DADK_BUILD_CACHE_DIR_RELIBC_0_1_0)
|
||||
CFLAGS=-I $(RELIBC_OPT)/include -D__dragonos__
|
||||
ifeq ($(ARCH), x86_64)
|
||||
CROSS_COMPILE=x86_64-linux-musl-
|
||||
else ifeq ($(ARCH), riscv64)
|
||||
CROSS_COMPILE=riscv64-linux-musl-
|
||||
endif
|
||||
|
||||
tmp_output_dir=$(ROOT_PATH)/bin/tmp/user
|
||||
output_dir=$(DADK_BUILD_CACHE_DIR_HTTP_SERVER_0_1_0)
|
||||
CC=$(CROSS_COMPILE)gcc
|
||||
|
||||
LIBC_OBJS:=$(shell find $(RELIBC_OPT)/lib -name "*.o" | sort )
|
||||
LIBC_OBJS+=$(RELIBC_OPT)/lib/libc.a
|
||||
.PHONY: all
|
||||
all: main.c
|
||||
$(CC) -static -o http_server main.c
|
||||
|
||||
all: main.o
|
||||
mkdir -p $(tmp_output_dir)
|
||||
|
||||
$(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
|
||||
.PHONY: install clean
|
||||
install: all
|
||||
mv http_server $(DADK_CURRENT_BUILD_DIR)/http_server
|
||||
|
||||
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
|
||||
LD=ld
|
||||
OBJCOPY=objcopy
|
||||
# 修改这里,把它改为你的relibc的sysroot路径
|
||||
RELIBC_OPT=$(DADK_BUILD_CACHE_DIR_RELIBC_0_1_0)
|
||||
CFLAGS=-I $(RELIBC_OPT)/include -D__dragonos__
|
||||
ifeq ($(ARCH), x86_64)
|
||||
CROSS_COMPILE=x86_64-linux-musl-
|
||||
else ifeq ($(ARCH), riscv64)
|
||||
CROSS_COMPILE=riscv64-linux-musl-
|
||||
endif
|
||||
|
||||
tmp_output_dir=$(ROOT_PATH)/bin/tmp/user
|
||||
output_dir=$(DADK_BUILD_CACHE_DIR_TEST_BIND_0_1_0)
|
||||
CC=$(CROSS_COMPILE)gcc
|
||||
|
||||
LIBC_OBJS:=$(shell find $(RELIBC_OPT)/lib -name "*.o" | sort )
|
||||
LIBC_OBJS+=$(RELIBC_OPT)/lib/libc.a
|
||||
.PHONY: all
|
||||
all: main.c
|
||||
$(CC) -static -o test_bind main.c
|
||||
|
||||
all: main.o
|
||||
mkdir -p $(tmp_output_dir)
|
||||
|
||||
$(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
|
||||
.PHONY: install clean
|
||||
install: all
|
||||
mv test_bind $(DADK_CURRENT_BUILD_DIR)/test_bind
|
||||
|
||||
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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.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
|
||||
LD=ld
|
||||
OBJCOPY=objcopy
|
||||
# 修改这里,把它改为你的relibc的sysroot路径
|
||||
RELIBC_OPT=$(DADK_BUILD_CACHE_DIR_RELIBC_0_1_0)
|
||||
CFLAGS=-I $(RELIBC_OPT)/include -D__dragonos__
|
||||
ifeq ($(ARCH), x86_64)
|
||||
CROSS_COMPILE=x86_64-linux-musl-
|
||||
else ifeq ($(ARCH), riscv64)
|
||||
CROSS_COMPILE=riscv64-linux-musl-
|
||||
endif
|
||||
|
||||
tmp_output_dir=$(ROOT_PATH)/bin/tmp/user
|
||||
output_dir=$(DADK_BUILD_CACHE_DIR_TEST_FSTAT_0_1_0)
|
||||
CC=$(CROSS_COMPILE)gcc
|
||||
|
||||
LIBC_OBJS:=$(shell find $(RELIBC_OPT)/lib -name "*.o" | sort )
|
||||
LIBC_OBJS+=$(RELIBC_OPT)/lib/libc.a
|
||||
.PHONY: all
|
||||
all: main.c
|
||||
$(CC) -static -o test_fstat main.c
|
||||
|
||||
all: main.o
|
||||
mkdir -p $(tmp_output_dir)
|
||||
|
||||
$(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
|
||||
.PHONY: install clean
|
||||
install: all
|
||||
mv test_fstat $(DADK_CURRENT_BUILD_DIR)/test_fstat
|
||||
|
||||
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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
int main()
|
||||
{
|
||||
|
||||
int fd = open("/bin/about.elf", O_RDONLY);
|
||||
if (fd == -1)
|
||||
return 0;
|
||||
printf("fd = %d\n", fd);
|
||||
struct stat *st = (struct stat *)malloc(sizeof(struct stat));
|
||||
fstat(fd, st);
|
||||
printf("stat size = %d\n", sizeof(struct stat));
|
||||
printf("stat size = %lu\n", sizeof(struct stat));
|
||||
// FIXME 打印数据时内存出错
|
||||
printf("====================\n");
|
||||
printf("st address: %#018lx\n", st);
|
||||
printf("st_dev = %d\n", (*st).st_dev);
|
||||
printf("st_ino = %d\n", (*st).st_ino);
|
||||
printf("st address: %p\n", st);
|
||||
printf("st_dev = %lu\n", (*st).st_dev);
|
||||
printf("st_ino = %lu\n", (*st).st_ino);
|
||||
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_gid = %d\n", (*st).st_gid);
|
||||
printf("st_rdev = %d\n", (*st).st_rdev);
|
||||
printf("st_size = %d\n", (*st).st_size);
|
||||
printf("st_blksize = %d\n", (*st).st_blksize);
|
||||
printf("st_blocks = %d\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_mtim.sec= %d\tst_mtim.nsec= %d\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_rdev = %lu\n", (*st).st_rdev);
|
||||
printf("st_size = %ld\n", (*st).st_size);
|
||||
printf("st_blksize = %ld\n", (*st).st_blksize);
|
||||
printf("st_blocks = %ld\n", (*st).st_blocks);
|
||||
printf("st_atim.sec= %ld\tst_atim.nsec= %ld\n", (*st).st_atim.tv_sec, (*st).st_atim.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= %ld\tst_ctim.nsec= %ld\n", (*st).st_ctim.tv_sec, (*st).st_ctim.tv_nsec);
|
||||
|
||||
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
|
||||
LD=ld
|
||||
OBJCOPY=objcopy
|
||||
# 修改这里,把它改为你的relibc的sysroot路径
|
||||
RELIBC_OPT=$(DADK_BUILD_CACHE_DIR_RELIBC_0_1_0)
|
||||
CFLAGS=-I $(RELIBC_OPT)/include -D__dragonos__
|
||||
ifeq ($(ARCH), x86_64)
|
||||
CROSS_COMPILE=x86_64-linux-musl-
|
||||
else ifeq ($(ARCH), riscv64)
|
||||
CROSS_COMPILE=riscv64-linux-musl-
|
||||
endif
|
||||
|
||||
tmp_output_dir=$(ROOT_PATH)/bin/tmp/user
|
||||
output_dir=$(DADK_BUILD_CACHE_DIR_TEST_GETTIMEOFDAY_0_1_0)
|
||||
CC=$(CROSS_COMPILE)gcc
|
||||
|
||||
LIBC_OBJS:=$(shell find $(RELIBC_OPT)/lib -name "*.o" | sort )
|
||||
LIBC_OBJS+=$(RELIBC_OPT)/lib/libc.a
|
||||
.PHONY: all
|
||||
all: main.c
|
||||
$(CC) -static -o test_gettimeofday main.c
|
||||
|
||||
all: main.o
|
||||
mkdir -p $(tmp_output_dir)
|
||||
|
||||
$(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
|
||||
.PHONY: install clean
|
||||
install: all
|
||||
mv test_gettimeofday $(DADK_CURRENT_BUILD_DIR)/test_gettimeofday
|
||||
|
||||
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
|
||||
main.o: main.c
|
||||
$(CC) $(CFLAGS) -c main.c -o main.o
|
||||
.PHONY: install clean
|
||||
install: all
|
||||
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
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define KVM_CREATE_VCPU 0x00
|
||||
#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
|
||||
LD=ld
|
||||
OBJCOPY=objcopy
|
||||
# 修改这里,把它改为你的relibc的sysroot路径
|
||||
RELIBC_OPT=$(DADK_BUILD_CACHE_DIR_RELIBC_0_1_0)
|
||||
CFLAGS=-I $(RELIBC_OPT)/include -D__dragonos__
|
||||
ifeq ($(ARCH), x86_64)
|
||||
CROSS_COMPILE=x86_64-linux-musl-
|
||||
else ifeq ($(ARCH), riscv64)
|
||||
CROSS_COMPILE=riscv64-linux-musl-
|
||||
endif
|
||||
|
||||
tmp_output_dir=$(ROOT_PATH)/bin/tmp/user
|
||||
output_dir=$(DADK_BUILD_CACHE_DIR_TEST_MKFIFO_0_1_0)
|
||||
CC=$(CROSS_COMPILE)gcc
|
||||
|
||||
LIBC_OBJS:=$(shell find $(RELIBC_OPT)/lib -name "*.o" | sort )
|
||||
LIBC_OBJS+=$(RELIBC_OPT)/lib/libc.a
|
||||
.PHONY: all
|
||||
all: main.c
|
||||
$(CC) -static -o test_mkfifo main.c
|
||||
|
||||
all: main.o
|
||||
mkdir -p $(tmp_output_dir)
|
||||
|
||||
$(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
|
||||
.PHONY: install clean
|
||||
install: all
|
||||
mv test_mkfifo $(DADK_CURRENT_BUILD_DIR)/test_mkfifo
|
||||
|
||||
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 <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define BUFFER_SIZE 256
|
||||
#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
|
||||
LD=ld
|
||||
OBJCOPY=objcopy
|
||||
# 修改这里,把它改为你的relibc的sysroot路径
|
||||
RELIBC_OPT=$(DADK_BUILD_CACHE_DIR_RELIBC_0_1_0)
|
||||
CFLAGS=-I $(RELIBC_OPT)/include -D__dragonos__
|
||||
ifeq ($(ARCH), x86_64)
|
||||
CROSS_COMPILE=x86_64-linux-musl-
|
||||
else ifeq ($(ARCH), riscv64)
|
||||
CROSS_COMPILE=riscv64-linux-musl-
|
||||
endif
|
||||
|
||||
tmp_output_dir=$(ROOT_PATH)/bin/tmp/user
|
||||
output_dir=$(DADK_BUILD_CACHE_DIR_TEST_SIGNAL_0_1_0)
|
||||
CC=$(CROSS_COMPILE)gcc
|
||||
|
||||
.PHONY: all
|
||||
all: main.c
|
||||
$(CC) -static -o test_signal main.c
|
||||
|
||||
LIBC_OBJS:=$(shell find $(RELIBC_OPT)/lib -name "*.o" | sort )
|
||||
LIBC_OBJS+=$(RELIBC_OPT)/lib/libc.a
|
||||
|
||||
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
|
||||
.PHONY: install clean
|
||||
install: all
|
||||
mv test_signal $(DADK_CURRENT_BUILD_DIR)/test_signal
|
||||
|
||||
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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
bool handle_ok = false;
|
||||
int count = 0;
|
||||
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-*/
|
||||
sqlite-*/
|
||||
test_sqlite3
|
||||
|
@ -1,34 +1,23 @@
|
||||
CC=$(DragonOS_GCC)/x86_64-elf-gcc
|
||||
LD=ld
|
||||
OBJCOPY=objcopy
|
||||
ifeq ($(ARCH), x86_64)
|
||||
CROSS_COMPILE=x86_64-linux-musl-
|
||||
else ifeq ($(ARCH), riscv64)
|
||||
CROSS_COMPILE=riscv64-linux-musl-
|
||||
endif
|
||||
|
||||
SQLITE_FILENAME=sqlite-amalgamation-3420000
|
||||
SQLITE3_DIR=$(shell pwd)/$(SQLITE_FILENAME)
|
||||
CC=$(CROSS_COMPILE)gcc
|
||||
|
||||
RELIBC_OPT=$(DADK_BUILD_CACHE_DIR_RELIBC_0_1_0)
|
||||
CFLAGS=-I $(RELIBC_OPT)/include -I $(SQLITE3_DIR) -D__dragonos__ -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_FLOATING_POINT -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_DEBUG
|
||||
.PHONY: all
|
||||
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
|
||||
output_dir=$(DADK_BUILD_CACHE_DIR_TEST_SQLITE3_3_42_0)
|
||||
.PHONY: install clean download_sqlite3 __download_sqlite3
|
||||
install: all
|
||||
mv test_sqlite3 $(DADK_CURRENT_BUILD_DIR)/test_sqlite3
|
||||
|
||||
LIBC_OBJS:=$(shell find $(RELIBC_OPT)/lib -name "*.o" | sort )
|
||||
LIBC_OBJS+=$(RELIBC_OPT)/lib/libc.a
|
||||
|
||||
.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
|
||||
clean:
|
||||
rm test_sqlite3 *.o
|
||||
|
||||
__download_sqlite3:
|
||||
@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
|
||||
|
||||
clean:
|
||||
rm -f *.o
|
||||
fmt:
|
||||
|
@ -1,25 +1,20 @@
|
||||
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__
|
||||
ifeq ($(ARCH), x86_64)
|
||||
CROSS_COMPILE=x86_64-linux-musl-
|
||||
else ifeq ($(ARCH), riscv64)
|
||||
CROSS_COMPILE=riscv64-linux-musl-
|
||||
endif
|
||||
|
||||
tmp_output_dir=$(ROOT_PATH)/bin/tmp/user
|
||||
output_dir=$(DADK_BUILD_CACHE_DIR_TEST_UART_0_1_0)
|
||||
CC=$(CROSS_COMPILE)gcc
|
||||
|
||||
LIBC_OBJS:=$(shell find $(RELIBC_OPT)/lib -name "*.o" | sort )
|
||||
LIBC_OBJS+=$(RELIBC_OPT)/lib/libc.a
|
||||
.PHONY: all
|
||||
all: main.c
|
||||
$(CC) -static -o test_uart main.c
|
||||
|
||||
all: main.o
|
||||
mkdir -p $(tmp_output_dir)
|
||||
|
||||
$(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
|
||||
.PHONY: install clean
|
||||
install: all
|
||||
mv test_uart $(DADK_CURRENT_BUILD_DIR)/test_uart
|
||||
|
||||
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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@ -21,11 +20,11 @@ int main() {
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("fd: %ld", fd);
|
||||
printf("fd: %d", fd);
|
||||
// 写入字符串
|
||||
char *str = "------fuck-----";
|
||||
int len = write(fd, str, strlen(str));
|
||||
printf("len: %ld", len);
|
||||
printf("len: %d", len);
|
||||
// 关闭文件
|
||||
close(fd);
|
||||
return 0;
|
||||
|
Reference in New Issue
Block a user