Compare commits

...

7 Commits

Author SHA1 Message Date
rcy17 723c808621 Fix CI 2023-03-03 00:00:25 +08:00
Campbell He b238448f61
chore: upgrade rustsbi-qemu and add gitlab mirror action 2022-10-06 21:14:35 +08:00
Campbell He f5e3ea3d43
docs: add info of user 2022-10-06 13:55:31 +08:00
Campbell He 64b1ce9b07
ci: fix repo url 2022-10-05 09:36:34 +08:00
Campbell He b368e01771
ci: add gitlab-ci.yml 2022-10-05 09:32:28 +08:00
rcy17 235e2ca5f5 ch2 2022-03-09 20:39:08 +08:00
rcy17 8645ae06c1 ch1 2022-03-09 20:38:26 +08:00
36 changed files with 2511 additions and 0 deletions

561
.clang-format Normal file
View File

@ -0,0 +1,561 @@
# SPDX-License-Identifier: GPL-2.0
#
# clang-format configuration file. Intended for clang-format >= 4.
#
# For more information, see:
#
# Documentation/process/clang-format.rst
# https://clang.llvm.org/docs/ClangFormat.html
# https://clang.llvm.org/docs/ClangFormatStyleOptions.html
#
---
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
#AlignEscapedNewlines: Left # Unknown to clang-format-4.0
AlignOperands: true
AlignTrailingComments: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: false
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: true
AfterNamespace: true
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
#AfterExternBlock: false # Unknown to clang-format-5.0
BeforeCatch: false
BeforeElse: false
IndentBraces: false
#SplitEmptyFunction: true # Unknown to clang-format-4.0
#SplitEmptyRecord: true # Unknown to clang-format-4.0
#SplitEmptyNamespace: true # Unknown to clang-format-4.0
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
#BreakBeforeInheritanceComma: false # Unknown to clang-format-4.0
BreakBeforeTernaryOperators: false
BreakConstructorInitializersBeforeComma: false
#BreakConstructorInitializers: BeforeComma # Unknown to clang-format-4.0
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: false
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
#CompactNamespaces: false # Unknown to clang-format-4.0
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 8
ContinuationIndentWidth: 8
Cpp11BracedListStyle: false
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
#FixNamespaceComments: false # Unknown to clang-format-4.0
# Taken from:
# git grep -h '^#define [^[:space:]]*for_each[^[:space:]]*(' include/ \
# | sed "s,^#define \([^[:space:]]*for_each[^[:space:]]*\)(.*$, - '\1'," \
# | sort | uniq
ForEachMacros:
- 'apei_estatus_for_each_section'
- 'ata_for_each_dev'
- 'ata_for_each_link'
- '__ata_qc_for_each'
- 'ata_qc_for_each'
- 'ata_qc_for_each_raw'
- 'ata_qc_for_each_with_internal'
- 'ax25_for_each'
- 'ax25_uid_for_each'
- '__bio_for_each_bvec'
- 'bio_for_each_bvec'
- 'bio_for_each_bvec_all'
- 'bio_for_each_integrity_vec'
- '__bio_for_each_segment'
- 'bio_for_each_segment'
- 'bio_for_each_segment_all'
- 'bio_list_for_each'
- 'bip_for_each_vec'
- 'bitmap_for_each_clear_region'
- 'bitmap_for_each_set_region'
- 'blkg_for_each_descendant_post'
- 'blkg_for_each_descendant_pre'
- 'blk_queue_for_each_rl'
- 'bond_for_each_slave'
- 'bond_for_each_slave_rcu'
- 'bpf_for_each_spilled_reg'
- 'btree_for_each_safe128'
- 'btree_for_each_safe32'
- 'btree_for_each_safe64'
- 'btree_for_each_safel'
- 'card_for_each_dev'
- 'cgroup_taskset_for_each'
- 'cgroup_taskset_for_each_leader'
- 'cpufreq_for_each_entry'
- 'cpufreq_for_each_entry_idx'
- 'cpufreq_for_each_valid_entry'
- 'cpufreq_for_each_valid_entry_idx'
- 'css_for_each_child'
- 'css_for_each_descendant_post'
- 'css_for_each_descendant_pre'
- 'device_for_each_child_node'
- 'displayid_iter_for_each'
- 'dma_fence_chain_for_each'
- 'do_for_each_ftrace_op'
- 'drm_atomic_crtc_for_each_plane'
- 'drm_atomic_crtc_state_for_each_plane'
- 'drm_atomic_crtc_state_for_each_plane_state'
- 'drm_atomic_for_each_plane_damage'
- 'drm_client_for_each_connector_iter'
- 'drm_client_for_each_modeset'
- 'drm_connector_for_each_possible_encoder'
- 'drm_for_each_bridge_in_chain'
- 'drm_for_each_connector_iter'
- 'drm_for_each_crtc'
- 'drm_for_each_crtc_reverse'
- 'drm_for_each_encoder'
- 'drm_for_each_encoder_mask'
- 'drm_for_each_fb'
- 'drm_for_each_legacy_plane'
- 'drm_for_each_plane'
- 'drm_for_each_plane_mask'
- 'drm_for_each_privobj'
- 'drm_mm_for_each_hole'
- 'drm_mm_for_each_node'
- 'drm_mm_for_each_node_in_range'
- 'drm_mm_for_each_node_safe'
- 'flow_action_for_each'
- 'for_each_acpi_dev_match'
- 'for_each_active_dev_scope'
- 'for_each_active_drhd_unit'
- 'for_each_active_iommu'
- 'for_each_aggr_pgid'
- 'for_each_available_child_of_node'
- 'for_each_bio'
- 'for_each_board_func_rsrc'
- 'for_each_bvec'
- 'for_each_card_auxs'
- 'for_each_card_auxs_safe'
- 'for_each_card_components'
- 'for_each_card_dapms'
- 'for_each_card_pre_auxs'
- 'for_each_card_prelinks'
- 'for_each_card_rtds'
- 'for_each_card_rtds_safe'
- 'for_each_card_widgets'
- 'for_each_card_widgets_safe'
- 'for_each_cgroup_storage_type'
- 'for_each_child_of_node'
- 'for_each_clear_bit'
- 'for_each_clear_bit_from'
- 'for_each_cmsghdr'
- 'for_each_compatible_node'
- 'for_each_component_dais'
- 'for_each_component_dais_safe'
- 'for_each_comp_order'
- 'for_each_console'
- 'for_each_cpu'
- 'for_each_cpu_and'
- 'for_each_cpu_not'
- 'for_each_cpu_wrap'
- 'for_each_dapm_widgets'
- 'for_each_dev_addr'
- 'for_each_dev_scope'
- 'for_each_dma_cap_mask'
- 'for_each_dpcm_be'
- 'for_each_dpcm_be_rollback'
- 'for_each_dpcm_be_safe'
- 'for_each_dpcm_fe'
- 'for_each_drhd_unit'
- 'for_each_dss_dev'
- 'for_each_dtpm_table'
- 'for_each_efi_memory_desc'
- 'for_each_efi_memory_desc_in_map'
- 'for_each_element'
- 'for_each_element_extid'
- 'for_each_element_id'
- 'for_each_endpoint_of_node'
- 'for_each_evictable_lru'
- 'for_each_fib6_node_rt_rcu'
- 'for_each_fib6_walker_rt'
- 'for_each_free_mem_pfn_range_in_zone'
- 'for_each_free_mem_pfn_range_in_zone_from'
- 'for_each_free_mem_range'
- 'for_each_free_mem_range_reverse'
- 'for_each_func_rsrc'
- 'for_each_hstate'
- 'for_each_if'
- 'for_each_iommu'
- 'for_each_ip_tunnel_rcu'
- 'for_each_irq_nr'
- 'for_each_link_codecs'
- 'for_each_link_cpus'
- 'for_each_link_platforms'
- 'for_each_lru'
- 'for_each_matching_node'
- 'for_each_matching_node_and_match'
- 'for_each_member'
- 'for_each_memcg_cache_index'
- 'for_each_mem_pfn_range'
- '__for_each_mem_range'
- 'for_each_mem_range'
- '__for_each_mem_range_rev'
- 'for_each_mem_range_rev'
- 'for_each_mem_region'
- 'for_each_migratetype_order'
- 'for_each_msi_entry'
- 'for_each_msi_entry_safe'
- 'for_each_msi_vector'
- 'for_each_net'
- 'for_each_net_continue_reverse'
- 'for_each_netdev'
- 'for_each_netdev_continue'
- 'for_each_netdev_continue_rcu'
- 'for_each_netdev_continue_reverse'
- 'for_each_netdev_feature'
- 'for_each_netdev_in_bond_rcu'
- 'for_each_netdev_rcu'
- 'for_each_netdev_reverse'
- 'for_each_netdev_safe'
- 'for_each_net_rcu'
- 'for_each_new_connector_in_state'
- 'for_each_new_crtc_in_state'
- 'for_each_new_mst_mgr_in_state'
- 'for_each_new_plane_in_state'
- 'for_each_new_private_obj_in_state'
- 'for_each_node'
- 'for_each_node_by_name'
- 'for_each_node_by_type'
- 'for_each_node_mask'
- 'for_each_node_state'
- 'for_each_node_with_cpus'
- 'for_each_node_with_property'
- 'for_each_nonreserved_multicast_dest_pgid'
- 'for_each_of_allnodes'
- 'for_each_of_allnodes_from'
- 'for_each_of_cpu_node'
- 'for_each_of_pci_range'
- 'for_each_old_connector_in_state'
- 'for_each_old_crtc_in_state'
- 'for_each_old_mst_mgr_in_state'
- 'for_each_oldnew_connector_in_state'
- 'for_each_oldnew_crtc_in_state'
- 'for_each_oldnew_mst_mgr_in_state'
- 'for_each_oldnew_plane_in_state'
- 'for_each_oldnew_plane_in_state_reverse'
- 'for_each_oldnew_private_obj_in_state'
- 'for_each_old_plane_in_state'
- 'for_each_old_private_obj_in_state'
- 'for_each_online_cpu'
- 'for_each_online_node'
- 'for_each_online_pgdat'
- 'for_each_pci_bridge'
- 'for_each_pci_dev'
- 'for_each_pci_msi_entry'
- 'for_each_pcm_streams'
- 'for_each_physmem_range'
- 'for_each_populated_zone'
- 'for_each_possible_cpu'
- 'for_each_present_cpu'
- 'for_each_prime_number'
- 'for_each_prime_number_from'
- 'for_each_process'
- 'for_each_process_thread'
- 'for_each_prop_codec_conf'
- 'for_each_prop_dai_codec'
- 'for_each_prop_dai_cpu'
- 'for_each_prop_dlc_codecs'
- 'for_each_prop_dlc_cpus'
- 'for_each_prop_dlc_platforms'
- 'for_each_property_of_node'
- 'for_each_registered_fb'
- 'for_each_requested_gpio'
- 'for_each_requested_gpio_in_range'
- 'for_each_reserved_mem_range'
- 'for_each_reserved_mem_region'
- 'for_each_rtd_codec_dais'
- 'for_each_rtd_components'
- 'for_each_rtd_cpu_dais'
- 'for_each_rtd_dais'
- 'for_each_set_bit'
- 'for_each_set_bit_from'
- 'for_each_set_clump8'
- 'for_each_sg'
- 'for_each_sg_dma_page'
- 'for_each_sg_page'
- 'for_each_sgtable_dma_page'
- 'for_each_sgtable_dma_sg'
- 'for_each_sgtable_page'
- 'for_each_sgtable_sg'
- 'for_each_sibling_event'
- 'for_each_subelement'
- 'for_each_subelement_extid'
- 'for_each_subelement_id'
- '__for_each_thread'
- 'for_each_thread'
- 'for_each_unicast_dest_pgid'
- 'for_each_vsi'
- 'for_each_wakeup_source'
- 'for_each_zone'
- 'for_each_zone_zonelist'
- 'for_each_zone_zonelist_nodemask'
- 'fwnode_for_each_available_child_node'
- 'fwnode_for_each_child_node'
- 'fwnode_graph_for_each_endpoint'
- 'gadget_for_each_ep'
- 'genradix_for_each'
- 'genradix_for_each_from'
- 'hash_for_each'
- 'hash_for_each_possible'
- 'hash_for_each_possible_rcu'
- 'hash_for_each_possible_rcu_notrace'
- 'hash_for_each_possible_safe'
- 'hash_for_each_rcu'
- 'hash_for_each_safe'
- 'hctx_for_each_ctx'
- 'hlist_bl_for_each_entry'
- 'hlist_bl_for_each_entry_rcu'
- 'hlist_bl_for_each_entry_safe'
- 'hlist_for_each'
- 'hlist_for_each_entry'
- 'hlist_for_each_entry_continue'
- 'hlist_for_each_entry_continue_rcu'
- 'hlist_for_each_entry_continue_rcu_bh'
- 'hlist_for_each_entry_from'
- 'hlist_for_each_entry_from_rcu'
- 'hlist_for_each_entry_rcu'
- 'hlist_for_each_entry_rcu_bh'
- 'hlist_for_each_entry_rcu_notrace'
- 'hlist_for_each_entry_safe'
- 'hlist_for_each_entry_srcu'
- '__hlist_for_each_rcu'
- 'hlist_for_each_safe'
- 'hlist_nulls_for_each_entry'
- 'hlist_nulls_for_each_entry_from'
- 'hlist_nulls_for_each_entry_rcu'
- 'hlist_nulls_for_each_entry_safe'
- 'i3c_bus_for_each_i2cdev'
- 'i3c_bus_for_each_i3cdev'
- 'ide_host_for_each_port'
- 'ide_port_for_each_dev'
- 'ide_port_for_each_present_dev'
- 'idr_for_each_entry'
- 'idr_for_each_entry_continue'
- 'idr_for_each_entry_continue_ul'
- 'idr_for_each_entry_ul'
- 'in_dev_for_each_ifa_rcu'
- 'in_dev_for_each_ifa_rtnl'
- 'inet_bind_bucket_for_each'
- 'inet_lhash2_for_each_icsk_rcu'
- 'key_for_each'
- 'key_for_each_safe'
- 'klp_for_each_func'
- 'klp_for_each_func_safe'
- 'klp_for_each_func_static'
- 'klp_for_each_object'
- 'klp_for_each_object_safe'
- 'klp_for_each_object_static'
- 'kunit_suite_for_each_test_case'
- 'kvm_for_each_memslot'
- 'kvm_for_each_vcpu'
- 'list_for_each'
- 'list_for_each_codec'
- 'list_for_each_codec_safe'
- 'list_for_each_continue'
- 'list_for_each_entry'
- 'list_for_each_entry_continue'
- 'list_for_each_entry_continue_rcu'
- 'list_for_each_entry_continue_reverse'
- 'list_for_each_entry_from'
- 'list_for_each_entry_from_rcu'
- 'list_for_each_entry_from_reverse'
- 'list_for_each_entry_lockless'
- 'list_for_each_entry_rcu'
- 'list_for_each_entry_reverse'
- 'list_for_each_entry_safe'
- 'list_for_each_entry_safe_continue'
- 'list_for_each_entry_safe_from'
- 'list_for_each_entry_safe_reverse'
- 'list_for_each_entry_srcu'
- 'list_for_each_prev'
- 'list_for_each_prev_safe'
- 'list_for_each_safe'
- 'llist_for_each'
- 'llist_for_each_entry'
- 'llist_for_each_entry_safe'
- 'llist_for_each_safe'
- 'mci_for_each_dimm'
- 'media_device_for_each_entity'
- 'media_device_for_each_intf'
- 'media_device_for_each_link'
- 'media_device_for_each_pad'
- 'nanddev_io_for_each_page'
- 'netdev_for_each_lower_dev'
- 'netdev_for_each_lower_private'
- 'netdev_for_each_lower_private_rcu'
- 'netdev_for_each_mc_addr'
- 'netdev_for_each_uc_addr'
- 'netdev_for_each_upper_dev_rcu'
- 'netdev_hw_addr_list_for_each'
- 'nft_rule_for_each_expr'
- 'nla_for_each_attr'
- 'nla_for_each_nested'
- 'nlmsg_for_each_attr'
- 'nlmsg_for_each_msg'
- 'nr_neigh_for_each'
- 'nr_neigh_for_each_safe'
- 'nr_node_for_each'
- 'nr_node_for_each_safe'
- 'of_for_each_phandle'
- 'of_property_for_each_string'
- 'of_property_for_each_u32'
- 'pci_bus_for_each_resource'
- 'pcl_for_each_chunk'
- 'pcl_for_each_segment'
- 'pcm_for_each_format'
- 'ping_portaddr_for_each_entry'
- 'plist_for_each'
- 'plist_for_each_continue'
- 'plist_for_each_entry'
- 'plist_for_each_entry_continue'
- 'plist_for_each_entry_safe'
- 'plist_for_each_safe'
- 'pnp_for_each_card'
- 'pnp_for_each_dev'
- 'protocol_for_each_card'
- 'protocol_for_each_dev'
- 'queue_for_each_hw_ctx'
- 'radix_tree_for_each_slot'
- 'radix_tree_for_each_tagged'
- 'rb_for_each'
- 'rbtree_postorder_for_each_entry_safe'
- 'rdma_for_each_block'
- 'rdma_for_each_port'
- 'rdma_umem_for_each_dma_block'
- 'resource_list_for_each_entry'
- 'resource_list_for_each_entry_safe'
- 'rhl_for_each_entry_rcu'
- 'rhl_for_each_rcu'
- 'rht_for_each'
- 'rht_for_each_entry'
- 'rht_for_each_entry_from'
- 'rht_for_each_entry_rcu'
- 'rht_for_each_entry_rcu_from'
- 'rht_for_each_entry_safe'
- 'rht_for_each_from'
- 'rht_for_each_rcu'
- 'rht_for_each_rcu_from'
- '__rq_for_each_bio'
- 'rq_for_each_bvec'
- 'rq_for_each_segment'
- 'scsi_for_each_prot_sg'
- 'scsi_for_each_sg'
- 'sctp_for_each_hentry'
- 'sctp_skb_for_each'
- 'shdma_for_each_chan'
- '__shost_for_each_device'
- 'shost_for_each_device'
- 'sk_for_each'
- 'sk_for_each_bound'
- 'sk_for_each_entry_offset_rcu'
- 'sk_for_each_from'
- 'sk_for_each_rcu'
- 'sk_for_each_safe'
- 'sk_nulls_for_each'
- 'sk_nulls_for_each_from'
- 'sk_nulls_for_each_rcu'
- 'snd_array_for_each'
- 'snd_pcm_group_for_each_entry'
- 'snd_soc_dapm_widget_for_each_path'
- 'snd_soc_dapm_widget_for_each_path_safe'
- 'snd_soc_dapm_widget_for_each_sink_path'
- 'snd_soc_dapm_widget_for_each_source_path'
- 'tb_property_for_each'
- 'tcf_exts_for_each_action'
- 'udp_portaddr_for_each_entry'
- 'udp_portaddr_for_each_entry_rcu'
- 'usb_hub_for_each_child'
- 'v4l2_device_for_each_subdev'
- 'v4l2_m2m_for_each_dst_buf'
- 'v4l2_m2m_for_each_dst_buf_safe'
- 'v4l2_m2m_for_each_src_buf'
- 'v4l2_m2m_for_each_src_buf_safe'
- 'virtio_device_for_each_vq'
- 'while_for_each_ftrace_op'
- 'xa_for_each'
- 'xa_for_each_marked'
- 'xa_for_each_range'
- 'xa_for_each_start'
- 'xas_for_each'
- 'xas_for_each_conflict'
- 'xas_for_each_marked'
- 'xbc_array_for_each_value'
- 'xbc_for_each_key_value'
- 'xbc_node_for_each_array_value'
- 'xbc_node_for_each_child'
- 'xbc_node_for_each_key_value'
- 'zorro_for_each_dev'
#IncludeBlocks: Preserve # Unknown to clang-format-5.0
IncludeCategories:
- Regex: '.*'
Priority: 1
IncludeIsMainRegex: '(Test)?$'
IndentCaseLabels: false
#IndentPPDirectives: None # Unknown to clang-format-5.0
IndentWidth: 8
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
#ObjCBinPackProtocolList: Auto # Unknown to clang-format-5.0
ObjCBlockIndentWidth: 8
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: true
# Taken from git's rules
#PenaltyBreakAssignment: 10 # Unknown to clang-format-4.0
PenaltyBreakBeforeFirstCallParameter: 30
PenaltyBreakComment: 10
PenaltyBreakFirstLessLess: 0
PenaltyBreakString: 10
PenaltyExcessCharacter: 100
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
ReflowComments: false
SortIncludes: false
#SortUsingDeclarations: false # Unknown to clang-format-4.0
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
#SpaceBeforeCtorInitializerColon: true # Unknown to clang-format-5.0
#SpaceBeforeInheritanceColon: true # Unknown to clang-format-5.0
SpaceBeforeParens: ControlStatements
#SpaceBeforeRangeBasedForLoopColon: true # Unknown to clang-format-5.0
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: false
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp03
TabWidth: 8
UseTab: Always
...

7
.gdbinit Normal file
View File

@ -0,0 +1,7 @@
set confirm off
set architecture riscv:rv64
target remote 127.0.0.1:15234
symbol-file build/kernel
display/12i $pc-8
set riscv use-compressed-breakpoints yes
break *0x1000

22
.github/workflows/gitlab-mirror.yml vendored Normal file
View File

@ -0,0 +1,22 @@
name: Mirror and run GitLab CI
on:
push:
branches:
- 'ch[0-9]'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Mirror + trigger CI
uses: Gallium70/gitlab-mirror-and-ci-action@master
with:
args: "https://git.tsinghua.edu.cn/os-lab/2023s/public/ucore-tutorial-code-2023s"
env:
GITLAB_HOSTNAME: "git.tsinghua.edu.cn"
GITLAB_PROJECT_ID: "20789"
GITLAB_PROJECT_NAME: "ucore-tutorial-code-2023s"
GITLAB_PROJECT_TOKEN: ${{secrets.GITLAB_PROJECT_TOKEN}}
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}

12
.gitignore vendored Normal file
View File

@ -0,0 +1,12 @@
.DS_Store
.vscode
.idea
build
target
/user
link_app.S
kernel_app.ld
*.o
*.d
*.asm
*.sym

12
.gitlab-ci.yml Normal file
View File

@ -0,0 +1,12 @@
default:
image: duskmoon/dev-env:ucore-ci
stages:
- test
test-code-job:
stage: test
script:
- git clone https://token:${UCORE_CHECKER_REPO_READ_TOKEN_2023S}@git.tsinghua.edu.cn/os-lab/2023s/ta/ucore-tutorial-checker-2023s.git ucore-tutorial-ci
- git clone https://token:${UCORE_TEST_REPO_READ_TOKEN_2023S}@git.tsinghua.edu.cn/os-lab/2023s/public/ucore-tutorial-test-2023s.git ucore-tutorial-ci/workplace/user
- cd ucore-tutorial-ci && make test CHAPTER=`echo $CI_COMMIT_REF_NAME | grep -oP 'ch\K[0-9]'`

125
Makefile Normal file
View File

@ -0,0 +1,125 @@
.PHONY: clean build user
all: build_kernel
LOG ?= error
K = os
U = user
TOOLPREFIX = riscv64-unknown-elf-
CC = $(TOOLPREFIX)gcc
AS = $(TOOLPREFIX)gcc
LD = $(TOOLPREFIX)ld
OBJCOPY = $(TOOLPREFIX)objcopy
OBJDUMP = $(TOOLPREFIX)objdump
PY = python3
GDB = $(TOOLPREFIX)gdb
CP = cp
BUILDDIR = build
C_SRCS = $(wildcard $K/*.c)
AS_SRCS = $(wildcard $K/*.S)
C_OBJS = $(addprefix $(BUILDDIR)/, $(addsuffix .o, $(basename $(C_SRCS))))
AS_OBJS = $(addprefix $(BUILDDIR)/, $(addsuffix .o, $(basename $(AS_SRCS))))
OBJS = $(C_OBJS) $(AS_OBJS)
HEADER_DEP = $(addsuffix .d, $(basename $(C_OBJS)))
ifeq (,$(findstring link_app.o,$(OBJS)))
AS_OBJS += $(BUILDDIR)/$K/link_app.o
endif
-include $(HEADER_DEP)
CFLAGS = -Wall -Werror -O -fno-omit-frame-pointer -ggdb
CFLAGS += -MD
CFLAGS += -mcmodel=medany
CFLAGS += -ffreestanding -fno-common -nostdlib -mno-relax
CFLAGS += -I$K
CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector)
ifeq ($(LOG), error)
CFLAGS += -D LOG_LEVEL_ERROR
else ifeq ($(LOG), warn)
CFLAGS += -D LOG_LEVEL_WARN
else ifeq ($(LOG), info)
CFLAGS += -D LOG_LEVEL_INFO
else ifeq ($(LOG), debug)
CFLAGS += -D LOG_LEVEL_DEBUG
else ifeq ($(LOG), trace)
CFLAGS += -D LOG_LEVEL_TRACE
endif
# Disable PIE when possible (for Ubuntu 16.10 toolchain)
ifneq ($(shell $(CC) -dumpspecs 2>/dev/null | grep -e '[^f]no-pie'),)
CFLAGS += -fno-pie -no-pie
endif
ifneq ($(shell $(CC) -dumpspecs 2>/dev/null | grep -e '[^f]nopie'),)
CFLAGS += -fno-pie -nopie
endif
LDFLAGS = -z max-page-size=4096
$(AS_OBJS): $(BUILDDIR)/$K/%.o : $K/%.S
@mkdir -p $(@D)
$(CC) $(CFLAGS) -c $< -o $@
$(C_OBJS): $(BUILDDIR)/$K/%.o : $K/%.c $(BUILDDIR)/$K/%.d
@mkdir -p $(@D)
$(CC) $(CFLAGS) -c $< -o $@
$(HEADER_DEP): $(BUILDDIR)/$K/%.d : $K/%.c
@mkdir -p $(@D)
@set -e; rm -f $@; $(CC) -MM $< $(INCLUDEFLAGS) > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
os/link_app.o: $K/link_app.S
os/link_app.S: scripts/pack.py
@$(PY) scripts/pack.py
os/kernel_app.ld: scripts/kernelld.py
@$(PY) scripts/kernelld.py
build: build/kernel
build/kernel: $(OBJS) os/kernel_app.ld
$(LD) $(LDFLAGS) -T os/kernel_app.ld -o $(BUILDDIR)/kernel $(OBJS)
$(OBJDUMP) -S $(BUILDDIR)/kernel > $(BUILDDIR)/kernel.asm
$(OBJDUMP) -t $(BUILDDIR)/kernel | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > $(BUILDDIR)/kernel.sym
@echo 'Build kernel done'
clean:
rm -rf $(BUILDDIR) os/kernel_app.ld os/link_app.S
make -C $(U) clean
# BOARD
BOARD ?= qemu
SBI ?= rustsbi
BOOTLOADER := ./bootloader/rustsbi-qemu.bin
QEMU = qemu-system-riscv64
QEMUOPTS = \
-nographic \
-machine virt \
-bios $(BOOTLOADER) \
-kernel build/kernel \
run: build/kernel
$(QEMU) $(QEMUOPTS)
# QEMU's gdb stub command line changed in 0.11
QEMUGDB = $(shell if $(QEMU) -help | grep -q '^-gdb'; \
then echo "-gdb tcp::15234"; \
else echo "-s -p 15234"; fi)
debug: build/kernel .gdbinit
$(QEMU) $(QEMUOPTS) -S $(QEMUGDB) &
sleep 1
$(GDB)
CHAPTER ?= $(shell git rev-parse --abbrev-ref HEAD | grep -oP 'ch\K[0-9]')
user:
make -C $(U) CHAPTER=$(CHAPTER) BASE=$(BASE)
test: user run

View File

@ -9,3 +9,20 @@ Course project for THU-OS.
实验 lab1-lab5 基准代码分别位于 ch3-ch8 分支下。
注:为了兼容清华 Git 的需求、避免同学在主分支写代码、明确主分支的功能性,特意单独建了仅包含 README 与 LICENSE 的 master 分支,完成课程实验时请在 clone 仓库后先 push master 分支到清华 Git然后切到自己开发所需的分支进行后续操作。
## 本地开发测试
在本地开发并测试时,需要拉取 uCore-Tutorial-Test-2022A 到 `user` 文件夹。你可以根据网络情况和个人偏好选择下列一项执行:
```bash
# 清华 git 使用 https
git clone https://git.tsinghua.edu.cn/os-lab/public/ucore-tutorial-test-2022a.git user
# 清华 git 使用 ssh
git clone git@git.tsinghua.edu.cn:os-lab/public/ucore-tutorial-test-2022a.git user
# GitHub 使用 https
git clone https://github.com/LearningOS/uCore-Tutorial-Test-2022A.git user
# GitHub 使用 ssh
git clone git@github.com:LearningOS/uCore-Tutorial-Test-2022A.git user
```
注意:`user` 已添加至 `.gitignore`你无需将其提交ci 也不会使用它

BIN
bootloader/rustsbi-qemu.bin Normal file

Binary file not shown.

12
os/console.c Normal file
View File

@ -0,0 +1,12 @@
#include "console.h"
#include "sbi.h"
void consputc(int c)
{
console_putchar(c);
}
void console_init()
{
// DO NOTHING
}

7
os/console.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef CONSOLE_H
#define CONSOLE_H
void consputc(int);
void console_init();
#endif // CONSOLE_H

12
os/const.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef CONST_H
#define CONST_H
#define PAGE_SIZE (0x1000)
enum {
STDIN = 0,
STDOUT = 1,
STDERR = 2,
};
#endif // CONST_H

17
os/defs.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef DEFS_H
#define DEFS_H
#include "const.h"
#include "log.h"
#include "printf.h"
#include "riscv.h"
#include "sbi.h"
#include "string.h"
#include "types.h"
// number of elements in fixed-size array
#define NELEM(x) (sizeof(x) / sizeof((x)[0]))
#define MIN(a, b) (a < b ? a : b)
#define MAX(a, b) (a > b ? a : b)
#endif // DEF_H

12
os/entry.S Normal file
View File

@ -0,0 +1,12 @@
.section .text.entry
.globl _entry
_entry:
la sp, boot_stack_top
call main
.section .bss.stack
.globl boot_stack
boot_stack:
.space 4096 * 16
.globl boot_stack_top
boot_stack_top:

51
os/kernel.ld Normal file
View File

@ -0,0 +1,51 @@
OUTPUT_ARCH(riscv)
ENTRY(_entry)
BASE_ADDRESS = 0x80200000;
SECTIONS
{
. = BASE_ADDRESS;
skernel = .;
s_text = .;
.text : {
*(.text.entry)
*(.text .text.*)
. = ALIGN(0x1000);
*(trampsec)
. = ALIGN(0x1000);
}
. = ALIGN(4K);
e_text = .;
s_rodata = .;
.rodata : {
*(.rodata .rodata.*)
}
. = ALIGN(4K);
e_rodata = .;
s_data = .;
.data : {
*(.data.apps)
*(.data .data.*)
*(.sdata .sdata.*)
}
. = ALIGN(4K);
e_data = .;
.bss : {
*(.bss.stack)
s_bss = .;
*(.bss .bss.*)
*(.sbss .sbss.*)
}
. = ALIGN(4K);
e_bss = .;
ekernel = .;
/DISCARD/ : {
*(.eh_frame)
}
}

68
os/kernelld.py Normal file
View File

@ -0,0 +1,68 @@
import os
TARGET_DIR = "../user/target/"
if __name__ == '__main__':
f = open("kernel_app.ld", mode="w")
apps = os.listdir(TARGET_DIR)
f.write(
'''OUTPUT_ARCH(riscv)
ENTRY(_entry)
BASE_ADDRESS = 0x80200000;
SECTIONS
{
. = BASE_ADDRESS;
skernel = .;
s_text = .;
.text : {
*(.text.entry)
*(.text .text.*)
. = ALIGN(0x1000);
*(trampsec)
. = ALIGN(0x1000);
}
. = ALIGN(4K);
e_text = .;
s_rodata = .;
.rodata : {
*(.rodata .rodata.*)
}
. = ALIGN(4K);
e_rodata = .;
s_data = .;
.data : {
*(.data)
''')
for (idx, _) in enumerate(apps):
f.write(' . = ALIGN(0x1000);\n')
f.write(' *(.data.app{})\n'.format(idx))
f.write(
'''
*(.data.*)
*(.sdata .sdata.*)
}
. = ALIGN(4K);
e_data = .;
.bss : {
*(.bss.stack)
s_bss = .;
*(.bss .bss.*)
*(.sbss .sbss.*)
}
. = ALIGN(4K);
e_bss = .;
ekernel = .;
/DISCARD/ : {
*(.eh_frame)
}
}
''')
f.close()

46
os/loader.c Normal file
View File

@ -0,0 +1,46 @@
#include "loader.h"
#include "defs.h"
#include "trap.h"
static int app_cur, app_num;
static uint64 *app_info_ptr;
extern char _app_num[], userret[], boot_stack_top[], ekernel[];
void loader_init()
{
if ((uint64)ekernel >= BASE_ADDRESS) {
panic("kernel too large...\n");
}
app_info_ptr = (uint64 *)_app_num;
app_cur = -1;
app_num = *app_info_ptr;
}
__attribute__((aligned(4096))) char user_stack[USER_STACK_SIZE];
__attribute__((aligned(4096))) char trap_page[TRAP_PAGE_SIZE];
int load_app(uint64 *info)
{
uint64 start = info[0], end = info[1], length = end - start;
memset((void *)BASE_ADDRESS, 0, MAX_APP_SIZE);
memmove((void *)BASE_ADDRESS, (void *)start, length);
return length;
}
int run_next_app()
{
struct trapframe *trapframe = (struct trapframe *)trap_page;
app_cur++;
app_info_ptr++;
if (app_cur >= app_num) {
return -1;
}
infof("load and run app %d", app_cur);
uint64 length = load_app(app_info_ptr);
debugf("bin range = [%p, %p)", *app_info_ptr, *app_info_ptr + length);
memset(trapframe, 0, 4096);
trapframe->epc = BASE_ADDRESS;
trapframe->sp = (uint64)user_stack + USER_STACK_SIZE;
usertrapret(trapframe, (uint64)boot_stack_top);
return 0;
}

15
os/loader.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef BATCH_H
#define BATCH_H
#include "const.h"
#include "types.h"
void loader_init();
int run_next_app();
#define BASE_ADDRESS (0x80400000)
#define MAX_APP_SIZE (0x20000)
#define USER_STACK_SIZE PAGE_SIZE
#define TRAP_PAGE_SIZE PAGE_SIZE
#endif // BATCH_H

118
os/log.h Normal file
View File

@ -0,0 +1,118 @@
#ifndef LOG_H
#define LOG_H
extern void printf(char *, ...);
extern int threadid();
extern void dummy(int, ...);
#if defined(LOG_LEVEL_ERROR)
#define USE_LOG_ERROR
#endif // LOG_LEVEL_ERROR
#if defined(LOG_LEVEL_WARN)
#define USE_LOG_ERROR
#define USE_LOG_WARN
#endif // LOG_LEVEL_ERROR
#if defined(LOG_LEVEL_INFO)
#define USE_LOG_ERROR
#define USE_LOG_WARN
#define USE_LOG_INFO
#endif // LOG_LEVEL_INFO
#if defined(LOG_LEVEL_DEBUG)
#define USE_LOG_ERROR
#define USE_LOG_WARN
#define USE_LOG_INFO
#define USE_LOG_DEBUG
#endif // LOG_LEVEL_DEBUG
#if defined(LOG_LEVEL_TRACE)
#define USE_LOG_ERROR
#define USE_LOG_WARN
#define USE_LOG_INFO
#define USE_LOG_DEBUG
#define USE_LOG_TRACE
#endif // LOG_LEVEL_TRACE
enum LOG_COLOR {
RED = 31,
GREEN = 32,
BLUE = 34,
GRAY = 90,
YELLOW = 93,
};
#if defined(USE_LOG_ERROR)
#define errorf(fmt, ...) \
do { \
int tid = threadid(); \
printf("\x1b[%dm[%s %d]" fmt "\x1b[0m\n", RED, "ERROR", tid, \
##__VA_ARGS__); \
} while (0)
#else
#define errorf(fmt, ...) dummy(0, ##__VA_ARGS__)
#endif // USE_LOG_ERROR
#if defined(USE_LOG_WARN)
#define warnf(fmt, ...) \
do { \
int tid = threadid(); \
printf("\x1b[%dm[%s %d]" fmt "\x1b[0m\n", YELLOW, "WARN", tid, \
##__VA_ARGS__); \
} while (0)
#else
#define warnf(fmt, ...) dummy(0, ##__VA_ARGS__)
#endif // USE_LOG_WARN
#if defined(USE_LOG_INFO)
#define infof(fmt, ...) \
do { \
int tid = threadid(); \
printf("\x1b[%dm[%s %d]" fmt "\x1b[0m\n", BLUE, "INFO", tid, \
##__VA_ARGS__); \
} while (0)
#else
#define infof(fmt, ...) dummy(0, ##__VA_ARGS__)
#endif // USE_LOG_INFO
#if defined(USE_LOG_DEBUG)
#define debugf(fmt, ...) \
do { \
int tid = threadid(); \
printf("\x1b[%dm[%s %d]" fmt "\x1b[0m\n", GREEN, "DEBUG", tid, \
##__VA_ARGS__); \
} while (0)
#else
#define debugf(fmt, ...) dummy(0, ##__VA_ARGS__)
#endif // USE_LOG_DEBUG
#if defined(USE_LOG_TRACE)
#define tracef(fmt, ...) \
do { \
int tid = threadid(); \
printf("\x1b[%dm[%s %d]" fmt "\x1b[0m\n", GRAY, "TRACE", tid, \
##__VA_ARGS__); \
} while (0)
#else
#define tracef(fmt, ...) dummy(0, ##__VA_ARGS__)
#endif // USE_LOG_TRACE
#define panic(fmt, ...) \
do { \
int tid = threadid(); \
printf("\x1b[%dm[%s %d] %s:%d: " fmt "\x1b[0m\n", RED, \
"PANIC", tid, __FILE__, __LINE__, ##__VA_ARGS__); \
} while (0)
#endif //! LOG_H

25
os/main.c Normal file
View File

@ -0,0 +1,25 @@
#include "console.h"
#include "defs.h"
#include "loader.h"
#include "trap.h"
int threadid()
{
return 0;
}
void clean_bss()
{
extern char s_bss[];
extern char e_bss[];
memset(s_bss, 0, e_bss - s_bss);
}
void main()
{
clean_bss();
printf("hello wrold!\n");
trap_init();
loader_init();
run_next_app();
}

42
os/pack.py Normal file
View File

@ -0,0 +1,42 @@
import os
TARGET_DIR = "../user/target"
if __name__ == '__main__':
f = open("link_app.S", mode="w")
apps = os.listdir(TARGET_DIR)
apps.sort()
f.write(
''' .align 4
.section .data
.global _app_num
_app_num:
.quad {}
'''.format(len(apps))
)
for (idx, _) in enumerate(apps):
f.write(' .quad app_{}_start\n'.format(idx))
f.write(' .quad app_{}_end\n'.format(len(apps) - 1))
f.write(
'''
.global _app_names
_app_names:
''');
for app in apps:
app = app[:app.find('.')]
f.write(" .string \"" + app + "\"\n")
for (idx, app) in enumerate(apps):
f.write(
'''
.section .data.app{0}
.global app_{0}_start
app_{0}_start:
.incbin "{1}"
'''.format(idx, TARGET_DIR + app)
)
f.write('app_{}_end:\n\n'.format(len(apps) - 1))
f.close()

83
os/printf.c Normal file
View File

@ -0,0 +1,83 @@
#include <stdarg.h>
#include "console.h"
#include "defs.h"
static char digits[] = "0123456789abcdef";
static void printint(int xx, int base, int sign)
{
char buf[16];
int i;
uint x;
if (sign && (sign = xx < 0))
x = -xx;
else
x = xx;
i = 0;
do {
buf[i++] = digits[x % base];
} while ((x /= base) != 0);
if (sign)
buf[i++] = '-';
while (--i >= 0)
consputc(buf[i]);
}
static void printptr(uint64 x)
{
int i;
consputc('0');
consputc('x');
for (i = 0; i < (sizeof(uint64) * 2); i++, x <<= 4)
consputc(digits[x >> (sizeof(uint64) * 8 - 4)]);
}
// Print to the console. only understands %d, %x, %p, %s.
void printf(char *fmt, ...)
{
va_list ap;
int i, c;
char *s;
if (fmt == 0)
panic("null fmt");
va_start(ap, fmt);
for (i = 0; (c = fmt[i] & 0xff) != 0; i++) {
if (c != '%') {
consputc(c);
continue;
}
c = fmt[++i] & 0xff;
if (c == 0)
break;
switch (c) {
case 'd':
printint(va_arg(ap, int), 10, 1);
break;
case 'x':
printint(va_arg(ap, int), 16, 1);
break;
case 'p':
printptr(va_arg(ap, uint64));
break;
case 's':
if ((s = va_arg(ap, char *)) == 0)
s = "(null)";
for (; *s; s++)
consputc(*s);
break;
case '%':
consputc('%');
break;
default:
// Print unknown % sequence to draw attention.
consputc('%');
consputc(c);
break;
}
}
}

6
os/printf.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef PRINTF_H
#define PRINTF_H
void printf(char *, ...);
#endif // PRINTF_H

322
os/riscv.h Normal file
View File

@ -0,0 +1,322 @@
#ifndef RISCV_H
#define RISCV_H
#include "types.h"
// which hart (core) is this?
static inline uint64 r_mhartid()
{
uint64 x;
asm volatile("csrr %0, mhartid" : "=r"(x));
return x;
}
// Machine Status Register, mstatus
#define MSTATUS_MPP_MASK (3L << 11) // previous mode.
#define MSTATUS_MPP_M (3L << 11)
#define MSTATUS_MPP_S (1L << 11)
#define MSTATUS_MPP_U (0L << 11)
#define MSTATUS_MIE (1L << 3) // machine-mode interrupt enable.
static inline uint64 r_mstatus()
{
uint64 x;
asm volatile("csrr %0, mstatus" : "=r"(x));
return x;
}
static inline void w_mstatus(uint64 x)
{
asm volatile("csrw mstatus, %0" : : "r"(x));
}
// machine exception program counter, holds the
// instruction address to which a return from
// exception will go.
static inline void w_mepc(uint64 x)
{
asm volatile("csrw mepc, %0" : : "r"(x));
}
// Supervisor Status Register, sstatus
#define SSTATUS_SPP (1L << 8) // Previous mode, 1=Supervisor, 0=User
#define SSTATUS_SPIE (1L << 5) // Supervisor Previous Interrupt Enable
#define SSTATUS_UPIE (1L << 4) // User Previous Interrupt Enable
#define SSTATUS_SIE (1L << 1) // Supervisor Interrupt Enable
#define SSTATUS_UIE (1L << 0) // User Interrupt Enable
static inline uint64 r_sstatus()
{
uint64 x;
asm volatile("csrr %0, sstatus" : "=r"(x));
return x;
}
static inline void w_sstatus(uint64 x)
{
asm volatile("csrw sstatus, %0" : : "r"(x));
}
// Supervisor Interrupt Pending
static inline uint64 r_sip()
{
uint64 x;
asm volatile("csrr %0, sip" : "=r"(x));
return x;
}
static inline void w_sip(uint64 x)
{
asm volatile("csrw sip, %0" : : "r"(x));
}
// Supervisor Interrupt Enable
#define SIE_SEIE (1L << 9) // external
#define SIE_STIE (1L << 5) // timer
#define SIE_SSIE (1L << 1) // software
static inline uint64 r_sie()
{
uint64 x;
asm volatile("csrr %0, sie" : "=r"(x));
return x;
}
static inline void w_sie(uint64 x)
{
asm volatile("csrw sie, %0" : : "r"(x));
}
// Machine-mode Interrupt Enable
#define MIE_MEIE (1L << 11) // external
#define MIE_MTIE (1L << 7) // timer
#define MIE_MSIE (1L << 3) // software
static inline uint64 r_mie()
{
uint64 x;
asm volatile("csrr %0, mie" : "=r"(x));
return x;
}
static inline void w_mie(uint64 x)
{
asm volatile("csrw mie, %0" : : "r"(x));
}
// machine exception program counter, holds the
// instruction address to which a return from
// exception will go.
static inline void w_sepc(uint64 x)
{
asm volatile("csrw sepc, %0" : : "r"(x));
}
static inline uint64 r_sepc()
{
uint64 x;
asm volatile("csrr %0, sepc" : "=r"(x));
return x;
}
// Machine Exception Delegation
static inline uint64 r_medeleg()
{
uint64 x;
asm volatile("csrr %0, medeleg" : "=r"(x));
return x;
}
static inline void w_medeleg(uint64 x)
{
asm volatile("csrw medeleg, %0" : : "r"(x));
}
// Machine Interrupt Delegation
static inline uint64 r_mideleg()
{
uint64 x;
asm volatile("csrr %0, mideleg" : "=r"(x));
return x;
}
static inline void w_mideleg(uint64 x)
{
asm volatile("csrw mideleg, %0" : : "r"(x));
}
// Supervisor Trap-Vector Base Address
// low two bits are mode.
static inline void w_stvec(uint64 x)
{
asm volatile("csrw stvec, %0" : : "r"(x));
}
static inline uint64 r_stvec()
{
uint64 x;
asm volatile("csrr %0, stvec" : "=r"(x));
return x;
}
// Machine-mode interrupt vector
static inline void w_mtvec(uint64 x)
{
asm volatile("csrw mtvec, %0" : : "r"(x));
}
// use riscv's sv39 page table scheme.
#define SATP_SV39 (8L << 60)
#define MAKE_SATP(pagetable) (SATP_SV39 | (((uint64)pagetable) >> 12))
// supervisor address translation and protection;
// holds the address of the page table.
static inline void w_satp(uint64 x)
{
asm volatile("csrw satp, %0" : : "r"(x));
}
static inline uint64 r_satp()
{
uint64 x;
asm volatile("csrr %0, satp" : "=r"(x));
return x;
}
// Supervisor Scratch register, for early trap handler in trampoline.S.
static inline void w_sscratch(uint64 x)
{
asm volatile("csrw sscratch, %0" : : "r"(x));
}
static inline void w_mscratch(uint64 x)
{
asm volatile("csrw mscratch, %0" : : "r"(x));
}
// Supervisor Trap Cause
static inline uint64 r_scause()
{
uint64 x;
asm volatile("csrr %0, scause" : "=r"(x));
return x;
}
// Supervisor Trap Value
static inline uint64 r_stval()
{
uint64 x;
asm volatile("csrr %0, stval" : "=r"(x));
return x;
}
// Machine-mode Counter-Enable
static inline void w_mcounteren(uint64 x)
{
asm volatile("csrw mcounteren, %0" : : "r"(x));
}
static inline uint64 r_mcounteren()
{
uint64 x;
asm volatile("csrr %0, mcounteren" : "=r"(x));
return x;
}
// machine-mode cycle counter
static inline uint64 r_time()
{
uint64 x;
asm volatile("csrr %0, time" : "=r"(x));
return x;
}
// enable device interrupts
static inline void intr_on()
{
w_sstatus(r_sstatus() | SSTATUS_SIE);
}
// disable device interrupts
static inline void intr_off()
{
w_sstatus(r_sstatus() & ~SSTATUS_SIE);
}
// are device interrupts enabled?
static inline int intr_get()
{
uint64 x = r_sstatus();
return (x & SSTATUS_SIE) != 0;
}
static inline uint64 r_sp()
{
uint64 x;
asm volatile("mv %0, sp" : "=r"(x));
return x;
}
// read and write tp, the thread pointer, which holds
// this core's hartid (core number), the index into cpus[].
static inline uint64 r_tp()
{
uint64 x;
asm volatile("mv %0, tp" : "=r"(x));
return x;
}
static inline void w_tp(uint64 x)
{
asm volatile("mv tp, %0" : : "r"(x));
}
static inline uint64 r_ra()
{
uint64 x;
asm volatile("mv %0, ra" : "=r"(x));
return x;
}
// flush the TLB.
static inline void sfence_vma()
{
// the zero, zero means flush all TLB entries.
asm volatile("sfence.vma zero, zero");
}
#define PGSIZE 4096 // bytes per page
#define PGSHIFT 12 // bits of offset within a page
#define PGROUNDUP(sz) (((sz) + PGSIZE - 1) & ~(PGSIZE - 1))
#define PGROUNDDOWN(a) (((a)) & ~(PGSIZE - 1))
#define PTE_V (1L << 0) // valid
#define PTE_R (1L << 1)
#define PTE_W (1L << 2)
#define PTE_X (1L << 3)
#define PTE_U (1L << 4) // 1 -> user can access
// shift a physical address to the right place for a PTE.
#define PA2PTE(pa) ((((uint64)pa) >> 12) << 10)
#define PTE2PA(pte) (((pte) >> 10) << 12)
#define PTE_FLAGS(pte) ((pte)&0x3FF)
// extract the three 9-bit page table indices from a virtual address.
#define PXMASK 0x1FF // 9 bits
#define PXSHIFT(level) (PGSHIFT + (9 * (level)))
#define PX(level, va) ((((uint64)(va)) >> PXSHIFT(level)) & PXMASK)
// one beyond the highest possible virtual address.
// MAXVA is actually one bit less than the max allowed by
// Sv39, to avoid having to sign-extend virtual addresses
// that have the high bit set.
#define MAXVA (1L << (9 + 9 + 9 + 12 - 1))
typedef uint64 pte_t;
typedef uint64 *pagetable_t; // 512 PTEs
#endif // RISCV_H

39
os/sbi.c Normal file
View File

@ -0,0 +1,39 @@
#include "sbi.h"
#include "types.h"
const uint64 SBI_SET_TIMER = 0;
const uint64 SBI_CONSOLE_PUTCHAR = 1;
const uint64 SBI_CONSOLE_GETCHAR = 2;
const uint64 SBI_CLEAR_IPI = 3;
const uint64 SBI_SEND_IPI = 4;
const uint64 SBI_REMOTE_FENCE_I = 5;
const uint64 SBI_REMOTE_SFENCE_VMA = 6;
const uint64 SBI_REMOTE_SFENCE_VMA_ASID = 7;
const uint64 SBI_SHUTDOWN = 8;
int inline sbi_call(uint64 which, uint64 arg0, uint64 arg1, uint64 arg2)
{
register uint64 a0 asm("a0") = arg0;
register uint64 a1 asm("a1") = arg1;
register uint64 a2 asm("a2") = arg2;
register uint64 a7 asm("a7") = which;
asm volatile("ecall"
: "=r"(a0)
: "r"(a0), "r"(a1), "r"(a2), "r"(a7)
: "memory");
return a0;
}
void console_putchar(int c)
{
sbi_call(SBI_CONSOLE_PUTCHAR, c, 0, 0);
}
int console_getchar()
{
return sbi_call(SBI_CONSOLE_GETCHAR, 0, 0, 0);
}
void shutdown()
{
sbi_call(SBI_SHUTDOWN, 0, 0, 0);
}

8
os/sbi.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef SBI_H
#define SBI_H
void console_putchar(int);
int console_getchar();
void shutdown();
#endif // SBI_H

100
os/string.c Normal file
View File

@ -0,0 +1,100 @@
#include "string.h"
#include "types.h"
void *memset(void *dst, int c, uint n)
{
char *cdst = (char *)dst;
int i;
for (i = 0; i < n; i++) {
cdst[i] = c;
}
return dst;
}
int memcmp(const void *v1, const void *v2, uint n)
{
const uchar *s1, *s2;
s1 = v1;
s2 = v2;
while (n-- > 0) {
if (*s1 != *s2)
return *s1 - *s2;
s1++, s2++;
}
return 0;
}
void *memmove(void *dst, const void *src, uint n)
{
const char *s;
char *d;
s = src;
d = dst;
if (s < d && s + n > d) {
s += n;
d += n;
while (n-- > 0)
*--d = *--s;
} else
while (n-- > 0)
*d++ = *s++;
return dst;
}
// memcpy exists to placate GCC. Use memmove.
void *memcpy(void *dst, const void *src, uint n)
{
return memmove(dst, src, n);
}
int strncmp(const char *p, const char *q, uint n)
{
while (n > 0 && *p && *p == *q)
n--, p++, q++;
if (n == 0)
return 0;
return (uchar)*p - (uchar)*q;
}
char *strncpy(char *s, const char *t, int n)
{
char *os;
os = s;
while (n-- > 0 && (*s++ = *t++) != 0)
;
while (n-- > 0)
*s++ = 0;
return os;
}
// Like strncpy but guaranteed to NUL-terminate.
char *safestrcpy(char *s, const char *t, int n)
{
char *os;
os = s;
if (n <= 0)
return os;
while (--n > 0 && (*s++ = *t++) != 0)
;
*s = 0;
return os;
}
int strlen(const char *s)
{
int n;
for (n = 0; s[n]; n++)
;
return n;
}
void dummy(int _, ...)
{
}

14
os/string.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef STRING_H
#define STRING_H
#include "types.h"
int memcmp(const void *, const void *, uint);
void *memmove(void *, const void *, uint);
void *memset(void *, int, uint);
char *safestrcpy(char *, const char *, int);
int strlen(const char *);
int strncmp(const char *, const char *, uint);
char *strncpy(char *, const char *, int);
#endif // STRING_H

50
os/syscall.c Normal file
View File

@ -0,0 +1,50 @@
#include "syscall.h"
#include "defs.h"
#include "loader.h"
#include "syscall_ids.h"
#include "trap.h"
uint64 sys_write(int fd, char *str, uint len)
{
debugf("sys_write fd = %d str = %x, len = %d", fd, str, len);
if (fd != STDOUT)
return -1;
for (int i = 0; i < len; ++i) {
console_putchar(str[i]);
}
return len;
}
__attribute__((noreturn)) void sys_exit(int code)
{
debugf("sysexit(%d)", code);
run_next_app();
printf("ALL DONE\n");
shutdown();
__builtin_unreachable();
}
extern char trap_page[];
void syscall()
{
struct trapframe *trapframe = (struct trapframe *)trap_page;
int id = trapframe->a7, ret;
uint64 args[6] = { trapframe->a0, trapframe->a1, trapframe->a2,
trapframe->a3, trapframe->a4, trapframe->a5 };
tracef("syscall %d args = [%x, %x, %x, %x, %x, %x]", id, args[0],
args[1], args[2], args[3], args[4], args[5]);
switch (id) {
case SYS_write:
ret = sys_write(args[0], (char *)args[1], args[2]);
break;
case SYS_exit:
sys_exit(args[0]);
// __builtin_unreachable();
default:
ret = -1;
errorf("unknown syscall %d", id);
}
trapframe->a0 = ret;
tracef("syscall ret %d", ret);
}

6
os/syscall.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef SYSCALL_H
#define SYSCALL_H
void syscall();
#endif // SYSCALL_H

295
os/syscall_ids.h Normal file
View File

@ -0,0 +1,295 @@
#define SYS_io_setup 0
#define SYS_io_destroy 1
#define SYS_io_submit 2
#define SYS_io_cancel 3
#define SYS_io_getevents 4
#define SYS_setxattr 5
#define SYS_lsetxattr 6
#define SYS_fsetxattr 7
#define SYS_getxattr 8
#define SYS_lgetxattr 9
#define SYS_fgetxattr 10
#define SYS_listxattr 11
#define SYS_llistxattr 12
#define SYS_flistxattr 13
#define SYS_removexattr 14
#define SYS_lremovexattr 15
#define SYS_fremovexattr 16
#define SYS_getcwd 17
#define SYS_lookup_dcookie 18
#define SYS_eventfd2 19
#define SYS_epoll_create1 20
#define SYS_epoll_ctl 21
#define SYS_epoll_pwait 22
#define SYS_dup 23
#define SYS_dup3 24
#define SYS_fcntl 25
#define SYS_inotify_init1 26
#define SYS_inotify_add_watch 27
#define SYS_inotify_rm_watch 28
#define SYS_ioctl 29
#define SYS_ioprio_set 30
#define SYS_ioprio_get 31
#define SYS_flock 32
#define SYS_mknodat 33
#define SYS_mkdirat 34
#define SYS_unlinkat 35
#define SYS_symlinkat 36
#define SYS_linkat 37
#define SYS_umount2 39
#define SYS_mount 40
#define SYS_pivot_root 41
#define SYS_nfsservctl 42
#define SYS_statfs 43
#define SYS_fstatfs 44
#define SYS_truncate 45
#define SYS_ftruncate 46
#define SYS_fallocate 47
#define SYS_faccessat 48
#define SYS_chdir 49
#define SYS_fchdir 50
#define SYS_chroot 51
#define SYS_fchmod 52
#define SYS_fchmodat 53
#define SYS_fchownat 54
#define SYS_fchown 55
#define SYS_openat 56
#define SYS_close 57
#define SYS_vhangup 58
#define SYS_pipe2 59
#define SYS_quotactl 60
#define SYS_getdents64 61
#define SYS_lseek 62
#define SYS_read 63
#define SYS_write 64
#define SYS_readv 65
#define SYS_writev 66
#define SYS_pread64 67
#define SYS_pwrite64 68
#define SYS_preadv 69
#define SYS_pwritev 70
#define SYS_sendfile 71
#define SYS_pselect6 72
#define SYS_ppoll 73
#define SYS_signalfd4 74
#define SYS_vmsplice 75
#define SYS_splice 76
#define SYS_tee 77
#define SYS_readlinkat 78
#define SYS_fstatat 79
#define SYS_fstat 80
#define SYS_sync 81
#define SYS_fsync 82
#define SYS_fdatasync 83
#define SYS_sync_file_range 84
#define SYS_timerfd_create 85
#define SYS_timerfd_settime 86
#define SYS_timerfd_gettime 87
#define SYS_utimensat 88
#define SYS_acct 89
#define SYS_capget 90
#define SYS_capset 91
#define SYS_personality 92
#define SYS_exit 93
#define SYS_exit_group 94
#define SYS_waitid 95
#define SYS_set_tid_address 96
#define SYS_unshare 97
#define SYS_futex 98
#define SYS_set_robust_list 99
#define SYS_get_robust_list 100
#define SYS_nanosleep 101
#define SYS_getitimer 102
#define SYS_setitimer 103
#define SYS_kexec_load 104
#define SYS_init_module 105
#define SYS_delete_module 106
#define SYS_timer_create 107
#define SYS_timer_gettime 108
#define SYS_timer_getoverrun 109
#define SYS_timer_settime 110
#define SYS_timer_delete 111
#define SYS_clock_settime 112
#define SYS_clock_gettime 113
#define SYS_clock_getres 114
#define SYS_clock_nanosleep 115
#define SYS_syslog 116
#define SYS_ptrace 117
#define SYS_sched_setparam 118
#define SYS_sched_setscheduler 119
#define SYS_sched_getscheduler 120
#define SYS_sched_getparam 121
#define SYS_sched_setaffinity 122
#define SYS_sched_getaffinity 123
#define SYS_sched_yield 124
#define SYS_sched_get_priority_max 125
#define SYS_sched_get_priority_min 126
#define SYS_sched_rr_get_interval 127
#define SYS_restart_syscall 128
#define SYS_kill 129
#define SYS_tkill 130
#define SYS_tgkill 131
#define SYS_sigaltstack 132
#define SYS_rt_sigsuspend 133
#define SYS_rt_sigaction 134
#define SYS_rt_sigprocmask 135
#define SYS_rt_sigpending 136
#define SYS_rt_sigtimedwait 137
#define SYS_rt_sigqueueinfo 138
#define SYS_rt_sigreturn 139
#define SYS_setpriority 140
#define SYS_getpriority 141
#define SYS_reboot 142
#define SYS_setregid 143
#define SYS_setgid 144
#define SYS_setreuid 145
#define SYS_setuid 146
#define SYS_setresuid 147
#define SYS_getresuid 148
#define SYS_setresgid 149
#define SYS_getresgid 150
#define SYS_setfsuid 151
#define SYS_setfsgid 152
#define SYS_times 153
#define SYS_setpgid 154
#define SYS_getpgid 155
#define SYS_getsid 156
#define SYS_setsid 157
#define SYS_getgroups 158
#define SYS_setgroups 159
#define SYS_uname 160
#define SYS_sethostname 161
#define SYS_setdomainname 162
#define SYS_getrlimit 163
#define SYS_setrlimit 164
#define SYS_getrusage 165
#define SYS_umask 166
#define SYS_prctl 167
#define SYS_getcpu 168
#define SYS_gettimeofday 169
#define SYS_settimeofday 170
#define SYS_adjtimex 171
#define SYS_getpid 172
#define SYS_getppid 173
#define SYS_getuid 174
#define SYS_geteuid 175
#define SYS_getgid 176
#define SYS_getegid 177
#define SYS_gettid 178
#define SYS_sysinfo 179
#define SYS_mq_open 180
#define SYS_mq_unlink 181
#define SYS_mq_timedsend 182
#define SYS_mq_timedreceive 183
#define SYS_mq_notify 184
#define SYS_mq_getsetattr 185
#define SYS_msgget 186
#define SYS_msgctl 187
#define SYS_msgrcv 188
#define SYS_msgsnd 189
#define SYS_semget 190
#define SYS_semctl 191
#define SYS_semtimedop 192
#define SYS_semop 193
#define SYS_shmget 194
#define SYS_shmctl 195
#define SYS_shmat 196
#define SYS_shmdt 197
#define SYS_socket 198
#define SYS_socketpair 199
#define SYS_bind 200
#define SYS_listen 201
#define SYS_accept 202
#define SYS_connect 203
#define SYS_getsockname 204
#define SYS_getpeername 205
#define SYS_sendto 206
#define SYS_recvfrom 207
#define SYS_setsockopt 208
#define SYS_getsockopt 209
#define SYS_shutdown 210
#define SYS_sendmsg 211
#define SYS_recvmsg 212
#define SYS_readahead 213
#define SYS_brk 214
#define SYS_munmap 215
#define SYS_mremap 216
#define SYS_add_key 217
#define SYS_request_key 218
#define SYS_keyctl 219
#define SYS_clone 220
#define SYS_execve 221
#define SYS_mmap 222
#define SYS_fadvise64 223
#define SYS_swapon 224
#define SYS_swapoff 225
#define SYS_mprotect 226
#define SYS_msync 227
#define SYS_mlock 228
#define SYS_munlock 229
#define SYS_mlockall 230
#define SYS_munlockall 231
#define SYS_mincore 232
#define SYS_madvise 233
#define SYS_remap_file_pages 234
#define SYS_mbind 235
#define SYS_get_mempolicy 236
#define SYS_set_mempolicy 237
#define SYS_migrate_pages 238
#define SYS_move_pages 239
#define SYS_rt_tgsigqueueinfo 240
#define SYS_perf_event_open 241
#define SYS_accept4 242
#define SYS_recvmmsg 243
#define SYS_arch_specific_syscall 244
#define SYS_wait4 260
#define SYS_prlimit64 261
#define SYS_fanotify_init 262
#define SYS_fanotify_mark 263
#define SYS_name_to_handle_at 264
#define SYS_open_by_handle_at 265
#define SYS_clock_adjtime 266
#define SYS_syncfs 267
#define SYS_setns 268
#define SYS_sendmmsg 269
#define SYS_process_vm_readv 270
#define SYS_process_vm_writev 271
#define SYS_kcmp 272
#define SYS_finit_module 273
#define SYS_sched_setattr 274
#define SYS_sched_getattr 275
#define SYS_renameat2 276
#define SYS_seccomp 277
#define SYS_getrandom 278
#define SYS_memfd_create 279
#define SYS_bpf 280
#define SYS_execveat 281
#define SYS_userfaultfd 282
#define SYS_membarrier 283
#define SYS_mlock2 284
#define SYS_copy_file_range 285
#define SYS_preadv2 286
#define SYS_pwritev2 287
#define SYS_pkey_mprotect 288
#define SYS_pkey_alloc 289
#define SYS_pkey_free 290
#define SYS_statx 291
#define SYS_io_pgetevents 292
#define SYS_rseq 293
#define SYS_kexec_file_load 294
#define SYS_pidfd_send_signal 424
#define SYS_io_uring_setup 425
#define SYS_io_uring_enter 426
#define SYS_io_uring_register 427
#define SYS_open_tree 428
#define SYS_move_mount 429
#define SYS_fsopen 430
#define SYS_fsconfig 431
#define SYS_fsmount 432
#define SYS_fspick 433
#define SYS_pidfd_open 434
#define SYS_clone3 435
#define SYS_openat2 437
#define SYS_pidfd_getfd 438
#define SYS_faccessat2 439
#define SYS_riscv_flush_icache 244 + 15

132
os/trampoline.S Normal file
View File

@ -0,0 +1,132 @@
#
# code to switch between user and kernel space.
#
# this code is mapped at the same virtual address
# (TRAMPOLINE) in user and kernel space so that
# it continues to work when it switches page tables.
#
# kernel.ld causes this to be aligned
# to a page boundary.
#
.section .text
.globl trampoline
trampoline:
.align 4
.globl uservec
uservec:
#
# trap.c sets stvec to point here, so
# traps from user space start here,
# in supervisor mode, but with a
# user page table.
#
# sscratch points to where the process's p->trapframe is
# mapped into user space, at TRAPFRAME.
#
# swap a0 and sscratch
# so that a0 is TRAPFRAME
csrrw a0, sscratch, a0
# save the user registers in TRAPFRAME
sd ra, 40(a0)
sd sp, 48(a0)
sd gp, 56(a0)
sd tp, 64(a0)
sd t0, 72(a0)
sd t1, 80(a0)
sd t2, 88(a0)
sd s0, 96(a0)
sd s1, 104(a0)
sd a1, 120(a0)
sd a2, 128(a0)
sd a3, 136(a0)
sd a4, 144(a0)
sd a5, 152(a0)
sd a6, 160(a0)
sd a7, 168(a0)
sd s2, 176(a0)
sd s3, 184(a0)
sd s4, 192(a0)
sd s5, 200(a0)
sd s6, 208(a0)
sd s7, 216(a0)
sd s8, 224(a0)
sd s9, 232(a0)
sd s10, 240(a0)
sd s11, 248(a0)
sd t3, 256(a0)
sd t4, 264(a0)
sd t5, 272(a0)
sd t6, 280(a0)
# save the user a0 in p->trapframe->a0
csrr t0, sscratch
sd t0, 112(a0)
csrr t1, sepc
sd t1, 24(a0)
ld sp, 8(a0)
ld tp, 32(a0)
ld t1, 0(a0)
# csrw satp, t1
# sfence.vma zero, zero
ld t0, 16(a0)
jr t0
.globl userret
userret:
# userret(TRAPFRAME, pagetable)
# switch from kernel to user.
# usertrapret() calls here.
# a0: TRAPFRAME, in user page table.
# a1: user page table, for satp.
# switch to the user page table.
# csrw satp, a1
# sfence.vma zero, zero
# put the saved user a0 in sscratch, so we
# can swap it with our a0 (TRAPFRAME) in the last step.
ld t0, 112(a0)
csrw sscratch, t0
# restore all but a0 from TRAPFRAME
ld ra, 40(a0)
ld sp, 48(a0)
ld gp, 56(a0)
ld tp, 64(a0)
ld t0, 72(a0)
ld t1, 80(a0)
ld t2, 88(a0)
ld s0, 96(a0)
ld s1, 104(a0)
ld a1, 120(a0)
ld a2, 128(a0)
ld a3, 136(a0)
ld a4, 144(a0)
ld a5, 152(a0)
ld a6, 160(a0)
ld a7, 168(a0)
ld s2, 176(a0)
ld s3, 184(a0)
ld s4, 192(a0)
ld s5, 200(a0)
ld s6, 208(a0)
ld s7, 216(a0)
ld s8, 224(a0)
ld s9, 232(a0)
ld s10, 240(a0)
ld s11, 248(a0)
ld t3, 256(a0)
ld t4, 264(a0)
ld t5, 272(a0)
ld t6, 280(a0)
# restore user a0, and save TRAPFRAME in sscratch
csrrw a0, sscratch, a0
# return to user mode and user pc.
# usertrapret() set up sstatus and sepc.
sret

79
os/trap.c Normal file
View File

@ -0,0 +1,79 @@
#include "trap.h"
#include "defs.h"
#include "loader.h"
#include "syscall.h"
extern char trampoline[], uservec[], boot_stack_top[];
extern void *userret(uint64);
// set up to take exceptions and traps while in the kernel.
void trap_init(void)
{
w_stvec((uint64)uservec & ~0x3);
}
//
// handle an interrupt, exception, or system call from user space.
// called from trampoline.S
//
void usertrap(struct trapframe *trapframe)
{
if ((r_sstatus() & SSTATUS_SPP) != 0)
panic("usertrap: not from user mode");
uint64 cause = r_scause();
if (cause == UserEnvCall) {
trapframe->epc += 4;
syscall();
return usertrapret(trapframe, (uint64)boot_stack_top);
}
switch (cause) {
case StoreMisaligned:
case StorePageFault:
case LoadMisaligned:
case LoadPageFault:
case InstructionMisaligned:
case InstructionPageFault:
errorf("%d in application, bad addr = %p, bad instruction = %p, core "
"dumped.",
cause, r_stval(), trapframe->epc);
break;
case IllegalInstruction:
errorf("IllegalInstruction in application, epc = %p, core dumped.",
trapframe->epc);
break;
default:
errorf("unknown trap: %p, stval = %p sepc = %p", r_scause(),
r_stval(), r_sepc());
break;
}
infof("switch to next app");
run_next_app();
printf("ALL DONE\n");
shutdown();
}
//
// return to user space
//
void usertrapret(struct trapframe *trapframe, uint64 kstack)
{
trapframe->kernel_satp = r_satp(); // kernel page table
trapframe->kernel_sp = kstack + PGSIZE; // process's kernel stack
trapframe->kernel_trap = (uint64)usertrap;
trapframe->kernel_hartid = r_tp(); // hartid for cpuid()
w_sepc(trapframe->epc);
// set up the registers that trampoline.S's sret will use
// to get to user space.
// set S Previous Privilege mode to User.
uint64 x = r_sstatus();
x &= ~SSTATUS_SPP; // clear SPP to 0 for user mode
x |= SSTATUS_SPIE; // enable interrupts in user mode
w_sstatus(x);
// tell trampoline.S the user page table to switch to.
// uint64 satp = MAKE_SATP(p->pagetable);
userret((uint64)trapframe);
}

74
os/trap.h Normal file
View File

@ -0,0 +1,74 @@
#ifndef TRAP_H
#define TRAP_H
#include "types.h"
struct trapframe {
/* 0 */ uint64 kernel_satp; // kernel page table
/* 8 */ uint64 kernel_sp; // top of process's kernel stack
/* 16 */ uint64 kernel_trap; // usertrap()
/* 24 */ uint64 epc; // saved user program counter
/* 32 */ uint64 kernel_hartid; // saved kernel tp
/* 40 */ uint64 ra;
/* 48 */ uint64 sp;
/* 56 */ uint64 gp;
/* 64 */ uint64 tp;
/* 72 */ uint64 t0;
/* 80 */ uint64 t1;
/* 88 */ uint64 t2;
/* 96 */ uint64 s0;
/* 104 */ uint64 s1;
/* 112 */ uint64 a0;
/* 120 */ uint64 a1;
/* 128 */ uint64 a2;
/* 136 */ uint64 a3;
/* 144 */ uint64 a4;
/* 152 */ uint64 a5;
/* 160 */ uint64 a6;
/* 168 */ uint64 a7;
/* 176 */ uint64 s2;
/* 184 */ uint64 s3;
/* 192 */ uint64 s4;
/* 200 */ uint64 s5;
/* 208 */ uint64 s6;
/* 216 */ uint64 s7;
/* 224 */ uint64 s8;
/* 232 */ uint64 s9;
/* 240 */ uint64 s10;
/* 248 */ uint64 s11;
/* 256 */ uint64 t3;
/* 264 */ uint64 t4;
/* 272 */ uint64 t5;
/* 280 */ uint64 t6;
};
enum Exception {
InstructionMisaligned = 0,
InstructionAccessFault = 1,
IllegalInstruction = 2,
Breakpoint = 3,
LoadMisaligned = 4,
LoadAccessFault = 5,
StoreMisaligned = 6,
StoreAccessFault = 7,
UserEnvCall = 8,
SupervisorEnvCall = 9,
MachineEnvCall = 11,
InstructionPageFault = 12,
LoadPageFault = 13,
StorePageFault = 15,
};
enum Interrupt {
UserSoft = 0,
SupervisorSoft,
UserTimer = 4,
SupervisorTimer,
UserExternal = 8,
SupervisorExternal,
};
void trap_init();
void usertrapret(struct trapframe *trapframe, uint64 kstack);
#endif // TRAP_H

12
os/types.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef TYPES_H
#define TYPES_H
typedef unsigned int uint;
typedef unsigned short ushort;
typedef unsigned char uchar;
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
typedef unsigned long uint64;
#endif // TYPES_H

69
scripts/kernelld.py Normal file
View File

@ -0,0 +1,69 @@
import os
TARGET_DIR = "./user/target/bin/"
if __name__ == '__main__':
f = open("os/kernel_app.ld", mode="w")
apps = os.listdir(TARGET_DIR)
f.write(
'''OUTPUT_ARCH(riscv)
ENTRY(_entry)
BASE_ADDRESS = 0x80200000;
SECTIONS
{
. = BASE_ADDRESS;
skernel = .;
s_text = .;
.text : {
*(.text.entry)
*(.text .text.*)
. = ALIGN(0x1000);
*(trampsec)
. = ALIGN(0x1000);
}
. = ALIGN(4K);
e_text = .;
s_rodata = .;
.rodata : {
*(.rodata .rodata.*)
}
. = ALIGN(4K);
e_rodata = .;
s_data = .;
.data : {
*(.data)
''')
for (idx, _) in enumerate(apps):
f.write(' . = ALIGN(0x1000);\n')
f.write(' *(.data.app{})\n'.format(idx))
f.write(
'''
. = ALIGN(0x1000);
*(.data.*)
*(.sdata .sdata.*)
}
. = ALIGN(4K);
e_data = .;
.bss : {
*(.bss.stack)
s_bss = .;
*(.bss .bss.*)
*(.sbss .sbss.*)
}
. = ALIGN(4K);
e_bss = .;
ekernel = .;
/DISCARD/ : {
*(.eh_frame)
}
}
''')
f.close()

41
scripts/pack.py Normal file
View File

@ -0,0 +1,41 @@
import os
TARGET_DIR = "./user/target/bin/"
if __name__ == '__main__':
f = open("os/link_app.S", mode="w")
apps = os.listdir(TARGET_DIR)
apps.sort()
f.write(
''' .align 4
.section .data
.global _app_num
_app_num:
.quad {}
'''.format(len(apps))
)
for (idx, _) in enumerate(apps):
f.write(' .quad app_{}_start\n'.format(idx))
f.write(' .quad app_{}_end\n'.format(len(apps) - 1))
f.write(
'''
.global _app_names
_app_names:
''');
for app in apps:
f.write(" .string \"" + app + "\"\n")
for (idx, app) in enumerate(apps):
f.write(
'''
.section .data.app{0}
.global app_{0}_start
app_{0}_start:
.incbin "{1}"
'''.format(idx, TARGET_DIR + app)
)
f.write('app_{}_end:\n\n'.format(len(apps) - 1))
f.close()