Browse Source

Merge branch 'master' into feat-dynamic-link

Chiichen 5 months ago
parent
commit
07d95d2dcd
100 changed files with 4488 additions and 2008 deletions
  1. 0 36
      .github/actions/import-toolchain/action.yml
  2. 0 16
      .github/actions/install-apt-packages/action.yml
  3. 0 94
      .github/workflows/cache-toolchain.yml
  4. 47 0
      .github/workflows/docs-multiversion.yml
  5. 34 0
      .github/workflows/docs.yml
  6. 18 20
      .github/workflows/makefile.yml
  7. 39 0
      .github/workflows/publish-dragonos-docker-image.yml
  8. 0 5
      .vscode/settings.json
  9. 6 1
      Makefile
  10. 1 1
      build-scripts/Cargo.toml
  11. 3 3
      build-scripts/kernel_build/src/cfiles/arch/mod.rs
  12. 11 10
      build-scripts/kernel_build/src/cfiles/arch/riscv64.rs
  13. 15 29
      build-scripts/kernel_build/src/cfiles/arch/x86_64.rs
  14. 21 0
      build-scripts/kernel_build/src/cfiles/common.rs
  15. 18 7
      build-scripts/kernel_build/src/cfiles/mod.rs
  16. 18 0
      docs/Makefile
  17. 8 0
      docs/_templates/footer.html
  18. 27 0
      docs/_templates/versions.html
  19. 37 2
      docs/conf.py
  20. 1 0
      docs/introduction/build_system.md
  21. 21 4
      docs/kernel/boot/bootloader.md
  22. 0 1
      docs/kernel/boot/index.rst
  23. 0 46
      docs/kernel/boot/multiboot2.md
  24. 11 0
      docs/kernel/libs/id-allocation.md
  25. 1 0
      docs/kernel/libs/index.rst
  26. 2 1
      docs/requirements.txt
  27. 4 3
      kernel/Cargo.toml
  28. 2 2
      kernel/crates/ida/Cargo.toml
  29. 3 0
      kernel/crates/ida/README.md
  30. 210 0
      kernel/crates/ida/src/lib.rs
  31. 3 2
      kernel/crates/kdepends/Cargo.toml
  32. 1 0
      kernel/crates/kdepends/src/lib.rs
  33. 8 21
      kernel/env.mk
  34. 2 2
      kernel/src/Makefile
  35. 3 1
      kernel/src/arch/riscv64/driver/sbi.rs
  36. 15 0
      kernel/src/arch/riscv64/init/boot.rs
  37. 41 0
      kernel/src/arch/riscv64/init/dragonstub.rs
  38. 9 1
      kernel/src/arch/riscv64/init/mod.rs
  39. 11 1
      kernel/src/arch/riscv64/rand.rs
  40. 152 81
      kernel/src/arch/x86_64/asm/head.S
  41. 1 1
      kernel/src/arch/x86_64/driver/apic/ioapic.rs
  42. 8 0
      kernel/src/arch/x86_64/driver/rtc.rs
  43. 52 0
      kernel/src/arch/x86_64/init/boot.rs
  44. 16 3
      kernel/src/arch/x86_64/init/mod.rs
  45. 248 0
      kernel/src/arch/x86_64/init/multiboot2.rs
  46. 142 0
      kernel/src/arch/x86_64/init/pvh/mod.rs
  47. 425 0
      kernel/src/arch/x86_64/init/pvh/param.rs
  48. 0 1
      kernel/src/arch/x86_64/interrupt/entry.rs
  49. 8 3
      kernel/src/arch/x86_64/link.lds
  50. 29 9
      kernel/src/arch/x86_64/mm/fault.rs
  51. 18 81
      kernel/src/arch/x86_64/mm/mod.rs
  52. 8 8
      kernel/src/arch/x86_64/pci/pci.rs
  53. 0 11
      kernel/src/arch/x86_64/sched.rs
  54. 0 14
      kernel/src/common/Makefile
  55. 0 23
      kernel/src/common/boot_info.h
  56. 10 27
      kernel/src/common/glib.h
  57. 0 10
      kernel/src/common/math/Makefile
  58. 9 58
      kernel/src/common/string.h
  59. 0 22
      kernel/src/common/unistd.h
  60. 2 1
      kernel/src/debug/Makefile
  61. 4 3
      kernel/src/debug/klog/mm.rs
  62. 0 17
      kernel/src/driver/Makefile
  63. 0 10
      kernel/src/driver/acpi/Makefile
  64. 0 35
      kernel/src/driver/acpi/acpi.c
  65. 0 37
      kernel/src/driver/acpi/acpi.h
  66. 0 8
      kernel/src/driver/acpi/c_adapter.rs
  67. 52 32
      kernel/src/driver/acpi/mod.rs
  68. 115 3
      kernel/src/driver/base/block/block_device.rs
  69. 34 12
      kernel/src/driver/base/block/disk_info.rs
  70. 195 0
      kernel/src/driver/base/block/gendisk.rs
  71. 238 0
      kernel/src/driver/base/block/manager.rs
  72. 3 0
      kernel/src/driver/base/block/mod.rs
  73. 24 22
      kernel/src/driver/base/cpu.rs
  74. 8 2
      kernel/src/driver/base/device/bus.rs
  75. 176 28
      kernel/src/driver/base/device/mod.rs
  76. 4 5
      kernel/src/driver/base/kobject.rs
  77. 53 47
      kernel/src/driver/base/platform/platform_device.rs
  78. 8 1
      kernel/src/driver/base/platform/subsys.rs
  79. 134 13
      kernel/src/driver/block/virtio_blk.rs
  80. 54 31
      kernel/src/driver/disk/ahci/ahcidisk.rs
  81. 8 52
      kernel/src/driver/disk/ahci/mod.rs
  82. 36 34
      kernel/src/driver/input/ps2_mouse/ps_mouse_device.rs
  83. 37 33
      kernel/src/driver/input/serio/i8042/i8042_device.rs
  84. 35 33
      kernel/src/driver/input/serio/i8042/i8042_ports.rs
  85. 3 4
      kernel/src/driver/input/serio/i8042/mod.rs
  86. 1 0
      kernel/src/driver/mod.rs
  87. 0 10
      kernel/src/driver/multiboot2/Makefile
  88. 0 165
      kernel/src/driver/multiboot2/multiboot2.c
  89. 0 473
      kernel/src/driver/multiboot2/multiboot2.h
  90. 83 0
      kernel/src/driver/net/class.rs
  91. 123 43
      kernel/src/driver/net/e1000e/e1000e_driver.rs
  92. 124 46
      kernel/src/driver/net/loopback.rs
  93. 88 2
      kernel/src/driver/net/mod.rs
  94. 635 0
      kernel/src/driver/net/sysfs.rs
  95. 339 93
      kernel/src/driver/net/virtio_net.rs
  96. 41 24
      kernel/src/driver/pci/device.rs
  97. 2 2
      kernel/src/driver/pci/pci_irq.rs
  98. 39 26
      kernel/src/driver/pci/raw_device.rs
  99. 5 0
      kernel/src/driver/pci/subsys.rs
  100. 8 0
      kernel/src/driver/pci/test/pt_device.rs

+ 0 - 36
.github/actions/import-toolchain/action.yml

@@ -1,36 +0,0 @@
-name: import-toolchain
-
-runs:
-  using: composite
-  steps:
-      - uses: actions/checkout@v3
-        with:
-          submodules: 'recursive'
-
-      - name: Cache DragonOS GCC
-        id: cache-dragonos-gcc
-        uses: actions/cache@v3
-        env:
-            cache-name: cache-dragonos-gcc
-        with:
-          path: |
-            ~/opt
-            ~/.bashrc
-          key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('tools/build_gcc_toolchain.sh') }}
-
-      - name: Cache build tools
-        id: cache-build-tools
-        uses: actions/cache@v3
-        env:
-            cache-name: cache-build-tools
-            dadk_version: 0.1.11
-        with:
-          path: |
-            ~/.cargo
-            ~/.rustup
-            ~/.bashrc
-            ~/opt
-          key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.dadk_version }}-${{ hashFiles('.github/workflows/cache-toolchain.yml') }}-${{ hashFiles('tools/install_musl_gcc.sh') }}
-      
-      - uses: ./.github/actions/install-apt-packages
-      

+ 0 - 16
.github/actions/install-apt-packages/action.yml

@@ -1,16 +0,0 @@
-name: install-apt-packages
-
-runs:
-  using: composite
-  steps:
-      
-      - uses: awalsh128/cache-apt-pkgs-action@latest
-        with:
-          packages: llvm-dev libclang-dev clang gcc-multilib libssl-dev pkg-config
-          version: ${{ hashFiles('.github/actions/install-apt-packages/action.yml') }}
-      
-      - uses: awalsh128/cache-apt-pkgs-action@latest
-        with:
-          packages:  gcc-riscv64-unknown-elf gcc-riscv64-linux-gnu gdb-multiarch
-          version: ${{ hashFiles('.github/actions/install-apt-packages/action.yml') }}
-    

+ 0 - 94
.github/workflows/cache-toolchain.yml

@@ -1,94 +0,0 @@
-name: Cache toolchain
-
-on: workflow_call
-
-jobs:
-    build:
-
-        runs-on: ubuntu-latest
-    
-        steps:
-        - uses: actions/checkout@v3
-        
-        - name: Cache DragonOS GCC
-          id: cache-dragonos-gcc
-          uses: actions/cache@v3
-          env:
-              cache-name: cache-dragonos-gcc
-          with:
-            path: |
-              ~/opt
-              ~/.bashrc
-            key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('tools/build_gcc_toolchain.sh') }}
-        
-        - if: ${{ steps.cache-dragonos-gcc.outputs.cache-hit != 'true' }}
-          name: build dragonos-gcc
-          continue-on-error: true
-          run: |
-              bash tools/build_gcc_toolchain.sh -f
-        
-        - uses: ./.github/actions/install-apt-packages
-
-        - name: Cache build tools
-          id: cache-build-tools
-          uses: actions/cache@v3
-          env:
-              cache-name: cache-build-tools
-              dadk_version: 0.1.11
-          with:
-            path: |
-              ~/.cargo
-              ~/.rustup
-              ~/.bashrc
-              ~/opt
-            key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.dadk_version }}-${{ hashFiles('.github/workflows/cache-toolchain.yml') }}-${{ hashFiles('tools/install_musl_gcc.sh') }}
-        
-        - if: ${{ steps.cache-build-tools.outputs.cache-hit != 'true' }}
-          name: Install toolchain
-          continue-on-error: false
-          run:  | 
-            USE_GITHUB=1 bash tools/install_musl_gcc.sh
-
-            cargo install cargo-binutils
-            rustup toolchain install nightly-x86_64-unknown-linux-gnu
-            rustup toolchain install nightly-2024-07-23-x86_64-unknown-linux-gnu
-            rustup toolchain install nightly-2023-08-15-x86_64-unknown-linux-gnu
-            rustup component add rust-src --toolchain nightly-2024-07-23-x86_64-unknown-linux-gnu
-            rustup component add rust-src --toolchain nightly-2023-08-15-x86_64-unknown-linux-gnu
-            rustup target add x86_64-unknown-none --toolchain nightly-2024-07-23-x86_64-unknown-linux-gnu
-            rustup target add x86_64-unknown-none --toolchain nightly-2023-08-15-x86_64-unknown-linux-gnu
-
-            rustup toolchain install nightly-2024-07-23-riscv64gc-unknown-linux-gnu --force-non-host
-            rustup toolchain install nightly-2023-08-15-riscv64gc-unknown-linux-gnu --force-non-host
-            rustup target add riscv64gc-unknown-none-elf --toolchain nightly-2024-07-23-riscv64gc-unknown-linux-gnu
-            rustup target add riscv64imac-unknown-none-elf --toolchain nightly-2024-07-23-riscv64gc-unknown-linux-gnu
-            rustup target add riscv64gc-unknown-none-elf --toolchain nightly-2023-08-15-riscv64gc-unknown-linux-gnu
-            rustup target add riscv64imac-unknown-none-elf --toolchain nightly-2023-08-15-riscv64gc-unknown-linux-gnu
-                
-            rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu
-            rustup component add rust-src
-            rustup component add llvm-tools-preview
-
-            rustup component add rustfmt
-            rustup component add rustfmt --toolchain nightly-x86_64-unknown-linux-gnu
-            rustup component add rustfmt --toolchain nightly-2024-07-23-x86_64-unknown-linux-gnu
-            rustup component add rustfmt --toolchain nightly-2023-08-15-x86_64-unknown-linux-gnu
-            rustup component add rustfmt --toolchain nightly-2024-07-23-riscv64gc-unknown-linux-gnu
-            rustup component add rustfmt --toolchain nightly-2023-08-15-riscv64gc-unknown-linux-gnu
-
-            rustup default nightly-2024-07-23
-
-            cargo install dadk --version 0.1.11
-          
-
-            userapp_musl_toolchain="nightly-2023-08-15-x86_64-unknown-linux-gnu"
-            
-            rustup toolchain install ${userapp_musl_toolchain}
-            rustup component add --toolchain ${userapp_musl_toolchain} rust-src
-            rustup target add --toolchain ${userapp_musl_toolchain} x86_64-unknown-linux-musl
-
-            rustup target add x86_64-unknown-linux-musl --toolchain nightly-2024-07-23-x86_64-unknown-linux-gnu
-            rustup component add rust-src --toolchain nightly-2024-07-23-x86_64-unknown-linux-gnu
-           
-
-

+ 47 - 0
.github/workflows/docs-multiversion.yml

@@ -0,0 +1,47 @@
+name: Build multiversion docs
+
+on:
+  push:
+    branches: [ "master" ]
+    tags: [ "v*", "V*"]
+
+env:
+    GITHUB_REPOSITORY: ${{ github.repository }}
+    GITHUB_REF: ${{ github.ref }}
+
+jobs:
+
+  build-multiversion:
+    if: github.repository == 'DragonOS-Community/DragonOS'
+    runs-on: ubuntu-latest
+
+    steps:
+    - uses: actions/checkout@v4
+      with:
+        fetch-depth: 0
+        ref: master
+      
+    - name: install requirements
+      working-directory: ./docs
+      run: |
+        sudo apt-get update
+        sudo apt-get install -y python3-pip python3-setuptools
+        pip3 install -r requirements.txt
+        python3 -m pip install --user awscli
+
+    - name: build docs
+      working-directory: ./docs
+      shell: bash -ileo pipefail {0}
+
+      run: |
+        make html-multiversion
+
+    - name: deploy docs
+      working-directory: ./docs
+      env:
+        AWS_ENDPOINT_URL: ${{ secrets.DOCS_DEPLOY_S3_ENDPOINT_URL }}
+        AWS_ACCESS_KEY_ID: ${{ secrets.DOCS_DEPLOY_S3_API_KEY }}
+        AWS_SECRET_ACCESS_KEY: ${{ secrets.DOCS_DEPLOY_S3_SECRET_KEY }}
+      
+      run: |
+        aws s3 sync ./_build/html s3://dragonos-docs --delete

+ 34 - 0
.github/workflows/docs.yml

@@ -0,0 +1,34 @@
+name: Build current version docs
+
+on:
+  pull_request:
+    branches: [ "master" ]
+    # paths:
+    #   - 'docs/**'
+
+env:
+    GITHUB_REPOSITORY: ${{ github.repository }}
+    GITHUB_REF: ${{ github.ref }}
+
+jobs:
+
+  build-current-version:
+    if: github.repository == 'DragonOS-Community/DragonOS'
+    runs-on: ubuntu-latest
+
+    steps:
+    - uses: actions/checkout@v4
+      
+    - name: install requirements
+      working-directory: ./docs
+      run: |
+        sudo apt-get update
+        sudo apt-get install -y python3-pip
+        pip3 install -r requirements.txt
+
+    - name: build docs
+      working-directory: ./docs
+      shell: bash -ileo pipefail {0}
+
+      run: |
+        make html

+ 18 - 20
.github/workflows/makefile.yml

@@ -7,28 +7,26 @@ on:
     branches: [ "master", "feat-*", "fix-*"]
 
 jobs:
-  # ensure the toolchain is cached
-  ensure-toolchain:
-    uses: ./.github/workflows/cache-toolchain.yml
   
   format-check:
     name: Format check ${{ matrix.arch }}
     runs-on: ubuntu-latest
-    needs: [ensure-toolchain]
     continue-on-error: true
+    container: dragonos/dragonos-dev:v1.3
 
     strategy:
       matrix:
         arch: [x86_64, riscv64]
 
     steps:
+    - run: echo "Running in dragonos/dragonos-dev:v1.3"
     - uses: actions/checkout@v3
 
-    - uses: ./.github/actions/import-toolchain
-
     - name: Format check
       env:
           ARCH: ${{ matrix.arch }}
+          HOME: /root
+      shell: bash -ileo pipefail {0}
       run: |
             printf "\n" >> kernel/src/include/bindings/bindings.rs
             FMT_CHECK=1 make fmt
@@ -36,38 +34,38 @@ jobs:
   kernel-static-test:
     name: Kernel static test ${{ matrix.arch }}
     runs-on: ubuntu-latest
-    needs: [ensure-toolchain]
     continue-on-error: true
+    container: dragonos/dragonos-dev:v1.3
 
     strategy:
       matrix:
         arch: [x86_64, riscv64]
 
     steps:
-    - uses: actions/checkout@v3
+    - run: echo "Running in dragonos/dragonos-dev:v1.3"
 
-    - uses: ./.github/actions/import-toolchain
+    - uses: actions/checkout@v3
 
     - name: Run kernel static test
       shell: bash -ileo pipefail {0}
       env:
           ARCH: ${{ matrix.arch }}
-      run: bash -c "source ~/.cargo/env && cd kernel && make test"
-    
+          HOME: /root
+      run: bash -c "source /root/.cargo/env && cd kernel && make test"
+
   build-x86_64:
 
     runs-on: ubuntu-latest
-    needs: [ensure-toolchain]
+    container: dragonos/dragonos-dev:v1.3
 
     steps:
-    - uses: actions/checkout@v3
+    - run: echo "Running in dragonos/dragonos-dev:v1.3"
 
-    - uses: ./.github/actions/import-toolchain
-
-      
+    - uses: actions/checkout@v3
     - name: build the DragonOS
       env:
           ARCH: x86_64
+          HOME: /root
       shell: bash -ileo pipefail {0}
 
       run: |
@@ -77,23 +75,23 @@ jobs:
         
         make -j $(nproc)
 
-  
   build-riscv64:
 
     runs-on: ubuntu-latest
-    needs: [ensure-toolchain]
+    container: dragonos/dragonos-dev:v1.3
 
     steps:
+    - run: echo "Running in dragonos/dragonos-dev:v1.3"
+
     - uses: actions/checkout@v3
       with:
         submodules: 'recursive'
 
-    - uses: ./.github/actions/import-toolchain
-
     - name: build the DragonOS
       shell: bash -ileo pipefail {0}
       env:
           ARCH: riscv64
+          HOME: /root
 
       run: source ~/.bashrc && source ~/.cargo/env && make kernel -j $(nproc)
 

+ 39 - 0
.github/workflows/publish-dragonos-docker-image.yml

@@ -0,0 +1,39 @@
+name: Publish Docker images
+
+on:
+  workflow_dispatch:
+  push:
+    paths:
+      - tools/BUILD_CONTAINER_VERSION
+    branches:
+      - master
+
+jobs:
+  docker:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Set up Docker Buildx
+        uses: docker/setup-buildx-action@v2
+
+      - name: Login to Docker Hub
+        uses: docker/login-action@v2
+        with:
+          username: ${{ secrets.DOCKERHUB_USERNAME }}
+          password: ${{ secrets.DOCKERHUB_TOKEN }}
+
+      - uses: actions/checkout@v4
+
+      - name: Fetch versions in the repo
+        id: fetch-versions
+        run: |
+          BUILD_CONTAINER_VERSION=$(cat tools/BUILD_CONTAINER_VERSION)
+          echo "build_container_version=$BUILD_CONTAINER_VERSION" >> "$GITHUB_OUTPUT"
+
+      - name: Build and push docker image
+        uses: docker/build-push-action@v4
+        with:
+          context: "{{defaultContext}}:tools"
+          file: Dockerfile
+          platforms: linux/amd64
+          push: true
+          tags: dragonos/dragonos-dev:${{ steps.fetch-versions.outputs.build_container_version }}

+ 0 - 5
.vscode/settings.json

@@ -9,7 +9,6 @@
         "glib.h": "c",
         "asm.h": "c",
         "memory.h": "c",
-        "multiboot2.h": "c",
         "kprint.h": "c",
         "ptrace.h": "c",
         "mouse.h": "c",
@@ -77,7 +76,6 @@
         "cstdbool": "c",
         "typeinfo": "c",
         "unistd.h": "c",
-        "syscall_num.h": "c",
         "stdint.h": "c",
         "syscall.h": "c",
         "fcntl.h": "c",
@@ -121,15 +119,12 @@
         "dirent.h": "c",
         "cmd_help.h": "c",
         "wait.h": "c",
-        "__libc__.h": "c",
         "ctype.h": "c",
-        "mmio.h": "c",
         "stdint-gcc.h": "c",
         "acpi.h": "c",
         "assert.h": "c",
         "sys_version.h": "c",
         "cmd.h": "c",
-        "sleep.h": "c",
         "net.h": "c",
         "cmd_test.h": "c",
         "cmpxchg.h": "c",

+ 6 - 1
Makefile

@@ -91,6 +91,11 @@ write_diskimage-uefi:
 # 不编译,直接启动QEMU
 qemu:
 	sh -c "cd tools && bash run-qemu.sh --bios=legacy --display=window && cd .."
+
+# 不编译,直接启动QEMU,不显示图像
+qemu-nographic:
+	sh -c "cd tools && bash run-qemu.sh --bios=legacy --display=nographic && cd .."
+
 # 不编译,直接启动QEMU(UEFI)
 qemu-uefi:
 	sh -c "cd tools && bash run-qemu.sh --bios=uefi --display=window && cd .."
@@ -163,7 +168,7 @@ update-submodules:
 update-submodules-by-mirror:
 	@echo "从镜像更新子模块"
 	@git config --global url."https://git.mirrors.dragonos.org.cn/DragonOS-Community/".insteadOf https://github.com/DragonOS-Community/
-	@$(MAKE) update-submodules --init
+	@$(MAKE) update-submodules
 	@git config --global --unset url."https://git.mirrors.dragonos.org.cn/DragonOS-Community/".insteadOf
 
 help:

+ 1 - 1
build-scripts/Cargo.toml

@@ -2,4 +2,4 @@
 members = [
     "kernel_build",
 ]
-resolver = "2"
+resolver = "2"

+ 3 - 3
build-scripts/kernel_build/src/cfiles/arch/mod.rs

@@ -1,4 +1,4 @@
-use std::path::PathBuf;
+use std::{collections::HashSet, path::PathBuf};
 
 use cc::Build;
 
@@ -13,9 +13,9 @@ pub(super) trait CFilesArch {
     /// 设置架构相关的宏定义
     fn setup_defines(&self, c: &mut Build);
     /// 设置架构相关的全局包含目录
-    fn setup_global_include_dir(&self, c: &mut Build);
+    fn setup_global_include_dir(&self, c: &mut HashSet<PathBuf>);
     /// 设置需要编译的架构相关的文件
-    fn setup_files(&self, c: &mut Build, files: &mut Vec<PathBuf>);
+    fn setup_files(&self, c: &mut Build, files: &mut HashSet<PathBuf>);
 
     /// 设置架构相关的全局编译标志
     fn setup_global_flags(&self, c: &mut Build);

+ 11 - 10
build-scripts/kernel_build/src/cfiles/arch/riscv64.rs

@@ -1,4 +1,4 @@
-use std::path::PathBuf;
+use std::{collections::HashSet, path::PathBuf};
 
 use crate::{constant::ARCH_DIR_RISCV64, utils::FileUtils};
 
@@ -12,17 +12,18 @@ impl CFilesArch for RiscV64CFilesArch {
         c.define("__riscv", None);
     }
 
-    fn setup_global_include_dir(&self, c: &mut cc::Build) {
-        c.include("src/arch/riscv64/include");
+    fn setup_global_include_dir(&self, include_dirs: &mut HashSet<PathBuf>) {
+        include_dirs.insert("src/arch/riscv64/include".into());
     }
 
-    fn setup_files(&self, _c: &mut cc::Build, files: &mut Vec<std::path::PathBuf>) {
-        files.push(PathBuf::from("src/arch/riscv64/asm/head.S"));
-        files.append(&mut FileUtils::list_all_files(
-            &arch_path("asm"),
-            Some("c"),
-            true,
-        ));
+    fn setup_files(&self, _c: &mut cc::Build, files: &mut HashSet<PathBuf>) {
+        files.insert(PathBuf::from("src/arch/riscv64/asm/head.S"));
+
+        FileUtils::list_all_files(&arch_path("asm"), Some("c"), true)
+            .into_iter()
+            .for_each(|f| {
+                files.insert(f);
+            });
     }
 
     fn setup_global_flags(&self, c: &mut cc::Build) {

+ 15 - 29
build-scripts/kernel_build/src/cfiles/arch/x86_64.rs

@@ -1,4 +1,4 @@
-use std::path::PathBuf;
+use std::{collections::HashSet, path::PathBuf};
 
 use cc::Build;
 
@@ -13,38 +13,24 @@ impl CFilesArch for X86_64CFilesArch {
         c.define("__x86_64__", None);
     }
 
-    fn setup_global_include_dir(&self, c: &mut cc::Build) {
-        c.include("src/arch/x86_64/include");
+    fn setup_global_include_dir(&self, include_dirs: &mut HashSet<PathBuf>) {
+        include_dirs.insert("src/arch/x86_64/include".into());
     }
 
-    fn setup_files(&self, _c: &mut Build, files: &mut Vec<PathBuf>) {
-        // 获取`kernel/src/arch/x86_64/driver/apic`下的所有C文件
-        files.append(&mut FileUtils::list_all_files(
-            &arch_path("driver/apic"),
-            Some("c"),
-            true,
-        ));
-
-        files.append(&mut FileUtils::list_all_files(
-            &arch_path("init"),
-            Some("c"),
-            true,
-        ));
-        files.append(&mut FileUtils::list_all_files(
-            &arch_path("asm"),
-            Some("c"),
-            true,
-        ));
-        files.append(&mut FileUtils::list_all_files(
-            &arch_path("interrupt"),
-            Some("c"),
-            true,
-        ));
+    fn setup_files(&self, _c: &mut Build, files: &mut HashSet<PathBuf>) {
+        const DIRS: [&str; 4] = ["driver/apic", "init", "asm", "interrupt"];
+        DIRS.iter().for_each(|dir| {
+            FileUtils::list_all_files(&arch_path(dir), Some("c"), true)
+                .into_iter()
+                .for_each(|f| {
+                    files.insert(f);
+                });
+        });
 
         // setup asm files
-        files.push(PathBuf::from("src/arch/x86_64/asm/head.S"));
-        files.push(PathBuf::from("src/arch/x86_64/asm/entry.S"));
-        files.push(PathBuf::from("src/arch/x86_64/asm/apu_boot.S"));
+        files.insert(PathBuf::from("src/arch/x86_64/asm/head.S"));
+        files.insert(PathBuf::from("src/arch/x86_64/asm/entry.S"));
+        files.insert(PathBuf::from("src/arch/x86_64/asm/apu_boot.S"));
     }
 
     fn setup_global_flags(&self, c: &mut Build) {

+ 21 - 0
build-scripts/kernel_build/src/cfiles/common.rs

@@ -0,0 +1,21 @@
+use std::{collections::HashSet, path::PathBuf};
+
+use crate::utils::FileUtils;
+
+pub(super) fn setup_common_files(files: &mut HashSet<PathBuf>) {
+    const DIRS: [&str; 3] = ["src/common", "src/debug/traceback", "src/libs"];
+    DIRS.iter().for_each(|dir| {
+        FileUtils::list_all_files(&dir.into(), Some("c"), true)
+            .into_iter()
+            .for_each(|f| {
+                files.insert(f);
+            });
+    });
+}
+
+pub(super) fn setup_common_include_dir(include_dirs: &mut HashSet<PathBuf>) {
+    const DIRS: [&str; 3] = ["src/include", "src/common", "src"];
+    DIRS.iter().for_each(|dir| {
+        include_dirs.insert(dir.into());
+    });
+}

+ 18 - 7
build-scripts/kernel_build/src/cfiles/mod.rs

@@ -1,4 +1,4 @@
-use std::path::PathBuf;
+use std::{collections::HashSet, path::PathBuf};
 
 use cc::Build;
 
@@ -7,6 +7,7 @@ use crate::utils::cargo_handler::CargoHandler;
 use self::arch::current_cfiles_arch;
 
 mod arch;
+mod common;
 
 /// 构建项目的c文件
 pub struct CFilesBuilder;
@@ -46,19 +47,29 @@ impl CFilesBuilder {
     }
 
     fn setup_global_include_dir(c: &mut Build) {
-        c.include("src/include");
-        c.include("src");
+        let mut include_dirs = HashSet::new();
+
         c.include(".");
 
-        current_cfiles_arch().setup_global_include_dir(c);
+        common::setup_common_include_dir(&mut include_dirs);
+
+        current_cfiles_arch().setup_global_include_dir(&mut include_dirs);
+
+        let include_dirs: Vec<PathBuf> = include_dirs.into_iter().collect();
+        Self::set_rerun_if_files_changed(&include_dirs);
+
+        include_dirs.into_iter().for_each(|dir| {
+            c.include(dir);
+        });
     }
 
     /// 设置需要编译的文件
     fn setup_files(c: &mut Build) {
-        let mut files: Vec<PathBuf> = Vec::new();
-
+        let mut files: HashSet<PathBuf> = HashSet::new();
         current_cfiles_arch().setup_files(c, &mut files);
-
+        common::setup_common_files(&mut files);
+        // 去重
+        let files: Vec<PathBuf> = files.into_iter().collect();
         Self::set_rerun_if_files_changed(&files);
         c.files(files.as_slice());
     }

+ 18 - 0
docs/Makefile

@@ -8,6 +8,20 @@ SPHINXBUILD   ?= sphinx-build
 SOURCEDIR     = .
 BUILDDIR      = _build
 
+LANGUAGE      = zh_CN
+
+SPHINXOPTS	+= -D language=$(LANGUAGE)
+
+export CURRENT_GIT_COMMIT_HASH := $(shell git rev-parse --short HEAD)
+
+GIT_STATUS := $(shell git status --porcelain --untracked-files=no)
+
+ifeq ($(strip $(GIT_STATUS)),)
+    export CURRENT_GIT_COMMIT_DIRTY = 0
+else
+    export CURRENT_GIT_COMMIT_DIRTY = 1
+endif
+
 # Put it first so that "make" without argument is like "make help".
 help:
 	@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
@@ -18,3 +32,7 @@ help:
 # "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
 %: Makefile
 	@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+.PHONY:
+html-multiversion:
+	rm -rf ./$(BUILDDIR) && CURRENT_GIT_COMMIT_DIRTY=0 sphinx-multiversion $(SPHINXOPTS) "$(SOURCEDIR)" ./$(BUILDDIR)/html && cp -rf ./$(BUILDDIR)/html/master/* ./$(BUILDDIR)/html/

+ 8 - 0
docs/_templates/footer.html

@@ -0,0 +1,8 @@
+{% extends "!footer.html" %}
+
+{% block extrafooter %}
+<div>
+    <br>
+    官网 <a href="https://dragonos.org">https://dragonos.org</a> | 论坛 <a href="https://bbs.dragonos.org.cn">https://bbs.dragonos.org.cn</a> |  <a href="https://dragonos.org">赞助DragonOS,成就未来!</a>
+</div>
+{% endblock %}

+ 27 - 0
docs/_templates/versions.html

@@ -0,0 +1,27 @@
+{%- if current_version %}
+<div class="rst-versions" data-toggle="rst-versions" role="note" aria-label="versions">
+  <span class="rst-current-version" data-toggle="rst-current-version">
+    <span class="fa fa-book"> Other Versions</span>
+    v: {{ current_version.name }}
+    <span class="fa fa-caret-down"></span>
+  </span>
+  <div class="rst-other-versions">
+    {%- if versions.tags %}
+    <dl>
+      <dt>Tags</dt>
+      {%- for item in versions.tags %}
+      <dd><a href="{{ item.url }}">{{ item.name }}</a></dd>
+      {%- endfor %}
+    </dl>
+    {%- endif %}
+    {%- if versions.branches %}
+    <dl>
+      <dt>Branches</dt>
+      {%- for item in versions.branches %}
+      <dd><a href="{{ item.url }}">{{ item.name }}</a></dd>
+      {%- endfor %}
+    </dl>
+    {%- endif %}
+  </div>
+</div>
+{%- endif %}

+ 37 - 2
docs/conf.py

@@ -19,6 +19,8 @@ import os
 project = 'DragonOS'
 copyright = '2022-2024, DragonOS Community'
 author = 'longjin'
+github_org = 'DragonOS-Community'
+github_repo = 'DragonOS'
 
 # The full version, including alpha/beta/rc tags
 release = 'dev'
@@ -29,7 +31,7 @@ release = 'dev'
 # Add any Sphinx extension module names here, as strings. They can be
 # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
 # ones.
-extensions = ['myst_parser']
+extensions = ['myst_parser', 'sphinx_multiversion']
 
 # Add any paths that contain templates here, relative to this directory.
 templates_path = ['_templates']
@@ -54,11 +56,19 @@ source_suffix = ['.rst', '.md']
 #
 html_theme = 'sphinx_rtd_theme'
 
+html_context = dict()
+
 # Add any paths that contain custom static files (such as style sheets) here,
 # relative to this directory. They are copied after the builtin static files,
 # so a file named "default.css" will overwrite the builtin "default.css".
 html_static_path = ['_static']
 
+html_sidebars = {
+    '**': [
+        'versioning.html',
+    ],
+}
+
 myst_enable_extensions = [
     "amsmath",
     "colon_fence",
@@ -74,10 +84,35 @@ myst_enable_extensions = [
     "tasklist",
 ]
 
+# sphinx-multiversion 指定哪个分支为 lastest 版本
+smv_latest_version = 'master'
+smv_released_pattern = r'^tags/.*$'           # Tags only
+smv_tag_whitelist = r'^(V.*|v.*)$'
+smv_branch_whitelist = "master"
 
 # Define the canonical URL if you are using a custom domain on Read the Docs
 html_baseurl = os.environ.get("READTHEDOCS_CANONICAL_URL", "")
 
 # Tell Jinja2 templates the build is running on Read the Docs
 if os.environ.get("READTHEDOCS", "") == "True":
-    html_context["READTHEDOCS"] = True
+    html_context["READTHEDOCS"] = True
+
+if os.environ.get("SPHINX_MULTIVERSION_GIT_COMMIT", "") != "":
+    html_context["commit"] = os.environ["SPHINX_MULTIVERSION_GIT_COMMIT"]
+elif os.environ.get("CURRENT_GIT_COMMIT_HASH", "") != "":
+    html_context["commit"] = os.environ["CURRENT_GIT_COMMIT_HASH"]
+
+
+# 截取前 7 位 commit hash,如果长度不足则不截取
+if "commit" in html_context:
+    html_context["commit"] = html_context["commit"][:7]
+    if os.environ.get("CURRENT_GIT_COMMIT_DIRTY", "") == "1":
+        html_context["commit"] += "-dirty"
+
+
+# -- Set GitHub URL for Edit on GitHub links ---
+html_context['display_github'] = True
+html_context['github_user'] = github_org
+html_context['github_repo'] = github_repo
+html_context['github_version'] = html_context['commit'] if 'commit' in html_context else 'master'
+html_context['conf_py_path'] = '/docs/'

+ 1 - 0
docs/introduction/build_system.md

@@ -242,6 +242,7 @@ make run-docker
 - Docker编译,并写入磁盘镜像,: `make docker`
 - Docker编译,写入磁盘镜像,并在QEMU中运行: `make run-docker`
 - 不编译,直接从已有的磁盘镜像启动: `make qemu`
+- 不编译,直接从已有的磁盘镜像启动(无图形模式): `make qemu-nographic`
 - 清理编译产生的文件: `make clean`
 - 编译文档: `make docs` (需要手动安装sphinx以及docs下的`requirements.txt`中的依赖)
 - 清理文档: `make clean-docs`

+ 21 - 4
docs/kernel/boot/bootloader.md

@@ -1,12 +1,29 @@
 # 引导加载程序
 
-## 原理
+## X86_64
 
-&emsp;&emsp;目前,DragonOS支持Legacy BIOS以及UEFI两种方式,进行启动引导。
+- [x] multiboot2
+- [x] HVM/PVH
 
-&emsp;&emsp;在`head.S`的头部包含了Multiboot2引导头,里面标志了一些Multiboot2相关的特定信息,以及一些配置命令。
+### x86_64下的HVM/PVH启动
 
-&emsp;&emsp;在DragonOS的启动初期,会存储由GRUB2传来的magic number以及multiboot2_boot_info_addr。当系统进入`Start_Kernel`函数之后,将会把这两个信息保存到multiboot2驱动程序之中。信息的具体含义请参照Multiboot2 Specification进行理解,该部分难度不大,相信读者经过思考能理解其中的原理。
+在DragonOS的note段,有一段PVH header,允许qemu使用`-kernel`参数启动DragonOS内核。
+
+## RISC-V 64
+
+DragonOS在RISC-V 64上,启动流程为:
+
+opensbi --> uboot --> DragonStub --> kernel
+
+这个启动流程,使得DragonOS内核与具体的硬件板卡解耦,能够以同一个二进制文件,在不同的硬件板卡上启动运行。
+
+
+## 内核启动回调
+
+DragonOS对内核引导加载程序进行了抽象,体现为`BootCallbacks`这个trait。
+不同的引导加载程序,实现对应的callback,初始化内核bootParams或者是其他的一些数据结构。
+
+内核启动时,自动根据引导加载程序的类型,注册回调。并且在适当的时候,会调用这些回调函数。
 
 ## 参考资料
 

+ 0 - 1
docs/kernel/boot/index.rst

@@ -8,4 +8,3 @@
    :caption: 目录
 
    bootloader
-   multiboot2

+ 0 - 46
docs/kernel/boot/multiboot2.md

@@ -1,46 +0,0 @@
-# Multiboot2支持模块
-
-&emsp;&emsp;Multiboot2支持模块提供对Multiboot2协议的支持。位于`kernel/driver/multiboot2`文件夹中。
-
-&emsp;&emsp;根据Multiboot2协议,操作系统能够从BootLoader处获得一些信息,比如基本的硬件信息以及ACPI表的起始地址等。
-
----
-
-## 数据结构
-
-&emsp;&emsp;`kernel/driver/multiboot2/multiboot2.h`中按照Multiboot2协议的规定,定义了大部分的数据结构,具体细节可查看该文件: [DragonOS/multiboot2.h at master · fslongjin/DragonOS · GitHub](https://github.com/fslongjin/DragonOS/blob/master/kernel/driver/multiboot2/multiboot2.h)
-
----
-
-## 迭代器
-
-&emsp;&emsp;由于Multiboot2的信息存储在自`multiboot2_boot_info_addr`开始的一段连续的内存空间之中,且不同类型的header的长度不同,因此设计了一迭代器`multiboot2_iter`。
-
-### 函数原型
-
-```c
-void multiboot2_iter(bool (*_fun)(const struct iter_data_t *, void *, unsigned int *),
-                     void *data, unsigned int *count)
-```
-
-**_fun**
-
-&emsp;&emsp;指定的handler。当某个header的tag与该handler所处理的tag相同时,handler将处理该header,并返回true。
-
-&emsp;&emsp;其第一个参数为tag类型,第二个参数为返回的数据的指针,第三个值为计数(某些没有用到该值的地方,该值可以为空)
-
-**data**
-
-&emsp;&emsp;传递给`_fun`的第二个参数,`_fun`函数将填充该指针所指向的内存区域,从而返回数据。
-
-**count**
-
-&emsp;&emsp;当返回的**data**为一个列表时,通过该值来指示列表中有多少项。
-
----
-
-## 迭代工作函数
-
-&emsp;&emsp;在模块中,按照我们需要获取不同类型的tag的需要,定义了一些迭代器工作函数。
-
-

+ 11 - 0
docs/kernel/libs/id-allocation.md

@@ -0,0 +1,11 @@
+# ID分配
+
+:::{note}
+本文作者:龙进 <[email protected]>
+
+2024年9月25日
+:::
+
+内核提供了一个名为`IdAllocator`的ID分配器,位于`kernel/crates/ida`中。
+
+它能够分配、释放ID。默认它会自增分配,假如ID大于设定的最大值,它会从最小值开始寻找空闲ID。如果没有空闲的ID,则会分配失败。

+ 1 - 0
docs/kernel/libs/index.rst

@@ -10,4 +10,5 @@
    lib_ui/scm
    lib_ui/textui
    unified-init
+   id-allocation
 

+ 2 - 1
docs/requirements.txt

@@ -1,3 +1,4 @@
 sphinx==5.0.2
 myst-parser==0.18.0
-sphinx-rtd-theme
+sphinx-rtd-theme
+git+https://git.mirrors.dragonos.org.cn/DragonOS-Community/sphinx-multiversion.git@5858b75#egg=sphinx-multiversion

+ 4 - 3
kernel/Cargo.toml

@@ -27,7 +27,7 @@ fatfs-secure = ["fatfs"]
 
 # 运行时依赖项
 [dependencies]
-acpi = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/acpi-rs.git", rev = "fb69243dcf" }
+acpi = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/acpi-rs.git", rev = "282df2af7b" }
 asm_macros = { path = "crates/asm_macros" }
 atomic_enum = "=0.2.0"
 bit_field = "=0.10"
@@ -35,11 +35,11 @@ bitfield-struct = "=0.5.3"
 bitflags = "=1.3.2"
 bitmap = { path = "crates/bitmap" }
 driver_base_macros = { "path" = "crates/driver_base_macros" }
-# 一个no_std的hashmap、hashset
 elf = { version = "=0.7.2", default-features = false }
 fdt = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/fdt", rev = "9862813020" }
+# 一个no_std的hashmap、hashset
 hashbrown = "=0.13.2"
-ida = { path = "src/libs/ida" }
+ida = { path = "crates/ida" }
 intertrait = { path = "crates/intertrait" }
 kdepends = { path = "crates/kdepends" }
 klog_types = { path = "crates/klog_types" }
@@ -63,6 +63,7 @@ lru = "0.12.3"
 # target为x86_64时,使用下面的依赖
 [target.'cfg(target_arch = "x86_64")'.dependencies]
 mini-backtrace = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/mini-backtrace.git", rev = "e0b1d90940" }
+multiboot2 = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/multiboot2", rev = "05739aab40" }
 raw-cpuid = "11.0.1"
 x86 = "=0.52.0"
 x86_64 = "=0.14.10"

+ 2 - 2
kernel/src/libs/ida/Cargo.toml → kernel/crates/ida/Cargo.toml

@@ -3,7 +3,7 @@ name = "ida"
 version = "0.1.0"
 edition = "2021"
 authors = ["longjin <[email protected]>"]
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+description = "一个基于XArray的ID分配器"
 
 [dependencies]
+kdepends = { path = "../kdepends" }

+ 3 - 0
kernel/crates/ida/README.md

@@ -0,0 +1,3 @@
+# IDA
+
+一个基于XArray的ID分配器

+ 210 - 0
kernel/crates/ida/src/lib.rs

@@ -0,0 +1,210 @@
+#![no_std]
+#![feature(core_intrinsics)]
+#![allow(internal_features)]
+#![allow(clippy::needless_return)]
+
+#[cfg(test)]
+#[macro_use]
+extern crate std;
+
+use core::cmp::min;
+use core::intrinsics::unlikely;
+use core::marker::PhantomData;
+use core::ops::Deref;
+
+struct EmptyIdaItemRef<'a> {
+    _marker: PhantomData<&'a EmptyIdaItem>,
+}
+
+impl<'a> Deref for EmptyIdaItemRef<'a> {
+    type Target = EmptyIdaItem;
+
+    fn deref(&self) -> &Self::Target {
+        &EmptyIdaItem
+    }
+}
+
+struct EmptyIdaItem;
+
+unsafe impl kdepends::xarray::ItemEntry for EmptyIdaItem {
+    type Ref<'a> = EmptyIdaItemRef<'a> where Self: 'a;
+
+    fn into_raw(self) -> *const () {
+        core::ptr::null()
+    }
+
+    unsafe fn from_raw(_raw: *const ()) -> Self {
+        EmptyIdaItem
+    }
+
+    unsafe fn raw_as_ref<'a>(_raw: *const ()) -> Self::Ref<'a> {
+        EmptyIdaItemRef {
+            _marker: PhantomData,
+        }
+    }
+}
+/// id分配器
+pub struct IdAllocator {
+    current_id: usize,
+    min_id: usize,
+    max_id: usize,
+    used: usize,
+    xarray: kdepends::xarray::XArray<EmptyIdaItem>,
+}
+
+impl IdAllocator {
+    /// 创建一个新的id分配器
+    pub const fn new(initial_id: usize, max_id: usize) -> Option<Self> {
+        if initial_id >= max_id {
+            return None;
+        }
+        Some(Self {
+            current_id: initial_id,
+            min_id: initial_id,
+            max_id,
+            used: 0,
+            xarray: kdepends::xarray::XArray::new(),
+        })
+    }
+
+    /// 可用的id数量
+    #[inline]
+    pub fn available(&self) -> usize {
+        self.max_id - self.min_id - self.used
+    }
+
+    /// 分配一个新的id
+    ///
+    /// ## 返回
+    ///
+    /// 如果分配成功,返回Some(id),否则返回None
+    pub fn alloc(&mut self) -> Option<usize> {
+        if unlikely(self.available() == 0) {
+            return None;
+        }
+
+        if let Some(try1) = self.do_find_first_free_index(self.current_id, self.max_id) {
+            self.current_id = try1;
+            self.xarray.store(try1 as u64, EmptyIdaItem);
+            self.used += 1;
+            return Some(try1);
+        }
+
+        // 从头开始找
+        if let Some(try2) =
+            self.do_find_first_free_index(self.min_id, min(self.current_id, self.max_id))
+        {
+            self.current_id = try2;
+            self.xarray.store(try2 as u64, EmptyIdaItem);
+            self.used += 1;
+            return Some(try2);
+        }
+        return None;
+    }
+
+    /// 检查id是否存在
+    ///
+    /// ## 参数
+    ///
+    /// - `id`:要检查的id
+    ///
+    /// ## 返回
+    ///
+    /// 如果id存在,返回true,否则返回false
+    pub fn exists(&self, id: usize) -> bool {
+        if id < self.min_id || id >= self.max_id {
+            return false;
+        }
+        self.xarray.load(id as u64).is_some()
+    }
+
+    fn do_find_first_free_index(&self, start_id: usize, end: usize) -> Option<usize> {
+        (start_id..end).find(|&i| !self.exists(i))
+    }
+
+    /// 释放一个id
+    ///
+    /// ## 参数
+    ///
+    /// - `id`:要释放的id
+    pub fn free(&mut self, id: usize) {
+        if id < self.min_id || id >= self.max_id {
+            return;
+        }
+        if self.xarray.remove(id as u64).is_some() {
+            self.used -= 1;
+        }
+    }
+
+    /// 返回已经使用的id数量
+    pub fn used(&self) -> usize {
+        self.used
+    }
+}
+
+impl core::fmt::Debug for IdAllocator {
+    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+        f.debug_struct("IdAllocator")
+            .field("current_id", &self.current_id)
+            .field("min_id", &self.min_id)
+            .field("max_id", &self.max_id)
+            .field("used", &self.used)
+            .field("xarray", &"xarray<()>")
+            .finish()
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    #[test]
+    fn test_new_fail() {
+        assert_eq!(IdAllocator::new(10, 10).is_none(), true);
+        assert_eq!(IdAllocator::new(11, 10).is_none(), true);
+    }
+    #[test]
+    fn test_new_success() {
+        assert_eq!(IdAllocator::new(9, 10).is_some(), true);
+        assert_eq!(IdAllocator::new(0, 10).is_some(), true);
+    }
+
+    #[test]
+    fn test_id_allocator() {
+        let mut ida = IdAllocator::new(0, 10).unwrap();
+        assert_eq!(ida.alloc(), Some(0));
+        assert_eq!(ida.alloc(), Some(1));
+        assert_eq!(ida.alloc(), Some(2));
+        assert_eq!(ida.alloc(), Some(3));
+        assert_eq!(ida.alloc(), Some(4));
+        assert_eq!(ida.alloc(), Some(5));
+        assert_eq!(ida.alloc(), Some(6));
+        assert_eq!(ida.alloc(), Some(7));
+        assert_eq!(ida.alloc(), Some(8));
+        assert_eq!(ida.alloc(), Some(9));
+        assert_eq!(ida.alloc(), None);
+
+        for i in 0..10 {
+            assert_eq!(ida.exists(i), true);
+        }
+
+        ida.free(5);
+
+        for i in 0..10 {
+            if i == 5 {
+                assert_eq!(ida.exists(i), false);
+            } else {
+                assert_eq!(ida.exists(i), true);
+            }
+        }
+        assert_eq!(ida.used(), 9);
+        assert_eq!(ida.alloc(), Some(5));
+        assert_eq!(ida.alloc(), None);
+
+        assert_eq!(ida.used(), 10);
+        for i in 0..10 {
+            ida.free(i);
+        }
+
+        assert_eq!(ida.used(), 0);
+    }
+}

+ 3 - 2
kernel/crates/kdepends/Cargo.toml

@@ -7,9 +7,10 @@ description = "需要导出的依赖项(为保持内核依赖版本与调试
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
-ringbuffer = "0.15.0"
-memoffset = "0.9.0"
 crc = { path = "../crc" }
+memoffset = "0.9.0"
+ringbuffer = "0.15.0"
+xarray = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/xarray", rev = "de93b57c34", features = ["slab-friendly"] }
 
 # 一个无锁MPSC队列
 [dependencies.thingbuf]

+ 1 - 0
kernel/crates/kdepends/src/lib.rs

@@ -7,3 +7,4 @@ pub extern crate memoffset;
 pub extern crate ringbuffer;
 
 pub extern crate crc;
+pub extern crate xarray;

+ 8 - 21
kernel/env.mk

@@ -2,30 +2,17 @@ include ../env.mk
 
 # 设置编译器
 ifeq ($(ARCH), x86_64)
-
-# 如果 x86_64时,DragonOS_GCC 为空,那么设置为默认值
-export DragonOS_GCC?=$(HOME)/opt/dragonos-gcc/gcc-x86_64-unknown-none/bin
-
-export CC=$(DragonOS_GCC)/x86_64-elf-gcc
-export LD=ld
-export AS=$(DragonOS_GCC)/x86_64-elf-as
-export NM=$(DragonOS_GCC)/x86_64-elf-nm
-export AR=$(DragonOS_GCC)/x86_64-elf-ar
-export OBJCOPY=$(DragonOS_GCC)/x86_64-elf-objcopy
-
+CCPREFIX=x86_64-linux-gnu-
 else ifeq ($(ARCH), riscv64)
-
-export CC=riscv64-unknown-elf-gcc
-# binutils版本需要>=2.38
-# 而ubuntu的unknown-elf的版本比较旧,所以使用了riscv64-linux-gnu-ld
-export LD=riscv64-linux-gnu-ld
-export AS=riscv64-unknown-elf-as
-export NM=riscv64-unknown-elf-nm
-export AR=riscv64-unknown-elf-ar
-export OBJCOPY=riscv64-unknown-elf-objcopy
-
+CCPREFIX=riscv64-linux-gnu-
 endif
 
+export CC=$(CCPREFIX)gcc
+export LD=$(CCPREFIX)ld
+export AS=$(CCPREFIX)as
+export NM=$(CCPREFIX)nm
+export AR=$(CCPREFIX)ar
+export OBJCOPY=$(CCPREFIX)objcopy
 
 export DEBUG=DEBUG
 

+ 2 - 2
kernel/src/Makefile

@@ -17,7 +17,7 @@ ifeq ($(UNWIND_ENABLE), yes)
     CFLAGS_UNWIND = -funwind-tables
 ifeq ($(ARCH), x86_64)
     LDFLAGS_UNWIND = --eh-frame-hdr
-    RUSTFLAGS_UNWIND = -Cforce-unwind-tables -Clink-arg=-Wl,eh_frame.ld 
+    RUSTFLAGS_UNWIND = -Cforce-unwind-tables -Clink-arg=-Wl,eh_frame.ld
 endif
 endif
 
@@ -36,7 +36,7 @@ export ASFLAGS := --64
 LD_LIST := ""
 
 
-kernel_subdirs := common driver debug syscall libs
+kernel_subdirs := debug
 
 
 kernel_rust:

+ 3 - 1
kernel/src/arch/riscv64/driver/sbi.rs

@@ -1,3 +1,5 @@
+use core::ptr::addr_of;
+
 /// 向控制台打印字符串。
 ///
 /// 该函数接受一个字节切片 `s` 作为输入,并迭代切片中的每个字节 `c`。
@@ -75,7 +77,7 @@ impl SbiDriver {
 
     /// 获取probe得到的SBI扩展信息。
     pub fn extensions() -> &'static SBIExtensions {
-        unsafe { &EXTENSIONS }
+        unsafe { addr_of!(EXTENSIONS).as_ref().unwrap() }
     }
 
     fn probe_extensions() -> SBIExtensions {

+ 15 - 0
kernel/src/arch/riscv64/init/boot.rs

@@ -0,0 +1,15 @@
+use system_error::SystemError;
+
+use super::dragonstub::early_dragonstub_init;
+
+#[derive(Debug)]
+#[repr(u64)]
+pub(super) enum BootProtocol {
+    DragonStub = 1,
+}
+
+pub(super) fn early_boot_init(protocol: BootProtocol) -> Result<(), SystemError> {
+    match protocol {
+        BootProtocol::DragonStub => early_dragonstub_init(),
+    }
+}

+ 41 - 0
kernel/src/arch/riscv64/init/dragonstub.rs

@@ -0,0 +1,41 @@
+use alloc::string::String;
+use system_error::SystemError;
+
+use crate::{
+    driver::video::fbdev::base::BootTimeScreenInfo,
+    init::boot::{register_boot_callbacks, BootCallbacks, BootloaderAcpiArg},
+};
+
+pub(super) fn early_dragonstub_init() -> Result<(), SystemError> {
+    register_boot_callbacks(&DragonStubCallBack);
+    Ok(())
+}
+
+struct DragonStubCallBack;
+
+impl BootCallbacks for DragonStubCallBack {
+    fn init_bootloader_name(&self) -> Result<Option<String>, SystemError> {
+        Ok(format!("DragonStub").into())
+    }
+
+    fn init_acpi_args(&self) -> Result<BootloaderAcpiArg, SystemError> {
+        Ok(BootloaderAcpiArg::NotProvided)
+    }
+
+    fn init_kernel_cmdline(&self) -> Result<(), SystemError> {
+        // parsed in `early_init_scan_chosen()`
+        Ok(())
+    }
+
+    fn early_init_framebuffer_info(
+        &self,
+        _scinfo: &mut BootTimeScreenInfo,
+    ) -> Result<(), SystemError> {
+        unimplemented!("dragonstub early_init_framebuffer_info")
+    }
+
+    fn early_init_memory_blocks(&self) -> Result<(), SystemError> {
+        // parsed in `early_init_scan_memory()` and uefi driver
+        Ok(())
+    }
+}

+ 9 - 1
kernel/src/arch/riscv64/init/mod.rs

@@ -3,7 +3,11 @@ use log::{debug, info};
 use system_error::SystemError;
 
 use crate::{
-    arch::{driver::sbi::SbiDriver, mm::init::mm_early_init},
+    arch::{
+        driver::sbi::SbiDriver,
+        init::boot::{early_boot_init, BootProtocol},
+        mm::init::mm_early_init,
+    },
     driver::{firmware::efi::init::efi_init, open_firmware::fdt::open_firmware_fdt_driver},
     init::{boot_params, init::start_kernel},
     mm::{memblock::mem_block_manager, PhysAddr, VirtAddr},
@@ -13,6 +17,9 @@ use crate::{
 
 use super::{cpu::init_local_context, interrupt::entry::handle_exception};
 
+mod boot;
+mod dragonstub;
+
 #[derive(Debug)]
 pub struct ArchBootParams {
     /// 启动时的fdt物理地址
@@ -119,6 +126,7 @@ pub fn early_setup_arch() -> Result<(), SystemError> {
         "DragonOS kernel is running on hart {}, fdt address:{:?}",
         hartid, fdt_paddr
     );
+    early_boot_init(BootProtocol::DragonStub).expect("Failed to init boot protocol!");
     mm_early_init();
 
     print_node(fdt.find_node("/").unwrap(), 0);

+ 11 - 1
kernel/src/arch/riscv64/rand.rs

@@ -1,3 +1,13 @@
 pub fn rand() -> usize {
-    unimplemented!("RiscV64 rand");
+    static mut SEED: u64 = 0xdead_beef_cafe_babe;
+    let mut buf = [0u8; size_of::<usize>()];
+    for x in buf.iter_mut() {
+        unsafe {
+            // from musl
+            SEED = SEED.wrapping_mul(0x5851_f42d_4c95_7f2d);
+            *x = (SEED >> 33) as u8;
+        }
+    }
+    let x: usize = unsafe { core::mem::transmute(buf) };
+    return x;
 }

+ 152 - 81
kernel/src/arch/x86_64/asm/head.S

@@ -7,71 +7,79 @@
 
 // 以下是来自 multiboot2 规范的定义
 //  How many bytes from the start of the file we search for the header.
-#define MULTIBOOT_SEARCH 32768
-#define MULTIBOOT_HEADER_ALIGN 8
+#define MULTIBOOT2_SEARCH 32768
+#define MULTIBOOT2_HEADER_ALIGN 8
 
 //  The magic field should contain this.
 #define MULTIBOOT2_HEADER_MAGIC 0xe85250d6
 
-//  This should be in %eax.
-#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289
+
 
 //  Alignment of multiboot modules.
-#define MULTIBOOT_MOD_ALIGN 0x00001000
+#define MULTIBOOT2_MOD_ALIGN 0x00001000
 
 //  Alignment of the multiboot info structure.
-#define MULTIBOOT_INFO_ALIGN 0x00000008
+#define MULTIBOOT2_INFO_ALIGN 0x00000008
 
 //  Flags set in the 'flags' member of the multiboot header.
 
-#define MULTIBOOT_TAG_ALIGN 8
-#define MULTIBOOT_TAG_TYPE_END 0
-#define MULTIBOOT_TAG_TYPE_CMDLINE 1
-#define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME 2
-#define MULTIBOOT_TAG_TYPE_MODULE 3
-#define MULTIBOOT_TAG_TYPE_BASIC_MEMINFO 4
-#define MULTIBOOT_TAG_TYPE_BOOTDEV 5
-#define MULTIBOOT_TAG_TYPE_MMAP 6
-#define MULTIBOOT_TAG_TYPE_VBE 7
-#define MULTIBOOT_TAG_TYPE_FRAMEBUFFER 8
-#define MULTIBOOT_TAG_TYPE_ELF_SECTIONS 9
-#define MULTIBOOT_TAG_TYPE_APM 10
-#define MULTIBOOT_TAG_TYPE_EFI32 11
-#define MULTIBOOT_TAG_TYPE_EFI64 12
-#define MULTIBOOT_TAG_TYPE_SMBIOS 13
-#define MULTIBOOT_TAG_TYPE_ACPI_OLD 14
-#define MULTIBOOT_TAG_TYPE_ACPI_NEW 15
-#define MULTIBOOT_TAG_TYPE_NETWORK 16
-#define MULTIBOOT_TAG_TYPE_EFI_MMAP 17
-#define MULTIBOOT_TAG_TYPE_EFI_BS 18
-#define MULTIBOOT_TAG_TYPE_EFI32_IH 19
-#define MULTIBOOT_TAG_TYPE_EFI64_IH 20
-#define MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR 21
-
-#define MULTIBOOT_HEADER_TAG_END 0
-#define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST 1
-#define MULTIBOOT_HEADER_TAG_ADDRESS 2
-#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS 3
-#define MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS 4
-#define MULTIBOOT_HEADER_TAG_FRAMEBUFFER 5
-#define MULTIBOOT_HEADER_TAG_MODULE_ALIGN 6
-#define MULTIBOOT_HEADER_TAG_EFI_BS 7
-#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI32 8
-#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 9
-#define MULTIBOOT_HEADER_TAG_RELOCATABLE 10
-
-#define MULTIBOOT_ARCHITECTURE_I386 0
-#define MULTIBOOT_ARCHITECTURE_MIPS32 4
-#define MULTIBOOT_HEADER_TAG_OPTIONAL 1
-
-#define MULTIBOOT_LOAD_PREFERENCE_NONE 0
-#define MULTIBOOT_LOAD_PREFERENCE_LOW 1
-#define MULTIBOOT_LOAD_PREFERENCE_HIGH 2
-
-#define MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED 1
-#define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2
+#define MULTIBOOT2_TAG_ALIGN 8
+#define MULTIBOOT2_TAG_TYPE_END 0
+#define MULTIBOOT2_TAG_TYPE_CMDLINE 1
+#define MULTIBOOT2_TAG_TYPE_BOOT_LOADER_NAME 2
+#define MULTIBOOT2_TAG_TYPE_MODULE 3
+#define MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO 4
+#define MULTIBOOT2_TAG_TYPE_BOOTDEV 5
+#define MULTIBOOT2_TAG_TYPE_MMAP 6
+#define MULTIBOOT2_TAG_TYPE_VBE 7
+#define MULTIBOOT2_TAG_TYPE_FRAMEBUFFER 8
+#define MULTIBOOT2_TAG_TYPE_ELF_SECTIONS 9
+#define MULTIBOOT2_TAG_TYPE_APM 10
+#define MULTIBOOT2_TAG_TYPE_EFI32 11
+#define MULTIBOOT2_TAG_TYPE_EFI64 12
+#define MULTIBOOT2_TAG_TYPE_SMBIOS 13
+#define MULTIBOOT2_TAG_TYPE_ACPI_OLD 14
+#define MULTIBOOT2_TAG_TYPE_ACPI_NEW 15
+#define MULTIBOOT2_TAG_TYPE_NETWORK 16
+#define MULTIBOOT2_TAG_TYPE_EFI_MMAP 17
+#define MULTIBOOT2_TAG_TYPE_EFI_BS 18
+#define MULTIBOOT2_TAG_TYPE_EFI32_IH 19
+#define MULTIBOOT2_TAG_TYPE_EFI64_IH 20
+#define MULTIBOOT2_TAG_TYPE_LOAD_BASE_ADDR 21
+
+#define MULTIBOOT2_HEADER_TAG_END 0
+#define MULTIBOOT2_HEADER_TAG_INFORMATION_REQUEST 1
+#define MULTIBOOT2_HEADER_TAG_ADDRESS 2
+#define MULTIBOOT2_HEADER_TAG_ENTRY_ADDRESS 3
+#define MULTIBOOT2_HEADER_TAG_CONSOLE_FLAGS 4
+#define MULTIBOOT2_HEADER_TAG_FRAMEBUFFER 5
+#define MULTIBOOT2_HEADER_TAG_MODULE_ALIGN 6
+#define MULTIBOOT2_HEADER_TAG_EFI_BS 7
+#define MULTIBOOT2_HEADER_TAG_ENTRY_ADDRESS_EFI32 8
+#define MULTIBOOT2_HEADER_TAG_ENTRY_ADDRESS_EFI64 9
+#define MULTIBOOT2_HEADER_TAG_RELOCATABLE 10
+
+#define MULTIBOOT2_ARCHITECTURE_I386 0
+#define MULTIBOOT2_ARCHITECTURE_MIPS32 4
+#define MULTIBOOT2_HEADER_TAG_OPTIONAL 1
+
+#define MULTIBOOT2_LOAD_PREFERENCE_NONE 0
+#define MULTIBOOT2_LOAD_PREFERENCE_LOW 1
+#define MULTIBOOT2_LOAD_PREFERENCE_HIGH 2
+
+#define MULTIBOOT2_CONSOLE_FLAGS_CONSOLE_REQUIRED 1
+#define MULTIBOOT2_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2
 
+//  This should be in %eax.
+#define MULTIBOOT_BOOTLOADER_MAGIC 0x2badb002
+#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289
 
+// 存储到boot_entry_type的值
+#define BOOT_ENTRY_TYPE_MULTIBOOT 1
+#define BOOT_ENTRY_TYPE_MULTIBOOT2  2
+#define BOOT_ENTRY_TYPE_LINUX_32  3
+#define BOOT_ENTRY_TYPE_LINUX_64  4
+#define BOOT_ENTRY_TYPE_LINUX_32_PVH 5
 
 // 直接用 -m64 编译出来的是 64 位代码,
 // 但是启动后的机器是 32 位的,相当于在 32 位机器上跑 64 位程序。
@@ -85,49 +93,89 @@
 // 声明这一段代码以 32 位模式编译
 .code32
 
+/* PVH Header with pvh_start_addr = __linux32_pvh_boot */
+
+	.pushsection .note.dragonos, "a", @note
+	.align 4
+	.long 2f - 1f
+	.long 4f - 3f
+	.long 18
+	1:.asciz "Xen"
+	2:.align 4
+	3:.long __linux32_pvh_boot
+	4:.align 4
+	.popsection
+
+.section ".multiboot_header", "a"
+
+#define MB_FLAGS_FB 0x4
+
+// reference: https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#Header-graphics-fields
+#define MB_HEADER_GRAPHIC_MODE_LINEAR 0
+#define MB_HEADER_GRAPHIC_MODE_TEXT 1
+
+MB_MAGIC = 0x1BADB002
+MB_FLAGS = MB_FLAGS_FB
+MB_CHECKSUM = -(MB_MAGIC + MB_FLAGS)
+
+
 // multiboot2 文件头
 // 计算头长度
-.SET HEADER_LENGTH, multiboot_header_end - multiboot_header
+.SET MB2_HEADER_LENGTH, multiboot2_header_end - multiboot2_header
 // 计算校验和
-.SET CHECKSUM, -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE_I386 + HEADER_LENGTH)
+.SET MB2_CHECKSUM, -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT2_ARCHITECTURE_I386 + MB2_HEADER_LENGTH)
 // 8 字节对齐
-.section .multiboot_header
-.align MULTIBOOT_HEADER_ALIGN
+.code32
+.section .multiboot2_header
+.align MULTIBOOT2_HEADER_ALIGN
 // 声明所属段
 
-multiboot_header:
+multiboot2_header:
     // 魔数
     .long MULTIBOOT2_HEADER_MAGIC
     // 架构
-    .long MULTIBOOT_ARCHITECTURE_I386
+    .long MULTIBOOT2_ARCHITECTURE_I386
     // 头长度
-    .long HEADER_LENGTH
+    .long MB2_HEADER_LENGTH
     // 校验和
-    .long CHECKSUM
+    .long MB2_CHECKSUM
     // 添加其它内容在此,详细信息见 Multiboot2 Specification version 2.0.pdf
 
 // 设置帧缓冲区(同时在这里设置qemu的分辨率, 默认为: 1440*900, 还支持: 640*480, 等)
 .align 8
 framebuffer_tag_start:
-    .short MULTIBOOT_HEADER_TAG_FRAMEBUFFER
-    .short MULTIBOOT_HEADER_TAG_OPTIONAL
+    .short MULTIBOOT2_HEADER_TAG_FRAMEBUFFER
+    .short MULTIBOOT2_HEADER_TAG_OPTIONAL
     .long framebuffer_tag_end - framebuffer_tag_start
     .long 1440   // 宽
     .long 900   // 高
     .long 32
 framebuffer_tag_end:
 .align 8
-	.short MULTIBOOT_HEADER_TAG_END
+	.short MULTIBOOT2_HEADER_TAG_END
     // 结束标记
     .short 0
     .long 8
-multiboot_header_end:
+multiboot2_header_end:
+
+// direct_linux32_boot启动的内核入口
+.section .bootstrap, "a"
+.code32
+.global __linux32_pvh_boot
+__linux32_pvh_boot:
+    cli
+    cld
+    // start info 指针
+    mov %ebx, mb_entry_info
+    mov $BOOT_ENTRY_TYPE_LINUX_32_PVH, %ebx
+    mov %ebx, boot_entry_type
+    jmp protected_mode_setup
+
+.code32
 
-.section .bootstrap
 
 .global _start
 .type _start, @function
-# 在 multiboot2.cpp 中定义
 
 .extern _start64
 .extern boot_info_addr
@@ -135,13 +183,31 @@ multiboot_header_end:
 ENTRY(_start)
     // 关中断
     cli
-    
-    // multiboot2_info 结构体指针
-    mov %ebx, mb2_info
-    //mov %ebx, %e8
-    // 魔数
-    mov %eax, mb2_magic
 
+    // multiboot2_info/ multiboot_info 结构体指针
+    mov %ebx, mb_entry_info
+    //mov %ebx, %e8
+    // multiboot魔数
+    mov %eax, mb_entry_magic
+
+    mov $MULTIBOOT_BOOTLOADER_MAGIC, %ebx
+    cmp %eax, %ebx
+    je bl_magic_is_mb
+    mov $MULTIBOOT2_BOOTLOADER_MAGIC, %ebx
+    cmp %eax, %ebx
+    je bl_magic_is_mb2
+    jmp halt // unreachable
+
+bl_magic_is_mb:
+    mov $BOOT_ENTRY_TYPE_MULTIBOOT, %ebx
+    mov %ebx, boot_entry_type
+    jmp protected_mode_setup
+bl_magic_is_mb2:
+    mov $BOOT_ENTRY_TYPE_MULTIBOOT2, %ebx
+    mov %ebx, boot_entry_type
+    jmp protected_mode_setup
+
+protected_mode_setup:
     //mov %eax, %e9
     / 从保护模式跳转到长模式
     // 1. 允许 PAE
@@ -225,16 +291,16 @@ switch_to_start64:
 
 
 .code64
-is_from_ap:
-    
+halt:
+    cli
     hlt
+    jmp halt
 
 .global _start64
 .type _start64, @function
 .extern Start_Kernel
 ENTRY(_start64)
 
-
     // 初始化寄存器
     mov $0x10, %ax
     mov %ax, %ds
@@ -307,7 +373,7 @@ ENTRY(_start64)
     add $8, %eax
     loop .fill_pt_64_2
 
-
+    
 
 // ==== 加载CR3寄存器
 
@@ -316,6 +382,7 @@ load_cr3:
     movq $__PML4E, %rax //设置页目录基地址
     
     movq %rax, %cr3
+    
     jmp to_switch_seg
 
 load_apu_cr3:
@@ -329,11 +396,12 @@ load_apu_cr3:
     jmp to_switch_seg
 
 to_switch_seg:
-
+    
     movq switch_seg(%rip), %rax
     // 由于ljmp和lcall在GAS中不受支持,因此我们需要先伪造函数调用现场,通过lret的方式,给它跳转过去。才能更新cs寄存器
     // 实在是太妙了!Amazing!
     pushq $0x08 //段选择子
+
     pushq %rax
     lretq
 
@@ -435,10 +503,11 @@ repeat_set_idt:
 
     
     // 传参
-    movq mb2_info, %rdi
-    movq mb2_magic, %rsi
+    movq mb_entry_info, %rdi
+    movq mb_entry_magic, %rsi
     movq %r13, %rdx // GDT size
     movq %r12, %r10 // IDT size
+    movq boot_entry_type, %r8
 
 	lretq
 
@@ -573,8 +642,10 @@ IDT_BASE64: .quad IDT_Table + 0xffff800000000000
 
 
 .section .bootstrap.data
-mb2_magic: .quad 0
-mb2_info: .quad 0
+mb_entry_magic: .quad 0
+mb_entry_info: .quad 0
+// 引导协议类型
+boot_entry_type: .quad 0
 
 .code32
 // 临时页表 4KB/页

+ 1 - 1
kernel/src/arch/x86_64/driver/apic/ioapic.rs

@@ -403,7 +403,7 @@ pub fn ioapic_init(ignore: &'static [IrqNumber]) {
     }
 
     // 绑定irqchip
-    for i in 32..256 {
+    for i in IoApic::VECTOR_BASE as u32..256 {
         let irq = IrqNumber::new(i);
 
         if ignore.contains(&irq) {

+ 8 - 0
kernel/src/arch/x86_64/driver/rtc.rs

@@ -163,6 +163,14 @@ impl Device for CmosRtcDevice {
     fn bus(&self) -> Option<Weak<dyn Bus>> {
         self.inner().device_common.get_bus_weak_or_clear()
     }
+
+    fn dev_parent(&self) -> Option<Weak<dyn Device>> {
+        self.inner().device_common.get_parent_weak_or_clear()
+    }
+
+    fn set_dev_parent(&self, parent: Option<Weak<dyn Device>>) {
+        self.inner().device_common.parent = parent;
+    }
 }
 
 impl KObject for CmosRtcDevice {

+ 52 - 0
kernel/src/arch/x86_64/init/boot.rs

@@ -0,0 +1,52 @@
+use core::hint::spin_loop;
+
+use system_error::SystemError;
+
+use super::{multiboot2::early_multiboot2_init, pvh::early_linux32_pvh_init};
+
+const BOOT_ENTRY_TYPE_MULTIBOOT: u64 = 1;
+const BOOT_ENTRY_TYPE_MULTIBOOT2: u64 = 2;
+const BOOT_ENTRY_TYPE_LINUX_32: u64 = 3;
+const BOOT_ENTRY_TYPE_LINUX_64: u64 = 4;
+const BOOT_ENTRY_TYPE_LINUX_32_PVH: u64 = 5;
+
+#[derive(Debug)]
+#[repr(u64)]
+enum BootProtocol {
+    Multiboot = 1,
+    Multiboot2,
+    Linux32,
+    Linux64,
+    Linux32Pvh,
+}
+
+impl TryFrom<u64> for BootProtocol {
+    type Error = SystemError;
+
+    fn try_from(value: u64) -> Result<Self, Self::Error> {
+        match value {
+            BOOT_ENTRY_TYPE_MULTIBOOT => Ok(BootProtocol::Multiboot),
+            BOOT_ENTRY_TYPE_MULTIBOOT2 => Ok(BootProtocol::Multiboot2),
+            BOOT_ENTRY_TYPE_LINUX_32 => Ok(BootProtocol::Linux32),
+            BOOT_ENTRY_TYPE_LINUX_64 => Ok(BootProtocol::Linux64),
+            BOOT_ENTRY_TYPE_LINUX_32_PVH => Ok(BootProtocol::Linux32Pvh),
+            _ => Err(SystemError::EINVAL),
+        }
+    }
+}
+
+#[inline(never)]
+pub(super) fn early_boot_init(
+    boot_entry_type: u64,
+    arg1: u64,
+    arg2: u64,
+) -> Result<(), SystemError> {
+    let boot_protocol = BootProtocol::try_from(boot_entry_type)?;
+    match boot_protocol {
+        BootProtocol::Multiboot2 => early_multiboot2_init(arg1 as u32, arg2),
+        BootProtocol::Linux32 | BootProtocol::Linux64 | BootProtocol::Multiboot => loop {
+            spin_loop();
+        },
+        BootProtocol::Linux32Pvh => early_linux32_pvh_init(arg2 as usize),
+    }
+}

+ 16 - 3
kernel/src/arch/x86_64/init/mod.rs

@@ -1,4 +1,7 @@
-use core::sync::atomic::{compiler_fence, Ordering};
+use core::{
+    hint::spin_loop,
+    sync::atomic::{compiler_fence, Ordering},
+};
 
 use log::debug;
 use system_error::SystemError;
@@ -11,6 +14,8 @@ use crate::{
     mm::{MemoryManagementArch, PhysAddr},
 };
 
+use self::boot::early_boot_init;
+
 use super::{
     driver::{
         hpet::{hpet_init, hpet_instance},
@@ -19,6 +24,10 @@ use super::{
     MMArch,
 };
 
+mod boot;
+mod multiboot2;
+mod pvh;
+
 #[derive(Debug)]
 pub struct ArchBootParams {}
 
@@ -31,7 +40,6 @@ extern "C" {
     static mut IDT_Table: [usize; 0usize];
     fn head_stack_start();
 
-    fn multiboot2_init(mb2_info: u64, mb2_magic: u32) -> bool;
 }
 
 #[no_mangle]
@@ -41,6 +49,7 @@ unsafe extern "C" fn kernel_main(
     mb2_magic: u64,
     bsp_gdt_size: u64,
     bsp_idt_size: u64,
+    boot_entry_type: u64,
 ) -> ! {
     let mut gdtp = DescriptorTablePointer::<usize>::default();
     let gdt_vaddr =
@@ -59,7 +68,11 @@ unsafe extern "C" fn kernel_main(
     x86::dtables::lidt(&idtp);
 
     compiler_fence(Ordering::SeqCst);
-    multiboot2_init(mb2_info, (mb2_magic & 0xFFFF_FFFF) as u32);
+    if early_boot_init(boot_entry_type, mb2_magic, mb2_info).is_err() {
+        loop {
+            spin_loop();
+        }
+    }
     compiler_fence(Ordering::SeqCst);
 
     start_kernel();

+ 248 - 0
kernel/src/arch/x86_64/init/multiboot2.rs

@@ -0,0 +1,248 @@
+use core::hint::spin_loop;
+
+use acpi::rsdp::Rsdp;
+use alloc::string::{String, ToString};
+use multiboot2::{BootInformation, BootInformationHeader, MemoryAreaType, RsdpV1Tag};
+use system_error::SystemError;
+
+use crate::{
+    arch::mm::x86_64_set_kernel_load_base_paddr,
+    driver::{
+        serial::serial8250::send_to_default_serial8250_port,
+        video::fbdev::{
+            base::{BootTimeScreenInfo, BootTimeVideoType},
+            vesafb::vesafb_early_map,
+        },
+    },
+    init::{
+        boot::{register_boot_callbacks, BootCallbacks, BootloaderAcpiArg},
+        boot_params,
+    },
+    libs::lazy_init::Lazy,
+    mm::{memblock::mem_block_manager, PhysAddr},
+};
+
+pub(super) const MULTIBOOT2_ENTRY_MAGIC: u32 = multiboot2::MAGIC;
+static MB2_INFO: Lazy<BootInformation> = Lazy::new();
+const MB2_RAW_INFO_MAX_SIZE: usize = 4096;
+
+static mut MB2_RAW_INFO: [u8; MB2_RAW_INFO_MAX_SIZE] = [0u8; MB2_RAW_INFO_MAX_SIZE];
+
+fn mb2_rsdp_v1_tag_to_rsdp_struct(tag: &RsdpV1Tag) -> Rsdp {
+    Rsdp {
+        signature: tag.signature,
+        checksum: tag.checksum,
+        oem_id: tag.oem_id,
+        revision: tag.revision,
+        rsdt_address: tag.rsdt_address,
+        length: 0,
+        xsdt_address: 0,
+        ext_checksum: 0,
+        reserved: [0u8; 3],
+    }
+}
+
+fn mb2_rsdp_v2_tag_to_rsdp_struct(tag: &multiboot2::RsdpV2Tag) -> Rsdp {
+    Rsdp {
+        signature: tag.signature,
+        checksum: tag.checksum,
+        oem_id: tag.oem_id,
+        revision: tag.revision,
+        rsdt_address: tag.rsdt_address,
+        length: tag.length,
+        xsdt_address: tag.xsdt_address,
+        ext_checksum: tag.ext_checksum,
+        reserved: tag._reserved,
+    }
+}
+struct Mb2Callback;
+
+impl BootCallbacks for Mb2Callback {
+    fn init_bootloader_name(&self) -> Result<Option<String>, SystemError> {
+        let name = MB2_INFO
+            .get()
+            .boot_loader_name_tag()
+            .expect("MB2: Bootloader name tag not found!")
+            .name()
+            .expect("Failed to parse bootloader name!")
+            .to_string();
+        Ok(Some(name))
+    }
+
+    fn init_acpi_args(&self) -> Result<BootloaderAcpiArg, SystemError> {
+        if let Some(v1_tag) = MB2_INFO.get().rsdp_v1_tag() {
+            Ok(BootloaderAcpiArg::Rsdt(mb2_rsdp_v1_tag_to_rsdp_struct(
+                v1_tag,
+            )))
+        } else if let Some(v2_tag) = MB2_INFO.get().rsdp_v2_tag() {
+            Ok(BootloaderAcpiArg::Xsdt(mb2_rsdp_v2_tag_to_rsdp_struct(
+                v2_tag,
+            )))
+        } else {
+            Ok(BootloaderAcpiArg::NotProvided)
+        }
+    }
+
+    fn init_kernel_cmdline(&self) -> Result<(), SystemError> {
+        let cmdline = MB2_INFO
+            .get()
+            .command_line_tag()
+            .expect("Mb2: Command line tag not found!")
+            .cmdline()
+            .expect("Mb2: Failed to parse command line!");
+        boot_params()
+            .write_irqsave()
+            .boot_cmdline_append(cmdline.as_bytes());
+        Ok(())
+    }
+
+    fn early_init_framebuffer_info(
+        &self,
+        scinfo: &mut BootTimeScreenInfo,
+    ) -> Result<(), SystemError> {
+        let Some(Ok(fb_tag)) = MB2_INFO.get().framebuffer_tag() else {
+            return Err(SystemError::ENODEV);
+        };
+        let width = fb_tag.width();
+        let height = fb_tag.height();
+        scinfo.is_vga = true;
+        scinfo.lfb_base = PhysAddr::new(fb_tag.address() as usize);
+
+        let fb_type = fb_tag.buffer_type().unwrap();
+        match fb_type {
+            multiboot2::FramebufferType::Indexed { palette: _ } => todo!(),
+            multiboot2::FramebufferType::RGB { red, green, blue } => {
+                scinfo.lfb_width = width;
+                scinfo.lfb_height = height;
+                scinfo.video_type = BootTimeVideoType::Vlfb;
+                scinfo.lfb_depth = fb_tag.bpp();
+                scinfo.red_pos = red.position;
+                scinfo.red_size = red.size;
+                scinfo.green_pos = green.position;
+                scinfo.green_size = green.size;
+                scinfo.blue_pos = blue.position;
+                scinfo.blue_size = blue.size;
+            }
+            multiboot2::FramebufferType::Text => {
+                scinfo.origin_video_cols = width as u8;
+                scinfo.origin_video_lines = height as u8;
+                scinfo.video_type = BootTimeVideoType::Mda;
+                scinfo.lfb_depth = 8;
+            }
+        };
+
+        scinfo.lfb_size = (width * height * ((scinfo.lfb_depth as u32 + 7) / 8)) as usize;
+
+        scinfo.lfb_virt_base = Some(vesafb_early_map(scinfo.lfb_base, scinfo.lfb_size)?);
+
+        return Ok(());
+    }
+
+    fn early_init_memory_blocks(&self) -> Result<(), SystemError> {
+        let mb2_info = MB2_INFO.get();
+        send_to_default_serial8250_port("init_memory_area_from_multiboot2\n\0".as_bytes());
+
+        let mem_regions_tag = mb2_info
+            .memory_map_tag()
+            .expect("MB2: Memory map tag not found!");
+        let mut total_mem_size = 0usize;
+        let mut usable_mem_size = 0usize;
+        for region in mem_regions_tag.memory_areas() {
+            let start = PhysAddr::new(region.start_address() as usize);
+            let size = region.size() as usize;
+            let area_typ = MemoryAreaType::from(region.typ());
+            total_mem_size += size;
+
+            match area_typ {
+                MemoryAreaType::Available => {
+                    usable_mem_size += size;
+                    mem_block_manager()
+                        .add_block(start, size)
+                        .unwrap_or_else(|e| {
+                            log::warn!(
+                                "Failed to add memory block: base={:?}, size={:#x}, error={:?}",
+                                start,
+                                size,
+                                e
+                            );
+                        });
+                }
+
+                _ => {
+                    mem_block_manager()
+                        .reserve_block(start, size)
+                        .unwrap_or_else(|e| {
+                            log::warn!(
+                                "Failed to reserve memory block: base={:?}, size={:#x}, error={:?}",
+                                start,
+                                size,
+                                e
+                            );
+                        });
+                }
+            }
+        }
+        send_to_default_serial8250_port("init_memory_area_from_multiboot2 end\n\0".as_bytes());
+        log::info!(
+            "Total memory size: {:#x}, Usable memory size: {:#x}",
+            total_mem_size,
+            usable_mem_size
+        );
+
+        // Add the boot module region since Grub does not specify it.
+        let mb2_module_tag = mb2_info.module_tags();
+        for module in mb2_module_tag {
+            let start = PhysAddr::new(module.start_address() as usize);
+            let size = module.module_size() as usize;
+            mem_block_manager()
+                .reserve_block(start, size)
+                .unwrap_or_else(|e| {
+                    log::warn!(
+                        "Failed to reserve memory block for mb2 modules: base={:?}, size={:#x}, error={:?}",
+                        start,
+                        size,
+                        e
+                    );
+                });
+        }
+
+        // setup kernel load base
+        self.setup_kernel_load_base();
+
+        Ok(())
+    }
+}
+
+impl Mb2Callback {
+    fn setup_kernel_load_base(&self) {
+        let mb2_info = MB2_INFO.get();
+        let kernel_start = mb2_info
+            .load_base_addr_tag()
+            .expect("MB2: Load base address tag not found!")
+            .load_base_addr();
+        let loadbase = PhysAddr::new(kernel_start as usize);
+        x86_64_set_kernel_load_base_paddr(loadbase);
+    }
+}
+pub(super) fn early_multiboot2_init(boot_magic: u32, boot_info: u64) -> Result<(), SystemError> {
+    assert_eq!(boot_magic, MULTIBOOT2_ENTRY_MAGIC);
+    let bi_ptr = boot_info as usize as *const BootInformationHeader;
+    let bi_size = unsafe { (*bi_ptr).total_size() as usize };
+    assert!(bi_size <= MB2_RAW_INFO_MAX_SIZE);
+    unsafe {
+        core::ptr::copy_nonoverlapping(bi_ptr as *const u8, MB2_RAW_INFO.as_mut_ptr(), bi_size);
+    }
+
+    let boot_info =
+        unsafe { BootInformation::load(MB2_RAW_INFO.as_mut_ptr() as *const BootInformationHeader) }
+            .inspect_err(|_| loop {
+                spin_loop();
+            })
+            .unwrap();
+
+    MB2_INFO.init(boot_info);
+
+    register_boot_callbacks(&Mb2Callback);
+
+    return Ok(());
+}

+ 142 - 0
kernel/src/arch/x86_64/init/pvh/mod.rs

@@ -0,0 +1,142 @@
+//! x86/HVM启动
+//!
+//! 初始化代码可参考:https://code.dragonos.org.cn/xref/linux-6.6.21/arch/x86/platform/pvh/enlighten.c#45
+use alloc::string::{String, ToString};
+use core::{ffi::CStr, hint::spin_loop};
+use param::{E820Type, HvmMemmapTableEntry, HvmStartInfo};
+use system_error::SystemError;
+
+use crate::{
+    arch::MMArch,
+    driver::{
+        serial::serial8250::send_to_default_serial8250_port, video::fbdev::base::BootTimeScreenInfo,
+    },
+    init::{
+        boot::{register_boot_callbacks, BootCallbacks, BootloaderAcpiArg},
+        boot_params,
+    },
+    libs::lazy_init::Lazy,
+    mm::{memblock::mem_block_manager, MemoryManagementArch, PhysAddr},
+};
+
+mod param;
+
+static START_INFO: Lazy<HvmStartInfo> = Lazy::new();
+
+struct PvhBootCallback;
+
+impl BootCallbacks for PvhBootCallback {
+    fn init_bootloader_name(&self) -> Result<Option<String>, SystemError> {
+        return Ok(Some("x86 PVH".to_string()));
+    }
+
+    fn init_acpi_args(&self) -> Result<BootloaderAcpiArg, SystemError> {
+        let rsdp_paddr = PhysAddr::new(START_INFO.get().rsdp_paddr as usize);
+        if rsdp_paddr.data() != 0 {
+            Ok(BootloaderAcpiArg::Rsdp(rsdp_paddr))
+        } else {
+            Ok(BootloaderAcpiArg::NotProvided)
+        }
+    }
+
+    fn init_kernel_cmdline(&self) -> Result<(), SystemError> {
+        let cmdline_c_str: &CStr = unsafe {
+            CStr::from_ptr(
+                MMArch::phys_2_virt(PhysAddr::new(START_INFO.get().cmdline_paddr as usize))
+                    .unwrap()
+                    .data() as *const i8,
+            )
+        };
+        let cmdline = cmdline_c_str.to_str().unwrap();
+        boot_params()
+            .write_irqsave()
+            .boot_cmdline_append(cmdline.as_bytes());
+        log::info!("pvh boot cmdline: {:?}", cmdline_c_str);
+        Ok(())
+    }
+
+    fn early_init_framebuffer_info(
+        &self,
+        _scinfo: &mut BootTimeScreenInfo,
+    ) -> Result<(), SystemError> {
+        return Err(SystemError::ENODEV);
+    }
+
+    fn early_init_memory_blocks(&self) -> Result<(), SystemError> {
+        let start_info = START_INFO.get();
+        let mut total_mem_size = 0usize;
+        let mut usable_mem_size = 0usize;
+        send_to_default_serial8250_port("init_memory_area by pvh boot\n\0".as_bytes());
+
+        if (start_info.version > 0) && start_info.memmap_entries > 0 {
+            let mut ep = unsafe {
+                MMArch::phys_2_virt(PhysAddr::new(start_info.memmap_paddr as usize)).unwrap()
+            }
+            .data() as *const HvmMemmapTableEntry;
+
+            for _ in 0..start_info.memmap_entries {
+                let entry = unsafe { *ep };
+                let start = PhysAddr::new(entry.addr as usize);
+                let size = entry.size as usize;
+                let typ = E820Type::from(entry.type_);
+
+                total_mem_size += size;
+                match typ {
+                    param::E820Type::Ram => {
+                        usable_mem_size += size;
+                        mem_block_manager()
+                            .add_block(start, size)
+                            .unwrap_or_else(|e| {
+                                log::warn!(
+                                    "Failed to add memory block: base={:?}, size={:#x}, error={:?}",
+                                    start,
+                                    size,
+                                    e
+                                );
+                            });
+                    }
+                    _ => {
+                        mem_block_manager()
+                            .reserve_block(start, size)
+                            .unwrap_or_else(|e| {
+                                log::warn!(
+                                    "Failed to reserve memory block: base={:?}, size={:#x}, error={:?}",
+                                    start,
+                                    size,
+                                    e
+                                );
+                            });
+                    }
+                }
+                ep = unsafe { ep.add(1) };
+            }
+        }
+        send_to_default_serial8250_port("init_memory_area_from pvh boot end\n\0".as_bytes());
+        log::info!(
+            "Total memory size: {:#x}, Usable memory size: {:#x}",
+            total_mem_size,
+            usable_mem_size
+        );
+        Ok(())
+    }
+}
+
+#[inline(never)]
+pub(super) fn early_linux32_pvh_init(params_ptr: usize) -> Result<(), SystemError> {
+    let start_info = unsafe { *(params_ptr as *const HvmStartInfo) };
+    if start_info.magic != HvmStartInfo::XEN_HVM_START_MAGIC_VALUE {
+        send_to_default_serial8250_port(
+            "early_linux32_pvh_init failed: Magic number not matched.\n\0".as_bytes(),
+        );
+
+        loop {
+            spin_loop();
+        }
+    }
+
+    START_INFO.init(start_info);
+
+    register_boot_callbacks(&PvhBootCallback);
+    send_to_default_serial8250_port("early_linux32_pvh_init done.\n\0".as_bytes());
+    Ok(())
+}

+ 425 - 0
kernel/src/arch/x86_64/init/pvh/param.rs

@@ -0,0 +1,425 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Copyright (c) 2016, Citrix Systems, Inc.
+ */
+
+/*
+ * automatically generated by rust-bindgen using:
+ *
+ * # bindgen start_info.h -- -include stdint.h > start_info.rs
+ *
+ * From the canonical version in upstream Xen repository
+ * xen/include/public/arch-x86/hvm/start_info.h
+ * at commit:
+ * b4642c32c4d079916d5607ddda0232aae5e1690e
+ *
+ * The generated file has been edited to eliminate unnecessary
+ * definitions, add comments, and relocate definitions and tests for clarity.
+ * Added Default to the list of traits that are automatically derived.
+ *
+ * The definitions in this file are intended to be exported and used by a particular
+ * VMM implementation in order to boot a Linux guest using the PVH entry point as
+ * specified in the x86/HVM direct boot ABI.
+ * These structures contain all the required information (cmdline address, ACPI RSDP,
+ * memory maps, etc) that must be written to guest memory before starting guest
+ * execution by jumping to the PVH entry point address.
+ * A comparable set of definitions to hvm_start_info and hvm_memmap_table_entry in this
+ * file would be the boot_params and boot_e820_entry definitions used by the Linux
+ * 64-bit boot protocol.
+ *
+ * Start of day structure passed to PVH guests and to HVM guests in %ebx.
+ *
+ * NOTE: nothing will be loaded at physical address 0, so a 0 value in any
+ * of the address fields should be treated as not present.
+ *
+ *  0 +----------------+
+ *    | magic          | Contains the magic value XEN_HVM_START_MAGIC_VALUE
+ *    |                | ("xEn3" with the 0x80 bit of the "E" set).
+ *  4 +----------------+
+ *    | version        | Version of this structure. Current version is 1. New
+ *    |                | versions are guaranteed to be backwards-compatible.
+ *  8 +----------------+
+ *    | flags          | SIF_xxx flags.
+ * 12 +----------------+
+ *    | nr_modules     | Number of modules passed to the kernel.
+ * 16 +----------------+
+ *    | modlist_paddr  | Physical address of an array of modules
+ *    |                | (layout of the structure below).
+ * 24 +----------------+
+ *    | cmdline_paddr  | Physical address of the command line,
+ *    |                | a zero-terminated ASCII string.
+ * 32 +----------------+
+ *    | rsdp_paddr     | Physical address of the RSDP ACPI data structure.
+ * 40 +----------------+
+ *    | memmap_paddr   | Physical address of the (optional) memory map. Only
+ *    |                | present in version 1 and newer of the structure.
+ * 48 +----------------+
+ *    | memmap_entries | Number of entries in the memory map table. Zero
+ *    |                | if there is no memory map being provided. Only
+ *    |                | present in version 1 and newer of the structure.
+ * 52 +----------------+
+ *    | reserved       | Version 1 and newer only.
+ * 56 +----------------+
+ *
+ * The layout of each entry in the module structure is the following:
+ *
+ *  0 +----------------+
+ *    | paddr          | Physical address of the module.
+ *  8 +----------------+
+ *    | size           | Size of the module in bytes.
+ * 16 +----------------+
+ *    | cmdline_paddr  | Physical address of the command line,
+ *    |                | a zero-terminated ASCII string.
+ * 24 +----------------+
+ *    | reserved       |
+ * 32 +----------------+
+ *
+ * The layout of each entry in the memory map table is as follows:
+ *
+ *  0 +----------------+
+ *    | addr           | Base address
+ *  8 +----------------+
+ *    | size           | Size of mapping in bytes
+ * 16 +----------------+
+ *    | type           | Type of mapping as defined between the hypervisor
+ *    |                | and guest. See XEN_HVM_MEMMAP_TYPE_* values below.
+ * 20 +----------------|
+ *    | reserved       |
+ * 24 +----------------+
+ *
+ * The address and sizes are always a 64bit little endian unsigned integer.
+ *
+ * NB: Xen on x86 will always try to place all the data below the 4GiB
+ * boundary.
+ *
+ * Version numbers of the hvm_start_info structure have evolved like this:
+ *
+ * Version 0:  Initial implementation.
+ *
+ * Version 1:  Added the memmap_paddr/memmap_entries fields (plus 4 bytes of
+ *             padding) to the end of the hvm_start_info struct. These new
+ *             fields can be used to pass a memory map to the guest. The
+ *             memory map is optional and so guests that understand version 1
+ *             of the structure must check that memmap_entries is non-zero
+ *             before trying to read the memory map.
+ */
+
+#[repr(C)]
+#[derive(Debug, Copy, Clone, Default)]
+pub struct HvmStartInfo {
+    pub magic: u32,
+    pub version: u32,
+    pub flags: u32,
+    pub nr_modules: u32,
+    pub modlist_paddr: u64,
+    pub cmdline_paddr: u64,
+    pub rsdp_paddr: u64,
+    pub memmap_paddr: u64,
+    pub memmap_entries: u32,
+    pub reserved: u32,
+}
+
+impl HvmStartInfo {
+    pub const XEN_HVM_START_MAGIC_VALUE: u32 = 0x336ec578;
+}
+
+#[repr(C)]
+#[derive(Debug, Copy, Clone, Default)]
+pub struct HvmModlistEntry {
+    pub paddr: u64,
+    pub size: u64,
+    pub cmdline_paddr: u64,
+    pub reserved: u64,
+}
+
+#[repr(C)]
+#[derive(Debug, Copy, Clone, Default)]
+pub struct HvmMemmapTableEntry {
+    pub addr: u64,
+    pub size: u64,
+    pub type_: u32,
+    pub reserved: u32,
+}
+
+/// The E820 types known to the kernel.
+#[derive(Copy, Clone, Debug)]
+#[repr(u32)]
+pub enum E820Type {
+    Ram = 1,
+    Reserved = 2,
+    Acpi = 3,
+    Nvs = 4,
+    Unusable = 5,
+    Pmem = 7,
+    Pram = 12,
+    SoftReserved = 0xefffffff,
+    ReservedKern = 128,
+}
+
+impl From<u32> for E820Type {
+    fn from(val: u32) -> Self {
+        match val {
+            1 => E820Type::Ram,
+            2 => E820Type::Reserved,
+            3 => E820Type::Acpi,
+            4 => E820Type::Nvs,
+            5 => E820Type::Unusable,
+            7 => E820Type::Pmem,
+            12 => E820Type::Pram,
+            0xefffffff => E820Type::SoftReserved,
+            128 => E820Type::ReservedKern,
+            _ => E820Type::Reserved,
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn bindgen_test_layout_hvm_start_info() {
+        const UNINIT: ::std::mem::MaybeUninit<HvmStartInfo> = ::std::mem::MaybeUninit::uninit();
+        let ptr = UNINIT.as_ptr();
+        assert_eq!(
+            ::std::mem::size_of::<HvmStartInfo>(),
+            56usize,
+            concat!("Size of: ", stringify!(hvm_start_info))
+        );
+        assert_eq!(
+            ::std::mem::align_of::<HvmStartInfo>(),
+            8usize,
+            concat!("Alignment of ", stringify!(hvm_start_info))
+        );
+        assert_eq!(
+            unsafe { ::std::ptr::addr_of!((*ptr).magic) as usize - ptr as usize },
+            0usize,
+            concat!(
+                "Offset of field: ",
+                stringify!(hvm_start_info),
+                "::",
+                stringify!(magic)
+            )
+        );
+        assert_eq!(
+            unsafe { ::std::ptr::addr_of!((*ptr).version) as usize - ptr as usize },
+            4usize,
+            concat!(
+                "Offset of field: ",
+                stringify!(hvm_start_info),
+                "::",
+                stringify!(version)
+            )
+        );
+        assert_eq!(
+            unsafe { ::std::ptr::addr_of!((*ptr).flags) as usize - ptr as usize },
+            8usize,
+            concat!(
+                "Offset of field: ",
+                stringify!(hvm_start_info),
+                "::",
+                stringify!(flags)
+            )
+        );
+        assert_eq!(
+            unsafe { ::std::ptr::addr_of!((*ptr).nr_modules) as usize - ptr as usize },
+            12usize,
+            concat!(
+                "Offset of field: ",
+                stringify!(hvm_start_info),
+                "::",
+                stringify!(nr_modules)
+            )
+        );
+        assert_eq!(
+            unsafe { ::std::ptr::addr_of!((*ptr).modlist_paddr) as usize - ptr as usize },
+            16usize,
+            concat!(
+                "Offset of field: ",
+                stringify!(hvm_start_info),
+                "::",
+                stringify!(modlist_paddr)
+            )
+        );
+        assert_eq!(
+            unsafe { ::std::ptr::addr_of!((*ptr).cmdline_paddr) as usize - ptr as usize },
+            24usize,
+            concat!(
+                "Offset of field: ",
+                stringify!(hvm_start_info),
+                "::",
+                stringify!(cmdline_paddr)
+            )
+        );
+        assert_eq!(
+            unsafe { ::std::ptr::addr_of!((*ptr).rsdp_paddr) as usize - ptr as usize },
+            32usize,
+            concat!(
+                "Offset of field: ",
+                stringify!(hvm_start_info),
+                "::",
+                stringify!(rsdp_paddr)
+            )
+        );
+        assert_eq!(
+            unsafe { ::std::ptr::addr_of!((*ptr).memmap_paddr) as usize - ptr as usize },
+            40usize,
+            concat!(
+                "Offset of field: ",
+                stringify!(hvm_start_info),
+                "::",
+                stringify!(memmap_paddr)
+            )
+        );
+        assert_eq!(
+            unsafe { ::std::ptr::addr_of!((*ptr).memmap_entries) as usize - ptr as usize },
+            48usize,
+            concat!(
+                "Offset of field: ",
+                stringify!(hvm_start_info),
+                "::",
+                stringify!(memmap_entries)
+            )
+        );
+        assert_eq!(
+            unsafe { ::std::ptr::addr_of!((*ptr).reserved) as usize - ptr as usize },
+            52usize,
+            concat!(
+                "Offset of field: ",
+                stringify!(hvm_start_info),
+                "::",
+                stringify!(reserved)
+            )
+        );
+    }
+
+    #[test]
+    fn bindgen_test_layout_hvm_modlist_entry() {
+        const UNINIT: ::std::mem::MaybeUninit<HvmModlistEntry> = ::std::mem::MaybeUninit::uninit();
+        let ptr = UNINIT.as_ptr();
+        assert_eq!(
+            ::std::mem::size_of::<HvmModlistEntry>(),
+            32usize,
+            concat!("Size of: ", stringify!(hvm_modlist_entry))
+        );
+        assert_eq!(
+            ::std::mem::align_of::<HvmModlistEntry>(),
+            8usize,
+            concat!("Alignment of ", stringify!(hvm_modlist_entry))
+        );
+        assert_eq!(
+            unsafe { ::std::ptr::addr_of!((*ptr).paddr) as usize - ptr as usize },
+            0usize,
+            concat!(
+                "Offset of field: ",
+                stringify!(hvm_modlist_entry),
+                "::",
+                stringify!(paddr)
+            )
+        );
+        assert_eq!(
+            unsafe { ::std::ptr::addr_of!((*ptr).size) as usize - ptr as usize },
+            8usize,
+            concat!(
+                "Offset of field: ",
+                stringify!(hvm_modlist_entry),
+                "::",
+                stringify!(size)
+            )
+        );
+        assert_eq!(
+            unsafe { ::std::ptr::addr_of!((*ptr).cmdline_paddr) as usize - ptr as usize },
+            16usize,
+            concat!(
+                "Offset of field: ",
+                stringify!(hvm_modlist_entry),
+                "::",
+                stringify!(cmdline_paddr)
+            )
+        );
+        assert_eq!(
+            unsafe { ::std::ptr::addr_of!((*ptr).reserved) as usize - ptr as usize },
+            24usize,
+            concat!(
+                "Offset of field: ",
+                stringify!(hvm_modlist_entry),
+                "::",
+                stringify!(reserved)
+            )
+        );
+    }
+
+    #[test]
+    fn bindgen_test_layout_hvm_memmap_table_entry() {
+        const UNINIT: ::std::mem::MaybeUninit<HvmMemmapTableEntry> =
+            ::std::mem::MaybeUninit::uninit();
+        let ptr = UNINIT.as_ptr();
+        assert_eq!(
+            ::std::mem::size_of::<HvmMemmapTableEntry>(),
+            24usize,
+            concat!("Size of: ", stringify!(hvm_memmap_table_entry))
+        );
+        assert_eq!(
+            ::std::mem::align_of::<HvmMemmapTableEntry>(),
+            8usize,
+            concat!("Alignment of ", stringify!(hvm_memmap_table_entry))
+        );
+        assert_eq!(
+            unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize },
+            0usize,
+            concat!(
+                "Offset of field: ",
+                stringify!(hvm_memmap_table_entry),
+                "::",
+                stringify!(addr)
+            )
+        );
+        assert_eq!(
+            unsafe { ::std::ptr::addr_of!((*ptr).size) as usize - ptr as usize },
+            8usize,
+            concat!(
+                "Offset of field: ",
+                stringify!(hvm_memmap_table_entry),
+                "::",
+                stringify!(size)
+            )
+        );
+        assert_eq!(
+            unsafe { ::std::ptr::addr_of!((*ptr).type_) as usize - ptr as usize },
+            16usize,
+            concat!(
+                "Offset of field: ",
+                stringify!(hvm_memmap_table_entry),
+                "::",
+                stringify!(type_)
+            )
+        );
+        assert_eq!(
+            unsafe { ::std::ptr::addr_of!((*ptr).reserved) as usize - ptr as usize },
+            20usize,
+            concat!(
+                "Offset of field: ",
+                stringify!(hvm_memmap_table_entry),
+                "::",
+                stringify!(reserved)
+            )
+        );
+    }
+}

+ 0 - 1
kernel/src/arch/x86_64/interrupt/entry.rs

@@ -58,7 +58,6 @@ macro_rules! interrupt_handler {
                         push rax
                         mov rsi, {irqnum}
                         jmp x86_64_do_irq
-                        // jmp do_IRQ
                         "
                     ),
                     irqnum = const($name),

+ 8 - 3
kernel/src/arch/x86_64/link.lds

@@ -9,19 +9,22 @@ SECTIONS
 	//KERNEL_VMA = 0;
 	. = 0;
 	. = 0x100000;
-	
+	_default_kernel_load_base = .;
 	.boot.text :
 	{
 		KEEP(*(.multiboot_header))
+		KEEP(*(.multiboot2_header))
+		
 		*(.bootstrap)
 		*(.bootstrap.code64)
 		*(.bootstrap.data)
+		
 		. = ALIGN(4096);
 	}
 
-	. = 0x1000000;
-	. += KERNEL_VMA;
+
 	. = ALIGN(32768);
+	. += KERNEL_VMA;
 	text_start_pa = .;
 	.text (text_start_pa): AT(text_start_pa - KERNEL_VMA)
 	{
@@ -54,6 +57,8 @@ SECTIONS
 		_rodata = .;	
 		*(.rodata)
 		*(.rodata.*)
+		*(.note.gnu.*)
+		*(.fixup)
 		_erodata = .;
 	}
 

+ 29 - 9
kernel/src/arch/x86_64/mm/fault.rs

@@ -10,15 +10,18 @@ use x86::{bits64::rflags::RFlags, controlregs::Cr4};
 use crate::{
     arch::{
         interrupt::{trap::X86PfErrorCode, TrapFrame},
+        ipc::signal::{SigCode, Signal},
         mm::{MemoryManagementArch, X86_64MMArch},
         CurrentIrqArch, MMArch,
     },
     exception::InterruptArch,
+    ipc::signal_types::{SigInfo, SigType},
     mm::{
         fault::{FaultFlags, PageFaultHandler, PageFaultMessage},
         ucontext::{AddressSpace, LockedVMA},
         VirtAddr, VmFaultReason, VmFlags,
     },
+    process::ProcessManager,
 };
 
 use super::LockedFrameAllocator;
@@ -229,13 +232,23 @@ impl X86_64MMArch {
             let vma = space_guard.mappings.find_nearest(address);
             // let vma = space_guard.mappings.contains(address);
 
-            let vma = vma.unwrap_or_else(|| {
-                panic!(
-                    "can not find nearest vma, error_code: {:#b}, address: {:#x}",
-                    error_code,
-                    address.data(),
-                )
-            });
+            let vma = match vma {
+                Some(vma) => vma,
+                None => {
+                    log::error!(
+                        "can not find nearest vma, error_code: {:#b}, address: {:#x}",
+                        error_code,
+                        address.data(),
+                    );
+                    let pid = ProcessManager::current_pid();
+                    let mut info =
+                        SigInfo::new(Signal::SIGSEGV, 0, SigCode::User, SigType::Kill(pid));
+                    Signal::SIGSEGV
+                        .send_signal_info(Some(&mut info), pid)
+                        .expect("failed to send SIGSEGV to process");
+                    return;
+                }
+            };
             let guard = vma.lock_irqsave();
             let region = *guard.region();
             let vm_flags = *guard.vm_flags();
@@ -253,11 +266,18 @@ impl X86_64MMArch {
                             )
                         });
                 } else {
-                    panic!(
+                    log::error!(
                         "No mapped vma, error_code: {:#b}, address: {:#x}",
                         error_code,
                         address.data(),
-                    )
+                    );
+                    let pid = ProcessManager::current_pid();
+                    let mut info =
+                        SigInfo::new(Signal::SIGSEGV, 0, SigCode::User, SigType::Kill(pid));
+                    Signal::SIGSEGV
+                        .send_signal_info(Some(&mut info), pid)
+                        .expect("failed to send SIGSEGV to process");
+                    return;
                 }
             }
 

+ 18 - 81
kernel/src/arch/x86_64/mm/mod.rs

@@ -6,15 +6,13 @@ pub mod pkru;
 use alloc::sync::Arc;
 use alloc::vec::Vec;
 use hashbrown::HashSet;
-use log::{debug, info, warn};
+use log::{debug, info};
 use x86::time::rdtsc;
 use x86_64::registers::model_specific::EferFlags;
 
 use crate::driver::serial::serial8250::send_to_default_serial8250_port;
-use crate::include::bindings::bindings::{
-    multiboot2_get_load_base, multiboot2_get_memory, multiboot2_iter, multiboot_mmap_entry_t,
-    multiboot_tag_load_base_addr_t,
-};
+
+use crate::init::boot::boot_callbacks;
 use crate::libs::align::page_align_up;
 use crate::libs::lib_ui::screen_manager::scm_disable_put_to_window;
 use crate::libs::spinlock::SpinLock;
@@ -34,9 +32,7 @@ use crate::mm::{MemoryManagementArch, PageTableKind, PhysAddr, VirtAddr, VmFlags
 use system_error::SystemError;
 
 use core::arch::asm;
-use core::ffi::c_void;
 use core::fmt::Debug;
-use core::mem::{self};
 
 use core::sync::atomic::{compiler_fence, AtomicBool, Ordering};
 
@@ -63,6 +59,12 @@ pub struct X86_64MMBootstrapInfo {
 
 pub(super) static mut BOOTSTRAP_MM_INFO: Option<X86_64MMBootstrapInfo> = None;
 
+pub(super) fn x86_64_set_kernel_load_base_paddr(paddr: PhysAddr) {
+    unsafe {
+        BOOTSTRAP_MM_INFO.as_mut().unwrap().kernel_load_base_paddr = paddr.data();
+    }
+}
+
 /// @brief X86_64的内存管理架构结构体
 #[derive(Debug, Clone, Copy, Hash)]
 pub struct X86_64MMArch;
@@ -125,8 +127,8 @@ impl MemoryManagementArch for X86_64MMArch {
     const USER_STACK_START: VirtAddr = VirtAddr::new(0x6ffff0a00000);
 
     const FIXMAP_START_VADDR: VirtAddr = VirtAddr::new(0xffffb00000000000);
-    /// 设置FIXMAP区域大小为1M
-    const FIXMAP_SIZE: usize = 256 * 4096;
+    /// 设置FIXMAP区域大小为16M
+    const FIXMAP_SIZE: usize = 256 * 4096 * 16;
 
     const MMIO_BASE: VirtAddr = VirtAddr::new(0xffffa10000000000);
     const MMIO_SIZE: usize = 1 << PAGE_1G_SHIFT;
@@ -139,13 +141,13 @@ impl MemoryManagementArch for X86_64MMArch {
             fn _edata();
             fn _erodata();
             fn _end();
+            fn _default_kernel_load_base();
         }
 
         Self::init_xd_rsvd();
-        let load_base_paddr = Self::get_load_base_paddr();
 
         let bootstrap_info = X86_64MMBootstrapInfo {
-            kernel_load_base_paddr: load_base_paddr.data(),
+            kernel_load_base_paddr: _default_kernel_load_base as usize,
             kernel_code_start: _text as usize,
             kernel_code_end: _etext as usize,
             kernel_data_end: _edata as usize,
@@ -157,8 +159,10 @@ impl MemoryManagementArch for X86_64MMArch {
             BOOTSTRAP_MM_INFO = Some(bootstrap_info);
         }
 
-        // 初始化物理内存区域(从multiboot2中获取)
-        Self::init_memory_area_from_multiboot2().expect("init memory area failed");
+        // 初始化物理内存区域
+        boot_callbacks()
+            .early_init_memory_blocks()
+            .expect("init memory area failed");
 
         debug!("bootstrap info: {:?}", unsafe { BOOTSTRAP_MM_INFO });
         debug!("phys[0]=virt[0x{:x}]", unsafe {
@@ -168,7 +172,7 @@ impl MemoryManagementArch for X86_64MMArch {
         // 初始化内存管理器
         unsafe { allocator_init() };
 
-        send_to_default_serial8250_port("x86 64 init done\n\0".as_bytes());
+        send_to_default_serial8250_port("x86 64 mm init done\n\0".as_bytes());
     }
 
     /// @brief 刷新TLB中,关于指定虚拟地址的条目
@@ -416,73 +420,6 @@ const fn protection_map() -> [EntryFlags<MMArch>; 16] {
 }
 
 impl X86_64MMArch {
-    unsafe fn get_load_base_paddr() -> PhysAddr {
-        let mut mb2_lb_info: [multiboot_tag_load_base_addr_t; 512] = mem::zeroed();
-        send_to_default_serial8250_port("get_load_base_paddr begin\n\0".as_bytes());
-
-        let mut mb2_count: u32 = 0;
-        multiboot2_iter(
-            Some(multiboot2_get_load_base),
-            &mut mb2_lb_info as *mut [multiboot_tag_load_base_addr_t; 512] as usize as *mut c_void,
-            &mut mb2_count,
-        );
-
-        if mb2_count == 0 {
-            send_to_default_serial8250_port(
-                "get_load_base_paddr mb2_count == 0, default to 1MB\n\0".as_bytes(),
-            );
-            return PhysAddr::new(0x100000);
-        }
-
-        let phys = mb2_lb_info[0].load_base_addr as usize;
-
-        return PhysAddr::new(phys);
-    }
-    unsafe fn init_memory_area_from_multiboot2() -> Result<usize, SystemError> {
-        // 这个数组用来存放内存区域的信息(从C获取)
-        let mut mb2_mem_info: [multiboot_mmap_entry_t; 512] = mem::zeroed();
-        send_to_default_serial8250_port("init_memory_area_from_multiboot2 begin\n\0".as_bytes());
-
-        let mut mb2_count: u32 = 0;
-        multiboot2_iter(
-            Some(multiboot2_get_memory),
-            &mut mb2_mem_info as *mut [multiboot_mmap_entry_t; 512] as usize as *mut c_void,
-            &mut mb2_count,
-        );
-        send_to_default_serial8250_port("init_memory_area_from_multiboot2 2\n\0".as_bytes());
-
-        let mb2_count = mb2_count as usize;
-        let mut areas_count = 0usize;
-        let mut total_mem_size = 0usize;
-        for info_entry in mb2_mem_info.iter().take(mb2_count) {
-            // Only use the memory area if its type is 1 (RAM)
-            if info_entry.type_ == 1 {
-                // Skip the memory area if its len is 0
-                if info_entry.len == 0 {
-                    continue;
-                }
-
-                total_mem_size += info_entry.len as usize;
-
-                mem_block_manager()
-                    .add_block(
-                        PhysAddr::new(info_entry.addr as usize),
-                        info_entry.len as usize,
-                    )
-                    .unwrap_or_else(|e| {
-                        warn!(
-                            "Failed to add memory block: base={:#x}, size={:#x}, error={:?}",
-                            info_entry.addr, info_entry.len, e
-                        );
-                    });
-                areas_count += 1;
-            }
-        }
-        send_to_default_serial8250_port("init_memory_area_from_multiboot2 end\n\0".as_bytes());
-        info!("Total memory size: {} MB, total areas from multiboot2: {mb2_count}, valid areas: {areas_count}", total_mem_size / 1024 / 1024);
-        return Ok(areas_count);
-    }
-
     fn init_xd_rsvd() {
         // 读取ia32-EFER寄存器的值
         let efer: EferFlags = x86_64::registers::model_specific::Efer::read();

+ 8 - 8
kernel/src/arch/x86_64/pci/pci.rs

@@ -1,4 +1,5 @@
-use crate::arch::TraitPciArch;
+use crate::arch::io::PortIOArch;
+use crate::arch::{CurrentPortIOArch, TraitPciArch};
 use crate::driver::acpi::acpi_manager;
 use crate::driver::pci::ecam::{pci_ecam_root_info_manager, EcamRootInfo};
 use crate::driver::pci::pci::{
@@ -6,7 +7,6 @@ use crate::driver::pci::pci::{
     PORT_PCI_CONFIG_DATA,
 };
 use crate::driver::pci::root::{pci_root_manager, PciRoot};
-use crate::include::bindings::bindings::{io_in32, io_in8, io_out32};
 use crate::init::initcall::INITCALL_SUBSYS;
 use crate::mm::PhysAddr;
 
@@ -22,7 +22,7 @@ impl X86_64PciArch {
     /// 参考:https://code.dragonos.org.cn/xref/linux-6.6.21/arch/x86/pci/early.c?fi=read_pci_config_byte#19
     fn read_config_early(bus: u8, slot: u8, func: u8, offset: u8) -> u8 {
         unsafe {
-            io_out32(
+            CurrentPortIOArch::out32(
                 PORT_PCI_CONFIG_ADDRESS,
                 0x80000000
                     | ((bus as u32) << 16)
@@ -31,7 +31,7 @@ impl X86_64PciArch {
                     | offset as u32,
             );
         }
-        let value = unsafe { io_in8(PORT_PCI_CONFIG_DATA + (offset & 3) as u16) };
+        let value = unsafe { CurrentPortIOArch::in8(PORT_PCI_CONFIG_DATA + (offset & 3) as u16) };
         return value;
     }
 }
@@ -45,8 +45,8 @@ impl TraitPciArch for X86_64PciArch {
             | (offset & 0xfc) as u32
             | (0x80000000);
         let ret = unsafe {
-            io_out32(PORT_PCI_CONFIG_ADDRESS, address);
-            let temp = io_in32(PORT_PCI_CONFIG_DATA);
+            CurrentPortIOArch::out32(PORT_PCI_CONFIG_ADDRESS, address);
+            let temp = CurrentPortIOArch::in32(PORT_PCI_CONFIG_DATA);
             temp
         };
         return ret;
@@ -59,9 +59,9 @@ impl TraitPciArch for X86_64PciArch {
             | (offset & 0xfc) as u32
             | (0x80000000);
         unsafe {
-            io_out32(PORT_PCI_CONFIG_ADDRESS, address);
+            CurrentPortIOArch::out32(PORT_PCI_CONFIG_ADDRESS, address);
             // 写入数据
-            io_out32(PORT_PCI_CONFIG_DATA, data);
+            CurrentPortIOArch::out32(PORT_PCI_CONFIG_DATA, data);
         }
     }
 

+ 0 - 11
kernel/src/arch/x86_64/sched.rs

@@ -4,17 +4,6 @@ use crate::{exception::InterruptArch, sched::SchedArch, smp::core::smp_get_proce
 
 use super::{driver::apic::apic_timer::apic_timer_init, CurrentIrqArch};
 
-// /// @brief 若内核代码不处在中断上下文中,那么将可以使用本函数,发起一个sys_sched系统调用,然后运行调度器。
-// /// 由于只能在中断上下文中进行进程切换,因此需要发起一个系统调用SYS_SCHED。
-// #[no_mangle]
-// pub extern "C" fn sched() {
-//     let _guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
-//     __schedule(SchedMode::SM_NONE);
-//     // unsafe {
-//     //     enter_syscall_int(SYS_SCHED as u64, 0, 0, 0, 0, 0, 0);
-//     // }
-// }
-
 static mut BSP_INIT_OK: bool = false;
 
 pub struct X86_64SchedArch;

+ 0 - 14
kernel/src/common/Makefile

@@ -1,14 +0,0 @@
-
-CFLAGS += -I .
-
-kernel_common_subdirs:= math
-
-ECHO:
-	@echo "$@"
-
-$(kernel_common_subdirs): ECHO
-
-	$(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)" 
-
-all:  $(kernel_common_subdirs)
-

+ 0 - 23
kernel/src/common/boot_info.h

@@ -1,23 +0,0 @@
-
-/**
- * @file boot_info.h
- * @brief 启动信息接口
- */
-
-#pragma once
-#include "glib.h"
-
-/**
- * @brief 启动信息接口
- * 由引导传递的机器信息处理
- * 如 grub2 传递的 multiboot2 结构
- * 注意这部分是通过内存传递的,在重新保存之前不能被覆盖
- * 架构专有的数据在 dtb.h 或 multiboot2.h
- * 实现在 dtb.cpp 或 multiboot2.cpp
- */
-    /// 声明,定义在具体的实现中
-    /// 地址
-    extern uintptr_t  boot_info_addr;
-    /// 长度
-    extern unsigned int boot_info_size;
-

+ 10 - 27
kernel/src/common/glib.h

@@ -6,11 +6,11 @@
 #pragma once
 
 // 引入对bool类型的支持
-#include <stdbool.h>
 #include <DragonOS/stdint.h>
-#include <common/stddef.h>
 #include <arch/arch.h>
 #include <common/compiler.h>
+#include <common/stddef.h>
+#include <stdbool.h>
 
 #include <asm/asm.h>
 
@@ -22,13 +22,11 @@
  *
  * 方法:使用ptr减去结构体内的偏移,得到结构体变量的基地址
  */
-#define container_of(ptr, type, member)                                     \
-    ({                                                                      \
-        typeof(((type *)0)->member) *p = (ptr);                             \
-        (type *)((unsigned long)p - (unsigned long)&(((type *)0)->member)); \
-    })
-
-
+#define container_of(ptr, type, member)                                        \
+  ({                                                                           \
+    typeof(((type *)0)->member) *p = (ptr);                                    \
+    (type *)((unsigned long)p - (unsigned long)&(((type *)0)->member));        \
+  })
 
 #define ABS(x) ((x) > 0 ? (x) : -(x)) // 绝对值
 // 最大最小值
@@ -39,10 +37,7 @@
 #define MASK_HIGH_32bit(x) (x & (0x00000000ffffffffUL))
 
 // 四舍五入成整数
-ul round(double x)
-{
-    return (ul)(x + 0.5);
-}
+ul round(double x) { return (ul)(x + 0.5); }
 
 /**
  * @brief 地址按照align进行对齐
@@ -51,18 +46,6 @@ ul round(double x)
  * @param _align
  * @return ul 对齐后的地址
  */
-static __always_inline ul ALIGN(const ul addr, const ul _align)
-{
-    return (ul)((addr + _align - 1) & (~(_align - 1)));
+static __always_inline ul ALIGN(const ul addr, const ul _align) {
+  return (ul)((addr + _align - 1) & (~(_align - 1)));
 }
-
-
-/**
- * @brief 将数据从src搬运到dst,并能正确处理地址重叠的问题
- *
- * @param dst 目标地址指针
- * @param src 源地址指针
- * @param size 大小
- * @return void* 指向目标地址的指针
- */
-void *c_memmove(void *dst, const void *src, uint64_t size);

+ 0 - 10
kernel/src/common/math/Makefile

@@ -1,10 +0,0 @@
-SRC = $(wildcard *.c)
-OBJ = $(SRC:.c=.o)
-CFLAGS += -I .
-
-.PHONY: all
-
-all: $(OBJ)
-
-%.o: %.c
-	$(CC) $(CFLAGS) -c $< -o $@

+ 9 - 58
kernel/src/common/string.h

@@ -1,62 +1,13 @@
 #pragma once
 #include "glib.h"
-/**
- * @brief 拷贝整个字符串
- *
- * @param dst 目标地址
- * @param src 源地址
- * @return char* 目标字符串
- */
-char *strcpy(char *dst, const char *src);
 
-//计算字符串的长度(经过测试,该版本比采用repne/scasb汇编的运行速度快16.8%左右)
-static inline int strlen(const char *s)
-{
-    if (s == NULL)
-        return 0;
-    register int __res = 0;
-    while (s[__res] != '\0')
-    {
-        ++__res;
-    }
-    return __res;
+// 计算字符串的长度(经过测试,该版本比采用repne/scasb汇编的运行速度快16.8%左右)
+static inline int strlen(const char *s) {
+  if (s == NULL)
+    return 0;
+  register int __res = 0;
+  while (s[__res] != '\0') {
+    ++__res;
+  }
+  return __res;
 }
-
-/**
- * @brief 测量字符串的长度
- *
- * @param src 字符串
- * @param maxlen 最大长度
- * @return long
- */
-long strnlen(const char *src, unsigned long maxlen);
-
-/*
-        比较字符串 FirstPart and SecondPart
-        FirstPart = SecondPart =>  0
-        FirstPart > SecondPart =>  1
-        FirstPart < SecondPart => -1
-*/
-
-int strcmp(const char *FirstPart, const char *SecondPart);
-
-char *strncpy(char *restrict d, const char *restrict s, size_t n);
-
-long strncpy_from_user(char *dst, const char *src, unsigned long size);
-
-/**
- * @brief 测量来自用户空间的字符串的长度,会检验地址空间是否属于用户空间
- * @param src
- * @param maxlen
- * @return long
- */
-long strnlen_user(const char *src, unsigned long maxlen);
-
-/**
- * @brief 拼接两个字符串(将src接到dest末尾)
- *
- * @param dest 目标串
- * @param src 源串
- * @return char*
- */
-char *strcat(char *dest, const char *src);

+ 0 - 22
kernel/src/common/unistd.h

@@ -1,22 +0,0 @@
-/**
- * @file unistd.h
- * @author fslongjin ([email protected])
- * @brief
- * @version 0.1
- * @date 2022-04-22
- *
- * @copyright Copyright (c) 2022
- *
- */
-#pragma once
-
-#include <syscall/syscall.h>
-#include <syscall/syscall_num.h>
-
-/**
- * @brief  交换n字节
- *  @param src  源地址
- *  @param dest  目的地址
- * @param nbytes  交换字节数
- */
-void swab(void *restrict src, void *restrict dest, ssize_t nbytes);

+ 2 - 1
kernel/src/debug/Makefile

@@ -1,5 +1,6 @@
 
-all: traceback.o
+all: 
+	@echo ""
 
 CFLAGS += -I .
 

+ 4 - 3
kernel/src/debug/klog/mm.rs

@@ -4,7 +4,7 @@ use core::sync::atomic::{compiler_fence, Ordering};
 
 use klog_types::{AllocatorLog, AllocatorLogType, LogSource, MMLogChannel};
 
-use crate::{arch::CurrentTimeArch, process::Pid, time::TimeArch};
+use crate::{arch::CurrentTimeArch, libs::spinlock::SpinLock, process::Pid, time::TimeArch};
 
 /// 全局的内存分配器日志通道
 ///
@@ -16,7 +16,8 @@ static __MM_ALLOCATOR_LOG_CHANNEL: MMLogChannel<{ MMDebugLogManager::MAX_ALLOC_L
 /// 全局的内存分配器日志id分配器
 ///
 /// id从1开始, 因为0是无效的id
-static __MM_DEBUG_LOG_IDA: ida::IdAllocator = ida::IdAllocator::new(1, usize::MAX);
+static __MM_DEBUG_LOG_IDA: SpinLock<ida::IdAllocator> =
+    SpinLock::new(ida::IdAllocator::new(1, usize::MAX).unwrap());
 
 /// 记录内存分配器的日志
 ///
@@ -50,7 +51,7 @@ impl MMDebugLogManager {
     /// - `pid`:日志来源的pid
     #[allow(dead_code)]
     pub fn log(log_type: AllocatorLogType, source: LogSource, pid: Option<Pid>) {
-        let id = __MM_DEBUG_LOG_IDA.alloc().unwrap();
+        let id = __MM_DEBUG_LOG_IDA.lock_irqsave().alloc().unwrap();
         let log = AllocatorLog::new(
             id as u64,
             log_type,

+ 0 - 17
kernel/src/driver/Makefile

@@ -1,17 +0,0 @@
-
-CFLAGS += -I .
-
-kernel_driver_subdirs:=acpi multiboot2 
-
-ECHO:
-	@echo "$@"
-
-$(kernel_driver_subdirs): ECHO
-
-	$(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)" 
-
-all: $(kernel_driver_subdirs)
-
-
-clean:
-	echo "Done."

+ 0 - 10
kernel/src/driver/acpi/Makefile

@@ -1,10 +0,0 @@
-SRC = $(wildcard *.c)
-OBJ = $(SRC:.c=.o)
-CFLAGS += -I .
-
-.PHONY: all
-
-all: $(OBJ)
-
-%.o: %.c
-	$(CC) $(CFLAGS) -c $< -o $@

+ 0 - 35
kernel/src/driver/acpi/acpi.c

@@ -1,35 +0,0 @@
-#include "acpi.h"
-#include <common/kprint.h>
-#include <driver/multiboot2/multiboot2.h>
-
-extern void rs_acpi_init(uint64_t rsdp_paddr1, uint64_t rsdp_paddr2);
-
-static struct acpi_RSDP_t *rsdpv1;
-static struct acpi_RSDP_2_t *rsdpv2;
-
-static struct multiboot_tag_old_acpi_t old_acpi;
-static struct multiboot_tag_new_acpi_t new_acpi;
-
-/**
- * @brief 初始化acpi模块
- *
- */
-void acpi_init()
-{
-    kinfo("Initializing ACPI...");
-
-    // 获取物理地址
-    int reserved;
-
-    multiboot2_iter(multiboot2_get_acpi_old_RSDP, &old_acpi, &reserved);
-    rsdpv1 = &(old_acpi.rsdp);
-
-    multiboot2_iter(multiboot2_get_acpi_new_RSDP, &new_acpi, &reserved);
-    rsdpv2 = &(new_acpi.rsdp);
-
-    // rsdpv1、rsdpv2,二者有一个能成功即可
-    rs_acpi_init((uint64_t)rsdpv1, (uint64_t)rsdpv2);
-
-    kinfo("ACPI module initialized!");
-    return;
-}

+ 0 - 37
kernel/src/driver/acpi/acpi.h

@@ -1,37 +0,0 @@
-/**
- * 解析acpi信息的模块
- **/
-
-#pragma once
-
-#include <common/glib.h>
-#include <mm/mm.h>
-
-struct acpi_RSDP_t
-{
-    unsigned char Signature[8];
-    unsigned char Checksum;
-    unsigned char OEMID[6];
-
-    unsigned char Revision;
-
-    // 32bit physical address of the RSDT
-    uint RsdtAddress;
-} __attribute__((packed));
-
-struct acpi_RSDP_2_t
-{
-    struct acpi_RSDP_t rsdp1;
-
-    // fields below are only valid when the revision value is 2 or above
-    // 表的长度(单位:字节)从offset=0开始算
-    uint Length;
-    // 64bit的XSDT的物理地址
-    ul XsdtAddress;
-    unsigned char ExtendedChecksum; // 整个表的checksum,包括了之前的checksum区域
-
-    unsigned char Reserved[3];
-} __attribute__((packed));
-
-// 初始化acpi模块
-void acpi_init();

+ 0 - 8
kernel/src/driver/acpi/c_adapter.rs

@@ -1,8 +0,0 @@
-use super::acpi_manager;
-
-#[no_mangle]
-unsafe extern "C" fn rs_acpi_init(rsdp_vaddr1: u64, rsdp_vaddr2: u64) {
-    acpi_manager()
-        .init(rsdp_vaddr1, rsdp_vaddr2)
-        .expect("rs_acpi_init(): failed to init acpi");
-}

+ 52 - 32
kernel/src/driver/acpi/mod.rs

@@ -1,4 +1,4 @@
-use core::{fmt::Debug, hint::spin_loop, ptr::NonNull};
+use core::{fmt::Debug, ptr::NonNull};
 
 use acpi::{AcpiHandler, AcpiTables, PlatformInfo};
 use alloc::{string::ToString, sync::Arc};
@@ -7,6 +7,7 @@ use log::{error, info};
 use crate::{
     arch::MMArch,
     driver::base::firmware::sys_firmware_kset,
+    init::{boot::BootloaderAcpiArg, boot_params},
     libs::align::{page_align_down, page_align_up, AlignedBox},
     mm::{
         mmio_buddy::{mmio_pool, MMIOSpaceGuard},
@@ -20,7 +21,6 @@ use super::base::kset::KSet;
 extern crate acpi;
 
 pub mod bus;
-mod c_adapter;
 pub mod glue;
 pub mod pmtmr;
 mod sysfs;
@@ -56,7 +56,7 @@ impl AcpiManager {
     /// ## 参考资料
     ///
     /// https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/acpi/bus.c#1390
-    pub fn init(&self, rsdp_vaddr1: u64, rsdp_vaddr2: u64) -> Result<(), SystemError> {
+    fn init(&self) -> Result<(), SystemError> {
         info!("Initializing Acpi Manager...");
 
         // 初始化`/sys/firmware/acpi`的kset
@@ -65,45 +65,46 @@ impl AcpiManager {
         unsafe {
             ACPI_KSET_INSTANCE = Some(kset.clone());
         }
-        self.map_tables(rsdp_vaddr1, rsdp_vaddr2)?;
+        let acpi_args = boot_params().read().acpi;
+        if let BootloaderAcpiArg::NotProvided = acpi_args {
+            error!("acpi_init(): ACPI not provided by bootloader");
+            return Err(SystemError::ENODEV);
+        }
+
+        self.map_tables(acpi_args)?;
         self.bus_init()?;
         info!("Acpi Manager initialized.");
         return Ok(());
     }
 
-    fn map_tables(&self, rsdp_vaddr1: u64, rsdp_vaddr2: u64) -> Result<(), SystemError> {
-        let rsdp_paddr1 = Self::rsdp_paddr(rsdp_vaddr1);
-        let res1 = unsafe { acpi::AcpiTables::from_rsdp(AcpiHandlerImpl, rsdp_paddr1.data()) };
-        let e1;
-        match res1 {
-            // 如果rsdpv1能够获取到acpi_table,则就用该表,不用rsdpv2了
+    fn map_tables(&self, acpi_args: BootloaderAcpiArg) -> Result<(), SystemError> {
+        let table_paddr: PhysAddr = match acpi_args {
+            BootloaderAcpiArg::Rsdt(rsdpv1) => Self::rsdp_paddr(&rsdpv1),
+            BootloaderAcpiArg::Xsdt(rsdpv2) => Self::rsdp_paddr(&rsdpv2),
+            BootloaderAcpiArg::Rsdp(rsdp) => rsdp,
+            _ => {
+                error!(
+                    "AcpiManager::map_tables(): unsupported acpi_args: {:?}",
+                    acpi_args
+                );
+                return Err(SystemError::ENODEV);
+            }
+        };
+        let res = unsafe { acpi::AcpiTables::from_rsdp(AcpiHandlerImpl, table_paddr.data()) };
+        match res {
             Ok(acpi_table) => {
                 Self::set_acpi_table(acpi_table);
                 return Ok(());
             }
             Err(e) => {
-                e1 = e;
-                Self::drop_rsdp_tmp_box();
-            }
-        }
-
-        let rsdp_paddr2 = Self::rsdp_paddr(rsdp_vaddr2);
-        let res2 = unsafe { acpi::AcpiTables::from_rsdp(AcpiHandlerImpl, rsdp_paddr2.data()) };
-        match res2 {
-            Ok(acpi_table) => {
-                Self::set_acpi_table(acpi_table);
-            }
-            // 如果rsdpv1和rsdpv2都无法获取到acpi_table,说明有问题,打印报错信息后进入死循环
-            Err(e2) => {
-                error!("acpi_init(): failed to parse acpi tables, error: (rsdpv1: {:?}) or (rsdpv2: {:?})", e1, e2);
+                error!(
+                    "AcpiManager::map_tables(): failed to map tables, error: {:?}",
+                    e
+                );
                 Self::drop_rsdp_tmp_box();
-                loop {
-                    spin_loop();
-                }
+                return Err(SystemError::ENODEV);
             }
         }
-
-        return Ok(());
     }
 
     /// 通过RSDP虚拟地址获取RSDP物理地址
@@ -115,13 +116,18 @@ impl AcpiManager {
     /// ## 返回值
     ///
     /// RSDP物理地址
-    fn rsdp_paddr(rsdp_vaddr: u64) -> PhysAddr {
+    fn rsdp_paddr(rsdp_instance: &acpi::rsdp::Rsdp) -> PhysAddr {
         unsafe {
             RSDP_TMP_BOX = Some(AlignedBox::new_zeroed().expect("rs_acpi_init(): failed to alloc"))
         };
+
         let size = core::mem::size_of::<acpi::rsdp::Rsdp>();
-        let tmp_data =
-            unsafe { core::slice::from_raw_parts(rsdp_vaddr as usize as *const u8, size) };
+        let tmp_data = unsafe {
+            core::slice::from_raw_parts(
+                rsdp_instance as *const acpi::rsdp::Rsdp as usize as *const u8,
+                size,
+            )
+        };
         unsafe { RSDP_TMP_BOX.as_mut().unwrap()[0..size].copy_from_slice(tmp_data) };
         let rsdp_paddr = unsafe {
             MMArch::virt_2_phys(VirtAddr::new(
@@ -221,3 +227,17 @@ impl AcpiHandler for AcpiHandlerImpl {
         drop(mmio_guard);
     }
 }
+
+#[inline(never)]
+pub fn acpi_init() -> Result<(), SystemError> {
+    #[cfg(target_arch = "x86_64")]
+    {
+        acpi_manager().init()
+    }
+
+    #[cfg(not(target_arch = "x86_64"))]
+    {
+        log::warn!("acpi_init(): unsupported arch");
+        return Ok(());
+    }
+}

+ 115 - 3
kernel/src/driver/base/block/block_device.rs

@@ -13,12 +13,12 @@ use crate::driver::{
     block::cache::{cached_block_device::BlockCache, BlockCacheError, BLOCK_SIZE},
 };
 
-use alloc::{sync::Arc, vec::Vec};
-use core::any::Any;
+use alloc::{string::String, sync::Arc, vec::Vec};
+use core::{any::Any, fmt::Display, ops::Deref};
 use log::error;
 use system_error::SystemError;
 
-use super::disk_info::Partition;
+use super::{disk_info::Partition, gendisk::GenDisk, manager::BlockDevMeta};
 
 /// 该文件定义了 Device 和 BlockDevice 的接口
 /// Notice 设备错误码使用 Posix 规定的 int32_t 的错误码表示,而不是自己定义错误enum
@@ -36,6 +36,41 @@ pub const BLK_SIZE_LOG2_LIMIT: u8 = 12; // 设定块设备的块大小不能超
 /// 在DragonOS中,我们认为磁盘的每个LBA大小均为512字节。(注意,文件系统的1个扇区可能事实上是多个LBA)
 pub const LBA_SIZE: usize = 512;
 
+#[derive(Debug, Clone, Copy)]
+pub struct GeneralBlockRange {
+    pub lba_start: usize,
+    pub lba_end: usize,
+}
+
+impl GeneralBlockRange {
+    pub fn new(lba_start: usize, lba_end: usize) -> Option<Self> {
+        if lba_start >= lba_end {
+            return None;
+        }
+        return Some(GeneralBlockRange { lba_start, lba_end });
+    }
+
+    #[inline]
+    pub fn len(&self) -> usize {
+        return self.lba_end - self.lba_start;
+    }
+
+    /// 取交集
+    pub fn intersects_with(&self, rhs: &Self) -> Option<Self> {
+        // 检查是否相交
+        if self.lba_start <= rhs.lba_end && self.lba_end >= rhs.lba_start {
+            // 计算相交部分的起始和结束 LBA
+            let start = usize::max(self.lba_start, rhs.lba_start);
+            let end = usize::min(self.lba_end, rhs.lba_end);
+            // 返回相交部分
+            GeneralBlockRange::new(start, end)
+        } else {
+            // 不相交,返回 None
+            None
+        }
+    }
+}
+
 /// @brief 块设备的迭代器
 /// @usage 某次操作读/写块设备的[L,R]范围内的字节,
 ///        那么可以使用此结构体进行迭代遍历,每次调用next()返回一个BlockRange
@@ -186,8 +221,80 @@ pub fn __lba_to_bytes(lba_id: usize, blk_size: usize) -> BlockId {
     return lba_id * blk_size;
 }
 
+/// 块设备的名字
+pub struct BlockDevName {
+    name: Arc<String>,
+    id: usize,
+}
+
+impl BlockDevName {
+    pub fn new(name: String, id: usize) -> Self {
+        return BlockDevName {
+            name: Arc::new(name),
+            id,
+        };
+    }
+
+    #[inline]
+    pub fn id(&self) -> usize {
+        return self.id;
+    }
+}
+
+impl core::fmt::Debug for BlockDevName {
+    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+        return write!(f, "{}", self.name);
+    }
+}
+
+impl Display for BlockDevName {
+    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+        return write!(f, "{}", self.name);
+    }
+}
+
+impl Clone for BlockDevName {
+    fn clone(&self) -> Self {
+        return BlockDevName {
+            name: self.name.clone(),
+            id: self.id,
+        };
+    }
+}
+
+impl core::hash::Hash for BlockDevName {
+    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
+        self.name.hash(state);
+    }
+}
+
+impl Deref for BlockDevName {
+    type Target = String;
+
+    fn deref(&self) -> &Self::Target {
+        return self.name.as_ref();
+    }
+}
+
+impl PartialEq for BlockDevName {
+    fn eq(&self, other: &Self) -> bool {
+        return self.name == other.name;
+    }
+}
+
+impl Eq for BlockDevName {}
+
 /// @brief 块设备应该实现的操作
 pub trait BlockDevice: Device {
+    /// # dev_name
+    /// 返回块设备的名字
+    fn dev_name(&self) -> &BlockDevName;
+
+    fn blkdev_meta(&self) -> &BlockDevMeta;
+
+    /// 获取设备的扇区范围
+    fn disk_range(&self) -> GeneralBlockRange;
+
     /// @brief: 在块设备中,从第lba_id_start个块开始,读取count个块数据,存放到buf中
     ///
     /// @parameter lba_id_start: 起始块
@@ -379,6 +486,11 @@ pub trait BlockDevice: Device {
         }
         return Ok(len);
     }
+
+    /// # gendisk注册成功的回调函数
+    fn callback_gendisk_registered(&self, _gendisk: &Arc<GenDisk>) -> Result<(), SystemError> {
+        Ok(())
+    }
 }
 
 /// @brief 块设备框架函数集

+ 34 - 12
kernel/src/driver/base/block/disk_info.rs

@@ -1,22 +1,19 @@
 #![allow(dead_code)]
 use alloc::sync::{Arc, Weak};
+use system_error::SystemError;
 
-use super::block_device::BlockDevice;
+use super::block_device::{BlockDevice, GeneralBlockRange};
 
 pub type SectorT = u64;
 
-pub const BLK_TYPE_AHCI: u64 = 0;
-pub const DISK_NAME_LEN: usize = 32; // 磁盘名称的最大长度
-pub const BLK_GF_AHCI: u16 = 1 << 0; // 定义blk_gendisk中的标志位
-
 /// @brief: 磁盘的分区信息 - (保留了c版本的数据信息)
 #[derive(Debug)]
 pub struct Partition {
-    pub start_sector: SectorT,   // 该分区的起始扇区
-    pub lba_start: u64,          // 起始LBA号
-    pub sectors_num: u64,        // 该分区的扇区数
-    disk: Weak<dyn BlockDevice>, // 当前分区所属的磁盘
-    pub partno: u16,             // 在磁盘上的分区号
+    pub start_sector: SectorT,           // 该分区的起始扇区
+    pub lba_start: u64,                  // 起始LBA号
+    pub sectors_num: u64,                // 该分区的扇区数
+    disk: Option<Weak<dyn BlockDevice>>, // 当前分区所属的磁盘
+    pub partno: u16,                     // 在磁盘上的分区号
 }
 
 /// @brief: 分区信息 - 成员函数
@@ -33,14 +30,39 @@ impl Partition {
             start_sector,
             lba_start,
             sectors_num,
-            disk,
+            disk: Some(disk),
             partno,
         });
     }
 
+    pub fn new_raw(start_sector: SectorT, lba_start: u64, sectors_num: u64, partno: u16) -> Self {
+        return Partition {
+            start_sector,
+            lba_start,
+            sectors_num,
+            disk: None,
+            partno,
+        };
+    }
+
     /// @brief 获取当前分区所属的磁盘的Arc指针
     #[inline]
     pub fn disk(&self) -> Arc<dyn BlockDevice> {
-        return self.disk.upgrade().unwrap();
+        return self.disk.as_ref().unwrap().upgrade().unwrap();
+    }
+}
+
+impl TryInto<GeneralBlockRange> for Partition {
+    type Error = SystemError;
+
+    fn try_into(self) -> Result<GeneralBlockRange, Self::Error> {
+        if let Some(range) = GeneralBlockRange::new(
+            self.lba_start as usize,
+            (self.lba_start + self.sectors_num) as usize,
+        ) {
+            return Ok(range);
+        } else {
+            return Err(SystemError::EINVAL);
+        }
     }
 }

+ 195 - 0
kernel/src/driver/base/block/gendisk.rs

@@ -0,0 +1,195 @@
+use core::{
+    ops::{Deref, DerefMut},
+    sync::atomic::{AtomicU32, Ordering},
+};
+
+use alloc::sync::{Arc, Weak};
+use hashbrown::HashMap;
+use system_error::SystemError;
+
+use super::block_device::{BlockDevice, BlockId, GeneralBlockRange, LBA_SIZE};
+
+#[derive(Debug)]
+pub struct GenDisk {
+    bdev: Weak<dyn BlockDevice>,
+    range: GeneralBlockRange,
+    block_size_log2: u8,
+    idx: Option<u32>,
+}
+
+impl GenDisk {
+    /// 如果gendisk是整个磁盘,则idx为u32::MAX
+    pub const ENTIRE_DISK_IDX: u32 = u32::MAX;
+
+    pub fn new(
+        bdev: Weak<dyn BlockDevice>,
+        range: GeneralBlockRange,
+        idx: Option<u32>,
+    ) -> Arc<Self> {
+        let bsizelog2 = bdev.upgrade().unwrap().blk_size_log2();
+
+        return Arc::new(GenDisk {
+            bdev,
+            range,
+            block_size_log2: bsizelog2,
+            idx,
+        });
+    }
+
+    pub fn block_device(&self) -> Arc<dyn BlockDevice> {
+        return self.bdev.upgrade().unwrap();
+    }
+
+    /// # read_at
+    ///
+    /// 读取分区内的数据
+    ///
+    /// ## 参数
+    ///
+    /// - buf: 输出缓冲区,大小必须为LBA_SIZE的整数倍,否则返回EINVAL
+    /// - start_block_offset: 分区内的块号
+    pub fn read_at(
+        &self,
+        buf: &mut [u8],
+        start_block_offset: BlockId,
+    ) -> Result<usize, SystemError> {
+        if (buf.len() & (LBA_SIZE - 1)) > 0 {
+            return Err(SystemError::EINVAL);
+        }
+
+        let blocks = buf.len() / (1 << self.block_size_log2 as usize);
+        let lba = self.block_offset_2_disk_blkid(start_block_offset);
+
+        return self.block_device().read_at(lba, blocks, buf);
+    }
+
+    /// # read_at_bytes
+    ///
+    /// 按字节偏移量从分区中读取数据
+    ///
+    /// ## 参数
+    ///
+    /// - buf: 输出缓冲区
+    /// - bytes_offset: 分区内的字节偏移量
+    pub fn read_at_bytes(&self, buf: &mut [u8], bytes_offset: usize) -> Result<usize, SystemError> {
+        let start_lba = self.range.lba_start;
+        let bytes_offset = self.disk_blkid_2_bytes(start_lba) + bytes_offset;
+        return self
+            .block_device()
+            .read_at_bytes(bytes_offset, buf.len(), buf);
+    }
+
+    /// # 分区内的字节偏移量转换为磁盘上的字节偏移量
+    pub fn disk_bytes_offset(&self, bytes_offset: usize) -> usize {
+        let start_lba = self.range.lba_start;
+        return self.disk_blkid_2_bytes(start_lba) + bytes_offset;
+    }
+
+    /// # write_at_bytes
+    ///
+    /// 按字节偏移量向分区写入数据
+    ///
+    /// ## 参数
+    ///
+    /// - buf: 输入缓冲区
+    /// - bytes_offset: 分区内的字节偏移量
+    pub fn write_at_bytes(&self, buf: &[u8], bytes_offset: usize) -> Result<usize, SystemError> {
+        let start_lba = self.range.lba_start;
+        let bytes_offset = self.disk_blkid_2_bytes(start_lba) + bytes_offset;
+        return self
+            .block_device()
+            .write_at_bytes(bytes_offset, buf.len(), buf);
+    }
+
+    /// # write_at
+    ///
+    /// 向分区内写入数据
+    ///
+    /// ## 参数
+    ///
+    /// - buf: 输入缓冲区,大小必须为LBA_SIZE的整数倍,否则返回EINVAL
+    /// - start_block_offset: 分区内的块号
+    pub fn write_at(&self, buf: &[u8], start_block_offset: BlockId) -> Result<usize, SystemError> {
+        if (buf.len() & (LBA_SIZE - 1)) > 0 {
+            return Err(SystemError::EINVAL);
+        }
+
+        let blocks = buf.len() / (1 << self.block_size_log2 as usize);
+        let lba = self.block_offset_2_disk_blkid(start_block_offset);
+        return self.block_device().write_at(lba, blocks, buf);
+    }
+
+    #[inline]
+    fn block_offset_2_disk_blkid(&self, block_offset: BlockId) -> BlockId {
+        self.range.lba_start + block_offset
+    }
+
+    #[inline]
+    fn disk_blkid_2_bytes(&self, disk_blkid: BlockId) -> usize {
+        disk_blkid * LBA_SIZE
+    }
+
+    #[inline]
+    pub fn idx(&self) -> u32 {
+        self.idx.unwrap_or(Self::ENTIRE_DISK_IDX)
+    }
+
+    #[inline]
+    pub fn range(&self) -> &GeneralBlockRange {
+        &self.range
+    }
+
+    /// # sync
+    /// 同步磁盘
+    pub fn sync(&self) -> Result<(), SystemError> {
+        self.block_device().sync()
+    }
+}
+
+#[derive(Default)]
+pub struct GenDiskMap {
+    data: HashMap<u32, Arc<GenDisk>>,
+    max_idx: AtomicU32,
+}
+
+impl GenDiskMap {
+    pub fn new() -> Self {
+        GenDiskMap {
+            data: HashMap::new(),
+            max_idx: AtomicU32::new(1),
+        }
+    }
+
+    #[inline]
+    pub fn max_idx(&self) -> u32 {
+        self.max_idx.load(Ordering::SeqCst)
+    }
+
+    #[inline]
+    pub fn alloc_idx(&self) -> u32 {
+        self.max_idx.fetch_add(1, Ordering::SeqCst)
+    }
+
+    pub fn intersects(&self, range: &GeneralBlockRange) -> bool {
+        for (_, v) in self.iter() {
+            if range.intersects_with(&v.range).is_some() {
+                return true;
+            }
+        }
+        return false;
+    }
+}
+
+impl Deref for GenDiskMap {
+    type Target = HashMap<u32, Arc<GenDisk>>;
+
+    fn deref(&self) -> &Self::Target {
+        &self.data
+    }
+}
+
+impl DerefMut for GenDiskMap {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        &mut self.data
+    }
+}

+ 238 - 0
kernel/src/driver/base/block/manager.rs

@@ -0,0 +1,238 @@
+use core::fmt::Formatter;
+
+use alloc::sync::Arc;
+use hashbrown::HashMap;
+use system_error::SystemError;
+use unified_init::macros::unified_init;
+
+use crate::{
+    driver::base::block::gendisk::GenDisk,
+    filesystem::mbr::MbrDiskPartionTable,
+    init::initcall::INITCALL_POSTCORE,
+    libs::spinlock::{SpinLock, SpinLockGuard},
+};
+
+use super::{
+    block_device::{BlockDevName, BlockDevice, GeneralBlockRange},
+    gendisk::GenDiskMap,
+};
+
+static mut BLOCK_DEV_MANAGER: Option<BlockDevManager> = None;
+
+#[inline]
+pub fn block_dev_manager() -> &'static BlockDevManager {
+    unsafe { BLOCK_DEV_MANAGER.as_ref().unwrap() }
+}
+
+#[unified_init(INITCALL_POSTCORE)]
+pub fn block_dev_manager_init() -> Result<(), SystemError> {
+    unsafe {
+        BLOCK_DEV_MANAGER = Some(BlockDevManager::new());
+    }
+    Ok(())
+}
+
+/// 磁盘设备管理器
+pub struct BlockDevManager {
+    inner: SpinLock<InnerBlockDevManager>,
+}
+
+struct InnerBlockDevManager {
+    disks: HashMap<BlockDevName, Arc<dyn BlockDevice>>,
+}
+impl BlockDevManager {
+    pub fn new() -> Self {
+        BlockDevManager {
+            inner: SpinLock::new(InnerBlockDevManager {
+                disks: HashMap::new(),
+            }),
+        }
+    }
+
+    fn inner(&self) -> SpinLockGuard<InnerBlockDevManager> {
+        self.inner.lock()
+    }
+
+    /// 注册磁盘设备
+    pub fn register(&self, dev: Arc<dyn BlockDevice>) -> Result<(), SystemError> {
+        let mut inner = self.inner();
+        let dev_name = dev.dev_name();
+        if inner.disks.contains_key(dev_name) {
+            return Err(SystemError::EEXIST);
+        }
+        inner.disks.insert(dev_name.clone(), dev.clone());
+
+        let mut out_remove = || {
+            inner.disks.remove(dev_name);
+        };
+
+        // 检测分区表,并创建gendisk
+        self.check_partitions(&dev).inspect_err(|_| out_remove())?;
+        Ok(())
+    }
+
+    /// 检测分区表,并创建gendisk
+    fn check_partitions(&self, dev: &Arc<dyn BlockDevice>) -> Result<(), SystemError> {
+        if self.check_mbr(dev).is_ok() {
+            return Ok(());
+        }
+
+        // use entire disk as a gendisk
+        self.register_entire_disk_as_gendisk(dev)
+    }
+
+    fn check_mbr(&self, dev: &Arc<dyn BlockDevice>) -> Result<(), SystemError> {
+        let mbr = MbrDiskPartionTable::from_disk(dev.clone())?;
+        let piter = mbr.partitions_raw();
+        for p in piter {
+            self.register_gendisk_with_range(dev, p.try_into()?)?;
+        }
+        Ok(())
+    }
+
+    /// 将整个磁盘注册为gendisk
+    fn register_entire_disk_as_gendisk(
+        &self,
+        dev: &Arc<dyn BlockDevice>,
+    ) -> Result<(), SystemError> {
+        let range = dev.disk_range();
+        self.register_gendisk_with_range(dev, range)
+    }
+
+    fn register_gendisk_with_range(
+        &self,
+        dev: &Arc<dyn BlockDevice>,
+        range: GeneralBlockRange,
+    ) -> Result<(), SystemError> {
+        let weak_dev = Arc::downgrade(dev);
+        let gendisk = GenDisk::new(
+            weak_dev,
+            range,
+            Some(dev.blkdev_meta().inner().gendisks.alloc_idx()),
+        );
+        self.register_gendisk(dev, gendisk)
+    }
+
+    fn register_gendisk(
+        &self,
+        dev: &Arc<dyn BlockDevice>,
+        gendisk: Arc<GenDisk>,
+    ) -> Result<(), SystemError> {
+        let blk_meta = dev.blkdev_meta();
+        let idx = gendisk.idx();
+        let mut meta_inner = blk_meta.inner();
+        // 检查是否重复
+        if meta_inner.gendisks.intersects(gendisk.range()) {
+            return Err(SystemError::EEXIST);
+        }
+
+        meta_inner.gendisks.insert(idx, gendisk.clone());
+        dev.callback_gendisk_registered(&gendisk).inspect_err(|_| {
+            meta_inner.gendisks.remove(&idx);
+        })?;
+        Ok(())
+    }
+
+    /// 卸载磁盘设备
+    pub fn unregister(&self, dev: &Arc<dyn BlockDevice>) {
+        let mut inner = self.inner();
+        inner.disks.remove(dev.dev_name());
+        // todo: 这里应该callback一下磁盘设备,但是现在还没实现热插拔,所以暂时没做这里
+        todo!("BlockDevManager: unregister disk")
+    }
+
+    /// 通过路径查找gendisk
+    ///
+    /// # 参数
+    ///
+    /// - `path`: 分区路径 `/dev/sda1` 或者 `sda1`,或者是`/dev/sda`
+    pub fn lookup_gendisk_by_path(&self, path: &str) -> Option<Arc<GenDisk>> {
+        let (devname, partno) = self.path2devname(path)?;
+        let inner = self.inner();
+        for dev in inner.disks.values() {
+            if dev.dev_name().as_str() == devname {
+                return dev.blkdev_meta().inner().gendisks.get(&partno).cloned();
+            }
+        }
+        None
+    }
+
+    /// 打印所有的gendisk的路径
+    pub fn print_gendisks(&self) {
+        let mut disks = alloc::vec::Vec::new();
+
+        let inner = self.inner();
+        for dev in inner.disks.values() {
+            let meta = dev.blkdev_meta().inner();
+            for idx in meta.gendisks.keys() {
+                if idx == &GenDisk::ENTIRE_DISK_IDX {
+                    disks.push(format!("/dev/{}", dev.dev_name()));
+                } else {
+                    disks.push(format!("/dev/{}{}", dev.dev_name(), idx));
+                }
+            }
+        }
+
+        log::debug!("All gendisks: {:?}", disks);
+    }
+
+    /// 将路径转换为设备名以及分区号
+    ///
+    /// 例如: sda1 -> (sda, 1)  nvme0n1p1 -> (nvme0n1, 1)
+    fn path2devname<'a>(&self, mut path: &'a str) -> Option<(&'a str, u32)> {
+        // 去除开头的"/dev/"
+        if path.starts_with("/dev/") {
+            path = path.strip_prefix("/dev/")?;
+        }
+
+        let mut partno = GenDisk::ENTIRE_DISK_IDX;
+        // 截取末尾数字
+        let mut last_digit = path.len();
+        while last_digit > 0 && path.chars().nth(last_digit - 1).unwrap().is_ascii_digit() {
+            last_digit -= 1;
+        }
+        if last_digit == 0 {
+            return (path, GenDisk::ENTIRE_DISK_IDX).into();
+        }
+
+        if last_digit < path.len() {
+            partno = path[last_digit..].parse().ok()?;
+        }
+
+        let path = &path[..last_digit];
+
+        Some((path, partno))
+    }
+}
+
+pub struct BlockDevMeta {
+    pub devname: BlockDevName,
+    inner: SpinLock<InnerBlockDevMeta>,
+}
+
+pub struct InnerBlockDevMeta {
+    pub gendisks: GenDiskMap,
+}
+
+impl BlockDevMeta {
+    pub fn new(devname: BlockDevName) -> Self {
+        BlockDevMeta {
+            devname,
+            inner: SpinLock::new(InnerBlockDevMeta {
+                gendisks: GenDiskMap::new(),
+            }),
+        }
+    }
+
+    fn inner(&self) -> SpinLockGuard<InnerBlockDevMeta> {
+        self.inner.lock()
+    }
+}
+
+impl core::fmt::Debug for BlockDevMeta {
+    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
+        f.debug_struct("BlockDevMeta")
+            .field("devname", &self.devname)
+            .finish()
+    }
+}

+ 3 - 0
kernel/src/driver/base/block/mod.rs

@@ -1,5 +1,8 @@
 pub mod block_device;
 pub mod disk_info;
+pub mod gendisk;
+pub mod manager;
+
 #[derive(Debug)]
 #[allow(dead_code)]
 pub enum SeekFrom {

+ 24 - 22
kernel/src/driver/base/cpu.rs

@@ -18,9 +18,9 @@ use super::{
     device::{
         bus::{subsystem_manager, Bus},
         driver::Driver,
-        Device, DeviceType, IdTable,
+        Device, DeviceCommonData, DeviceType, IdTable,
     },
-    kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
+    kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
     kset::KSet,
     subsys::SubSysPrivate,
 };
@@ -123,23 +123,17 @@ impl CpuSubSystemFakeRootDevice {
 
 #[derive(Debug)]
 struct InnerCpuSubSystemFakeRootDevice {
-    parent_kobj: Option<Weak<dyn KObject>>,
-    bus: Option<Weak<dyn Bus>>,
-    kset: Option<Arc<KSet>>,
+    kobject_common: KObjectCommonData,
+    device_common: DeviceCommonData,
     name: String,
-    kern_inode: Option<Arc<KernFSInode>>,
-    ktype: Option<&'static dyn KObjType>,
 }
 
 impl InnerCpuSubSystemFakeRootDevice {
     pub fn new() -> Self {
         return Self {
-            parent_kobj: None,
-            bus: None,
-            kset: None,
+            kobject_common: KObjectCommonData::default(),
+            device_common: DeviceCommonData::default(),
             name: "".to_string(),
-            kern_inode: None,
-            ktype: None,
         };
     }
 }
@@ -154,11 +148,11 @@ impl Device for CpuSubSystemFakeRootDevice {
     }
 
     fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
-        self.inner.write().bus = bus;
+        self.inner.write().device_common.bus = bus;
     }
 
     fn bus(&self) -> Option<Weak<dyn Bus>> {
-        self.inner.read().bus.clone()
+        self.inner.read().device_common.bus.clone()
     }
 
     fn driver(&self) -> Option<Arc<dyn Driver>> {
@@ -188,6 +182,14 @@ impl Device for CpuSubSystemFakeRootDevice {
     fn set_class(&self, _class: Option<Weak<dyn Class>>) {
         todo!()
     }
+
+    fn dev_parent(&self) -> Option<Weak<dyn Device>> {
+        self.inner.read().device_common.parent.clone()
+    }
+
+    fn set_dev_parent(&self, dev_parent: Option<Weak<dyn Device>>) {
+        self.inner.write().device_common.parent = dev_parent;
+    }
 }
 
 impl KObject for CpuSubSystemFakeRootDevice {
@@ -196,35 +198,35 @@ impl KObject for CpuSubSystemFakeRootDevice {
     }
 
     fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
-        self.inner.write().kern_inode = inode;
+        self.inner.write().kobject_common.kern_inode = inode;
     }
 
     fn inode(&self) -> Option<Arc<KernFSInode>> {
-        self.inner.read().kern_inode.clone()
+        self.inner.read().kobject_common.kern_inode.clone()
     }
 
     fn parent(&self) -> Option<Weak<dyn KObject>> {
-        self.inner.read().parent_kobj.clone()
+        self.inner.read().kobject_common.parent.clone()
     }
 
     fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
-        self.inner.write().parent_kobj = parent;
+        self.inner.write().kobject_common.parent = parent;
     }
 
     fn kset(&self) -> Option<Arc<KSet>> {
-        self.inner.read().kset.clone()
+        self.inner.read().kobject_common.kset.clone()
     }
 
     fn set_kset(&self, kset: Option<Arc<KSet>>) {
-        self.inner.write().kset = kset;
+        self.inner.write().kobject_common.kset = kset;
     }
 
     fn kobj_type(&self) -> Option<&'static dyn KObjType> {
-        self.inner.read().ktype
+        self.inner.read().kobject_common.kobj_type
     }
 
     fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
-        self.inner.write().ktype = ktype;
+        self.inner.write().kobject_common.kobj_type = ktype;
     }
 
     fn name(&self) -> String {

+ 8 - 2
kernel/src/driver/base/device/bus.rs

@@ -299,9 +299,14 @@ impl BusManager {
             .ok_or(SystemError::EINVAL)?;
         debug!("bus '{}' add driver '{}'", bus.name(), driver.name());
 
-        driver.set_kobj_type(Some(&BusDriverKType));
+        // driver.set_kobj_type(Some(&BusDriverKType));
         let kobj = driver.clone() as Arc<dyn KObject>;
-        KObjectManager::add_kobj(kobj, bus.subsystem().drivers_kset())?;
+        // KObjectManager::add_kobj(kobj, bus.subsystem().drivers_kset())?;
+        KObjectManager::init_and_add_kobj(
+            kobj,
+            bus.subsystem().drivers_kset(),
+            Some(&BusDriverKType),
+        )?;
 
         bus.subsystem().add_driver_to_vec(driver)?;
         if bus.subsystem().drivers_autoprobe() {
@@ -451,6 +456,7 @@ impl BusManager {
         }
         let bus = bus.unwrap();
         if bus.subsystem().drivers_autoprobe() {
+            log::info!("MT bus '{}' autoprobe driver", bus.name());
             device_manager().device_initial_probe(dev).ok();
         }
         for interface in bus.subsystem().interfaces() {

+ 176 - 28
kernel/src/driver/base/device/mod.rs

@@ -1,4 +1,5 @@
 use alloc::{
+    collections::BTreeMap,
     string::{String, ToString},
     sync::{Arc, Weak},
 };
@@ -12,16 +13,21 @@ use crate::{
     },
     exception::irqdata::IrqHandlerData,
     filesystem::{
+        kernfs::KernFSInode,
         sysfs::{
             file::sysfs_emit_str, sysfs_instance, Attribute, AttributeGroup, SysFSOps,
             SysFSOpsSupport,
         },
         vfs::syscall::ModeType,
     },
+    libs::{
+        rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
+        spinlock::{SpinLock, SpinLockGuard},
+    },
 };
 
-use core::fmt::Debug;
 use core::intrinsics::unlikely;
+use core::{any::Any, fmt::Debug};
 use system_error::SystemError;
 
 use self::{
@@ -31,8 +37,10 @@ use self::{
 };
 
 use super::{
-    class::Class,
-    kobject::{KObjType, KObject, KObjectManager, KObjectState},
+    class::{Class, ClassKObjbectType},
+    kobject::{
+        KObjType, KObject, KObjectCommonData, KObjectManager, KObjectState, LockedKObjectState,
+    },
     kset::KSet,
     swnode::software_node_notify,
 };
@@ -193,6 +201,10 @@ pub trait Device: KObject {
     fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
         None
     }
+
+    fn dev_parent(&self) -> Option<Weak<dyn Device>>;
+
+    fn set_dev_parent(&self, parent: Option<Weak<dyn Device>>);
 }
 
 impl dyn Device {
@@ -210,6 +222,7 @@ pub struct DeviceCommonData {
     pub driver: Option<Weak<dyn Driver>>,
     pub dead: bool,
     pub can_match: bool,
+    pub parent: Option<Weak<dyn Device>>,
 }
 
 impl Default for DeviceCommonData {
@@ -220,6 +233,7 @@ impl Default for DeviceCommonData {
             driver: None,
             dead: false,
             can_match: true,
+            parent: None,
         }
     }
 }
@@ -245,6 +259,13 @@ impl DeviceCommonData {
     pub fn get_driver_weak_or_clear(&mut self) -> Option<Weak<dyn Driver>> {
         driver_base_macros::get_weak_or_clear!(self.driver)
     }
+
+    /// 获取parent字段
+    ///
+    /// 当weak指针的strong count为0的时候,清除弱引用
+    pub fn get_parent_weak_or_clear(&mut self) -> Option<Weak<dyn Device>> {
+        driver_base_macros::get_weak_or_clear!(self.parent)
+    }
 }
 
 // 暂定是不可修改的,在初始化的时候就要确定。以后可能会包括例如硬件中断包含的信息
@@ -475,21 +496,26 @@ impl DeviceManager {
     #[allow(dead_code)]
     pub fn add_device(&self, device: Arc<dyn Device>) -> Result<(), SystemError> {
         // 在这里处理与parent相关的逻辑
-
-        let current_parent = device
-            .parent()
-            .and_then(|x| x.upgrade())
-            .and_then(|x| x.arc_any().cast::<dyn Device>().ok());
-
-        let actual_parent = self.get_device_parent(&device, current_parent)?;
-        if let Some(actual_parent) = actual_parent {
+        let deivce_parent = device.dev_parent().and_then(|x| x.upgrade());
+        if let Some(ref dev) = deivce_parent {
+            log::info!(
+                "deivce: {:?}  dev parent: {:?}",
+                device.name().to_string(),
+                dev.name()
+            );
+        }
+        let kobject_parent = self.get_device_parent(&device, deivce_parent)?;
+        if let Some(ref kobj) = kobject_parent {
+            log::debug!("kobject parent: {:?}", kobj.name());
+        }
+        if let Some(kobject_parent) = kobject_parent {
             // debug!(
             //     "device '{}' parent is '{}', strong_count: {}",
             //     device.name().to_string(),
             //     actual_parent.name(),
             //     Arc::strong_count(&actual_parent)
             // );
-            device.set_parent(Some(Arc::downgrade(&actual_parent)));
+            device.set_parent(Some(Arc::downgrade(&kobject_parent)));
         }
 
         KObjectManager::add_kobj(device.clone() as Arc<dyn KObject>, None).map_err(|e| {
@@ -536,12 +562,43 @@ impl DeviceManager {
         return Ok(());
     }
 
+    /// 用于创建并添加一个新的kset,表示一个设备类目录
+    /// 参考:https://code.dragonos.org.cn/xref/linux-6.6.21/drivers/base/core.c#3159
+    fn class_dir_create_and_add(
+        &self,
+        class: Arc<dyn Class>,
+        kobject_parent: Arc<dyn KObject>,
+    ) -> Arc<dyn KObject> {
+        let mut guard = CLASS_DIR_KSET_INSTANCE.write();
+        let class_name: String = class.name().to_string();
+        let kobject_parent_name = kobject_parent.name();
+        let key = format!("{}-{}", class_name, kobject_parent_name);
+
+        // 检查设备类目录是否已经存在
+        if let Some(class_dir) = guard.get(&key) {
+            return class_dir.clone();
+        }
+
+        let class_dir: Arc<ClassDir> = ClassDir::new();
+
+        class_dir.set_name(class_name.clone());
+        class_dir.set_kobj_type(Some(&ClassKObjbectType));
+        class_dir.set_parent(Some(Arc::downgrade(&kobject_parent)));
+
+        KObjectManager::add_kobj(class_dir.clone() as Arc<dyn KObject>, None)
+            .expect("add class dir failed");
+
+        guard.insert(key, class_dir.clone());
+
+        return class_dir;
+    }
+
     /// 获取设备真实的parent kobject
     ///
     /// ## 参数
     ///
     /// - `device`: 设备
-    /// - `current_parent`: 当前的parent kobject
+    /// - `device_parent`: 父设备
     ///
     /// ## 返回值
     ///
@@ -551,29 +608,31 @@ impl DeviceManager {
     fn get_device_parent(
         &self,
         device: &Arc<dyn Device>,
-        current_parent: Option<Arc<dyn Device>>,
+        device_parent: Option<Arc<dyn Device>>,
     ) -> Result<Option<Arc<dyn KObject>>, SystemError> {
         // debug!("get_device_parent() device:{:?}", device.name());
         if device.class().is_some() {
-            let parent_kobj: Arc<dyn KObject>;
-            // debug!("current_parent:{:?}", current_parent);
-            if let Some(cp) = current_parent {
-                if cp.class().is_some() {
-                    return Ok(Some(cp.clone() as Arc<dyn KObject>));
+            let kobject_parent: Arc<dyn KObject>;
+            if let Some(dp) = device_parent {
+                if dp.class().is_some() {
+                    return Ok(Some(dp.clone() as Arc<dyn KObject>));
                 } else {
-                    parent_kobj = cp.clone() as Arc<dyn KObject>;
+                    kobject_parent = dp.clone() as Arc<dyn KObject>;
                 }
             } else {
-                parent_kobj = sys_devices_virtual_kset() as Arc<dyn KObject>;
+                kobject_parent = sys_devices_virtual_kset() as Arc<dyn KObject>;
             }
 
             // 是否需要glue dir?
 
-            return Ok(Some(parent_kobj));
+            let kobject_parent =
+                self.class_dir_create_and_add(device.class().unwrap(), kobject_parent.clone());
+
+            return Ok(Some(kobject_parent));
         }
 
         // subsystems can specify a default root directory for their devices
-        if current_parent.is_none() {
+        if device_parent.is_none() {
             if let Some(bus) = device.bus().and_then(|bus| bus.upgrade()) {
                 if let Some(root) = bus.root_device().and_then(|x| x.upgrade()) {
                     return Ok(Some(root as Arc<dyn KObject>));
@@ -581,8 +640,8 @@ impl DeviceManager {
             }
         }
 
-        if let Some(current_parent) = current_parent {
-            return Ok(Some(current_parent as Arc<dyn KObject>));
+        if let Some(device_parent) = device_parent {
+            return Ok(Some(device_parent as Arc<dyn KObject>));
         }
 
         return Ok(None);
@@ -641,9 +700,8 @@ impl DeviceManager {
         let subsys_kobj = class.subsystem().subsys() as Arc<dyn KObject>;
         sysfs_instance().create_link(Some(&dev_kobj), &subsys_kobj, "subsystem".to_string())?;
 
-        // todo: 这里需要处理class的parent逻辑, 添加device链接
-        if let Some(parent) = dev.parent().and_then(|x| x.upgrade()) {
-            let parent_kobj = parent.clone() as Arc<dyn KObject>;
+        if let Some(dev_parent) = dev.dev_parent().and_then(|x| x.upgrade()) {
+            let parent_kobj = dev_parent.clone() as Arc<dyn KObject>;
             sysfs_instance()
                 .create_link(Some(&dev_kobj), &parent_kobj, "device".to_string())
                 .inspect_err(|_e| {
@@ -966,3 +1024,93 @@ impl core::hash::Hash for DeviceId {
 impl Eq for DeviceId {}
 
 impl IrqHandlerData for DeviceId {}
+
+lazy_static! {
+    /// class_dir列表,通过parent kobject的name和class_dir的name来索引class_dir实例
+    static ref CLASS_DIR_KSET_INSTANCE: RwLock<BTreeMap<String, Arc<ClassDir>>> = RwLock::new(BTreeMap::new());
+}
+
+#[derive(Debug)]
+struct ClassDir {
+    inner: SpinLock<InnerClassDir>,
+    locked_kobj_state: LockedKObjectState,
+}
+#[derive(Debug)]
+struct InnerClassDir {
+    name: Option<String>,
+    kobject_common: KObjectCommonData,
+}
+
+impl ClassDir {
+    fn new() -> Arc<Self> {
+        return Arc::new(Self {
+            inner: SpinLock::new(InnerClassDir {
+                name: None,
+                kobject_common: KObjectCommonData::default(),
+            }),
+            locked_kobj_state: LockedKObjectState::default(),
+        });
+    }
+
+    fn inner(&self) -> SpinLockGuard<InnerClassDir> {
+        return self.inner.lock();
+    }
+}
+
+impl KObject for ClassDir {
+    fn as_any_ref(&self) -> &dyn Any {
+        return self;
+    }
+
+    fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
+        self.inner().kobject_common.kern_inode = inode;
+    }
+
+    fn inode(&self) -> Option<Arc<KernFSInode>> {
+        return self.inner().kobject_common.kern_inode.clone();
+    }
+
+    fn parent(&self) -> Option<Weak<dyn KObject>> {
+        return self.inner().kobject_common.parent.clone();
+    }
+
+    fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
+        self.inner().kobject_common.parent = parent;
+    }
+
+    fn kset(&self) -> Option<Arc<KSet>> {
+        return self.inner().kobject_common.kset.clone();
+    }
+
+    fn set_kset(&self, kset: Option<Arc<KSet>>) {
+        self.inner().kobject_common.kset = kset;
+    }
+
+    fn kobj_type(&self) -> Option<&'static dyn KObjType> {
+        return self.inner().kobject_common.kobj_type;
+    }
+
+    fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
+        self.inner().kobject_common.kobj_type = ktype;
+    }
+
+    fn name(&self) -> String {
+        return self.inner().name.clone().unwrap_or_default();
+    }
+
+    fn set_name(&self, name: String) {
+        self.inner().name = Some(name);
+    }
+
+    fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
+        self.locked_kobj_state.read()
+    }
+
+    fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
+        self.locked_kobj_state.write()
+    }
+
+    fn set_kobj_state(&self, state: KObjectState) {
+        *self.locked_kobj_state.write() = state;
+    }
+}

+ 4 - 5
kernel/src/driver/base/kobject.rs

@@ -178,18 +178,17 @@ impl SysFSOps for KObjectSysFSOps {
 pub struct KObjectManager;
 
 impl KObjectManager {
-    #[allow(dead_code)]
     pub fn init_and_add_kobj(
         kobj: Arc<dyn KObject>,
         join_kset: Option<Arc<KSet>>,
+        kobj_type: Option<&'static dyn KObjType>,
     ) -> Result<(), SystemError> {
-        Self::kobj_init(&kobj);
+        Self::kobj_init(&kobj, kobj_type);
         Self::add_kobj(kobj, join_kset)
     }
 
-    #[allow(dead_code)]
-    pub fn kobj_init(kobj: &Arc<dyn KObject>) {
-        kobj.set_kobj_type(Some(&DynamicKObjKType));
+    pub fn kobj_init(kobj: &Arc<dyn KObject>, kobj_type: Option<&'static dyn KObjType>) {
+        kobj.set_kobj_type(kobj_type);
     }
 
     pub fn add_kobj(

+ 53 - 47
kernel/src/driver/base/platform/platform_device.rs

@@ -11,15 +11,15 @@ use crate::{
             bus::{Bus, BusState},
             device_manager,
             driver::Driver,
-            Device, DevicePrivateData, DeviceType, IdTable,
+            Device, DeviceCommonData, DevicePrivateData, DeviceType, IdTable,
         },
-        kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
+        kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
         kset::KSet,
     },
     filesystem::kernfs::KernFSInode,
     libs::{
         rwlock::{RwLockReadGuard, RwLockWriteGuard},
-        spinlock::SpinLock,
+        spinlock::{SpinLock, SpinLockGuard},
     },
 };
 use system_error::SystemError;
@@ -27,7 +27,8 @@ use system_error::SystemError;
 use super::{super::device::DeviceState, platform_bus, platform_bus_device, CompatibleTable};
 
 /// 平台设备id分配器
-static PLATFORM_DEVID_IDA: IdAllocator = IdAllocator::new(0, i32::MAX as usize);
+static PLATFORM_DEVID_IDA: SpinLock<IdAllocator> =
+    SpinLock::new(IdAllocator::new(0, i32::MAX as usize).unwrap());
 
 #[inline(always)]
 pub fn platform_device_manager() -> &'static PlatformDeviceManager {
@@ -79,9 +80,9 @@ pub struct PlatformDeviceManager;
 impl PlatformDeviceManager {
     /// platform_device_add - add a platform device to device hierarchy
     pub fn device_add(&self, pdev: Arc<dyn PlatformDevice>) -> Result<(), SystemError> {
-        if pdev.parent().is_none() {
-            pdev.set_parent(Some(Arc::downgrade(
-                &(platform_bus_device() as Arc<dyn KObject>),
+        if pdev.dev_parent().is_none() {
+            pdev.set_dev_parent(Some(Arc::downgrade(
+                &(platform_bus_device() as Arc<dyn Device>),
             )));
         }
 
@@ -93,7 +94,10 @@ impl PlatformDeviceManager {
                 pdev.set_name(pdev.pdev_name().to_string());
             }
             PLATFORM_DEVID_AUTO => {
-                let id = PLATFORM_DEVID_IDA.alloc().ok_or(SystemError::EOVERFLOW)?;
+                let id = PLATFORM_DEVID_IDA
+                    .lock()
+                    .alloc()
+                    .ok_or(SystemError::EOVERFLOW)?;
                 pdev.set_pdev_id(id as i32);
                 pdev.set_pdev_id_auto(true);
                 pdev.set_name(format!("{}.{}.auto", pdev.pdev_name(), pdev.pdev_id().0));
@@ -112,7 +116,7 @@ impl PlatformDeviceManager {
             // failed
             let pdevid = pdev.pdev_id();
             if pdevid.1 {
-                PLATFORM_DEVID_IDA.free(pdevid.0 as usize);
+                PLATFORM_DEVID_IDA.lock().free(pdevid.0 as usize);
                 pdev.set_pdev_id(PLATFORM_DEVID_AUTO);
             }
 
@@ -136,10 +140,12 @@ impl PlatformBusDevice {
         data: DevicePrivateData,
         parent: Option<Weak<dyn KObject>>,
     ) -> Arc<PlatformBusDevice> {
-        return Arc::new(PlatformBusDevice {
-            inner: SpinLock::new(InnerPlatformBusDevice::new(data, parent)),
+        let platform_bus_device = Self {
+            inner: SpinLock::new(InnerPlatformBusDevice::new(data)),
             kobj_state: LockedKObjectState::new(None),
-        });
+        };
+        platform_bus_device.set_parent(parent);
+        return Arc::new(platform_bus_device);
     }
 
     /// @brief: 获取总线的匹配表
@@ -180,38 +186,30 @@ impl PlatformBusDevice {
         let state = self.inner.lock().state;
         return state;
     }
+
+    fn inner(&self) -> SpinLockGuard<InnerPlatformBusDevice> {
+        self.inner.lock()
+    }
 }
 
 #[allow(dead_code)]
-#[derive(Debug, Clone)]
+#[derive(Debug)]
 pub struct InnerPlatformBusDevice {
     name: String,
     data: DevicePrivateData,
-    state: BusState,                   // 总线状态
-    parent: Option<Weak<dyn KObject>>, // 总线的父对象
-
-    kernfs_inode: Option<Arc<KernFSInode>>,
-    /// 当前设备挂载到的总线
-    bus: Option<Weak<dyn Bus>>,
-    /// 当前设备已经匹配的驱动
-    driver: Option<Weak<dyn Driver>>,
-
-    ktype: Option<&'static dyn KObjType>,
-    kset: Option<Arc<KSet>>,
+    state: BusState, // 总线状态
+    kobject_common: KObjectCommonData,
+    device_common: DeviceCommonData,
 }
 
 impl InnerPlatformBusDevice {
-    pub fn new(data: DevicePrivateData, parent: Option<Weak<dyn KObject>>) -> Self {
+    pub fn new(data: DevicePrivateData) -> Self {
         Self {
             data,
             name: "platform".to_string(),
             state: BusState::NotInitialized,
-            parent,
-            kernfs_inode: None,
-            bus: None,
-            driver: None,
-            ktype: None,
-            kset: None,
+            kobject_common: KObjectCommonData::default(),
+            device_common: DeviceCommonData::default(),
         }
     }
 }
@@ -222,27 +220,27 @@ impl KObject for PlatformBusDevice {
     }
 
     fn parent(&self) -> Option<Weak<dyn KObject>> {
-        self.inner.lock().parent.clone()
+        self.inner().kobject_common.parent.clone()
     }
 
     fn inode(&self) -> Option<Arc<KernFSInode>> {
-        self.inner.lock().kernfs_inode.clone()
+        self.inner().kobject_common.kern_inode.clone()
     }
 
     fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
-        self.inner.lock().kernfs_inode = inode;
+        self.inner().kobject_common.kern_inode = inode;
     }
 
     fn kobj_type(&self) -> Option<&'static dyn KObjType> {
-        self.inner.lock().ktype
+        self.inner().kobject_common.kobj_type
     }
 
     fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
-        self.inner.lock().ktype = ktype;
+        self.inner().kobject_common.kobj_type = ktype;
     }
 
     fn kset(&self) -> Option<Arc<KSet>> {
-        self.inner.lock().kset.clone()
+        self.inner().kobject_common.kset.clone()
     }
 
     fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
@@ -258,19 +256,19 @@ impl KObject for PlatformBusDevice {
     }
 
     fn name(&self) -> String {
-        self.inner.lock().name.clone()
+        self.inner().name.clone()
     }
 
     fn set_name(&self, name: String) {
-        self.inner.lock().name = name;
+        self.inner().name = name;
     }
 
     fn set_kset(&self, kset: Option<Arc<KSet>>) {
-        self.inner.lock().kset = kset;
+        self.inner().kobject_common.kset = kset;
     }
 
     fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
-        self.inner.lock().parent = parent;
+        self.inner().kobject_common.parent = parent;
     }
 }
 
@@ -288,15 +286,15 @@ impl Device for PlatformBusDevice {
     }
 
     fn bus(&self) -> Option<Weak<dyn Bus>> {
-        self.inner.lock().bus.clone()
+        self.inner().device_common.bus.clone()
     }
 
     fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
-        self.inner.lock().bus = bus;
+        self.inner().device_common.bus = bus;
     }
 
     fn driver(&self) -> Option<Arc<dyn Driver>> {
-        self.inner.lock().driver.clone()?.upgrade()
+        self.inner().device_common.driver.clone()?.upgrade()
     }
 
     #[inline]
@@ -305,7 +303,7 @@ impl Device for PlatformBusDevice {
     }
 
     fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
-        self.inner.lock().driver = driver;
+        self.inner().device_common.driver = driver;
     }
 
     fn can_match(&self) -> bool {
@@ -320,7 +318,15 @@ impl Device for PlatformBusDevice {
         todo!()
     }
 
-    fn set_class(&self, _class: Option<Weak<dyn Class>>) {
-        todo!()
+    fn set_class(&self, class: Option<Weak<dyn Class>>) {
+        self.inner().device_common.class = class;
+    }
+
+    fn dev_parent(&self) -> Option<Weak<dyn Device>> {
+        self.inner().device_common.get_parent_weak_or_clear()
+    }
+
+    fn set_dev_parent(&self, dev_parent: Option<Weak<dyn Device>>) {
+        self.inner().device_common.parent = dev_parent;
     }
 }

+ 8 - 1
kernel/src/driver/base/platform/subsys.rs

@@ -5,7 +5,9 @@ use alloc::{
 use intertrait::cast::CastArc;
 use log::error;
 
-use super::{platform_device::PlatformDevice, platform_driver::PlatformDriver};
+use super::{
+    platform_bus_device, platform_device::PlatformDevice, platform_driver::PlatformDriver,
+};
 use crate::{
     driver::{
         acpi::acpi_manager,
@@ -141,6 +143,11 @@ impl Bus for PlatformBus {
         // 尝试根据设备名称匹配
         return Ok(device.name().eq(&driver.name()));
     }
+
+    fn root_device(&self) -> Option<Weak<dyn Device>> {
+        let root_device = platform_bus_device() as Arc<dyn Device>;
+        return Some(Arc::downgrade(&root_device));
+    }
 }
 
 #[derive(Debug)]

+ 134 - 13
kernel/src/driver/block/virtio_blk.rs

@@ -1,21 +1,24 @@
 use core::{any::Any, fmt::Debug};
 
 use alloc::{
+    collections::LinkedList,
     string::{String, ToString},
     sync::{Arc, Weak},
     vec::Vec,
 };
-use log::{debug, error};
+use bitmap::traits::BitMapOps;
+use log::error;
 use system_error::SystemError;
 use unified_init::macros::unified_init;
-use virtio_drivers::device::blk::VirtIOBlk;
+use virtio_drivers::device::blk::{VirtIOBlk, SECTOR_SIZE};
 
 use crate::{
     driver::{
         base::{
             block::{
-                block_device::{BlockDevice, BlockId, LBA_SIZE},
+                block_device::{BlockDevName, BlockDevice, BlockId, GeneralBlockRange, LBA_SIZE},
                 disk_info::Partition,
+                manager::{block_dev_manager, BlockDevMeta},
             },
             class::Class,
             device::{
@@ -30,7 +33,8 @@ use crate::{
             sysfs::{virtio_bus, virtio_device_manager, virtio_driver_manager},
             transport::VirtIOTransport,
             virtio_impl::HalImpl,
-            VirtIODevice, VirtIODeviceIndex, VirtIODriver, VIRTIO_VENDOR_ID,
+            VirtIODevice, VirtIODeviceIndex, VirtIODriver, VirtIODriverCommonData, VirtioDeviceId,
+            VIRTIO_VENDOR_ID,
         },
     },
     exception::{irqdesc::IrqReturn, IrqNumber},
@@ -47,6 +51,7 @@ const VIRTIO_BLK_BASENAME: &str = "virtio_blk";
 static mut VIRTIO_BLK_DRIVER: Option<Arc<VirtIOBlkDriver>> = None;
 
 #[inline(always)]
+#[allow(dead_code)]
 fn virtio_blk_driver() -> Arc<VirtIOBlkDriver> {
     unsafe { VIRTIO_BLK_DRIVER.as_ref().unwrap().clone() }
 }
@@ -61,21 +66,92 @@ pub fn virtio_blk_0() -> Option<Arc<VirtIOBlkDevice>> {
         .map(|dev| dev.arc_any().downcast().unwrap())
 }
 
-pub fn virtio_blk(transport: VirtIOTransport, dev_id: Arc<DeviceId>) {
+pub fn virtio_blk(
+    transport: VirtIOTransport,
+    dev_id: Arc<DeviceId>,
+    dev_parent: Option<Arc<dyn Device>>,
+) {
     let device = VirtIOBlkDevice::new(transport, dev_id);
     if let Some(device) = device {
-        debug!("VirtIOBlkDevice '{:?}' created", device.dev_id);
+        if let Some(dev_parent) = dev_parent {
+            device.set_dev_parent(Some(Arc::downgrade(&dev_parent)));
+        }
         virtio_device_manager()
             .device_add(device.clone() as Arc<dyn VirtIODevice>)
             .expect("Add virtio blk failed");
     }
 }
 
+static mut VIRTIOBLK_MANAGER: Option<VirtIOBlkManager> = None;
+
+#[inline]
+fn virtioblk_manager() -> &'static VirtIOBlkManager {
+    unsafe { VIRTIOBLK_MANAGER.as_ref().unwrap() }
+}
+
+#[unified_init(INITCALL_POSTCORE)]
+fn virtioblk_manager_init() -> Result<(), SystemError> {
+    unsafe {
+        VIRTIOBLK_MANAGER = Some(VirtIOBlkManager::new());
+    }
+    Ok(())
+}
+
+pub struct VirtIOBlkManager {
+    inner: SpinLock<InnerVirtIOBlkManager>,
+}
+
+struct InnerVirtIOBlkManager {
+    id_bmp: bitmap::StaticBitmap<{ VirtIOBlkManager::MAX_DEVICES }>,
+    devname: [Option<BlockDevName>; VirtIOBlkManager::MAX_DEVICES],
+}
+
+impl VirtIOBlkManager {
+    pub const MAX_DEVICES: usize = 25;
+
+    pub fn new() -> Self {
+        Self {
+            inner: SpinLock::new(InnerVirtIOBlkManager {
+                id_bmp: bitmap::StaticBitmap::new(),
+                devname: [const { None }; Self::MAX_DEVICES],
+            }),
+        }
+    }
+
+    fn inner(&self) -> SpinLockGuard<InnerVirtIOBlkManager> {
+        self.inner.lock()
+    }
+
+    pub fn alloc_id(&self) -> Option<BlockDevName> {
+        let mut inner = self.inner();
+        let idx = inner.id_bmp.first_false_index()?;
+        inner.id_bmp.set(idx, true);
+        let name = Self::format_name(idx);
+        inner.devname[idx] = Some(name.clone());
+        Some(name)
+    }
+
+    /// Generate a new block device name like 'vda', 'vdb', etc.
+    fn format_name(id: usize) -> BlockDevName {
+        let x = (b'a' + id as u8) as char;
+        BlockDevName::new(format!("vd{}", x), id)
+    }
+
+    pub fn free_id(&self, id: usize) {
+        if id >= Self::MAX_DEVICES {
+            return;
+        }
+        self.inner().id_bmp.set(id, false);
+        self.inner().devname[id] = None;
+    }
+}
+
 /// virtio block device
 #[derive(Debug)]
 #[cast_to([sync] VirtIODevice)]
 #[cast_to([sync] Device)]
 pub struct VirtIOBlkDevice {
+    blkdev_meta: BlockDevMeta,
     dev_id: Arc<DeviceId>,
     inner: SpinLock<InnerVirtIOBlkDevice>,
     locked_kobj_state: LockedKObjectState,
@@ -87,6 +163,7 @@ unsafe impl Sync for VirtIOBlkDevice {}
 
 impl VirtIOBlkDevice {
     pub fn new(transport: VirtIOTransport, dev_id: Arc<DeviceId>) -> Option<Arc<Self>> {
+        let devname = virtioblk_manager().alloc_id()?;
         let irq = transport.irq().map(|irq| IrqNumber::new(irq.data()));
         let device_inner = VirtIOBlk::<HalImpl, VirtIOTransport>::new(transport);
         if let Err(e) = device_inner {
@@ -97,6 +174,7 @@ impl VirtIOBlkDevice {
         let mut device_inner: VirtIOBlk<HalImpl, VirtIOTransport> = device_inner.unwrap();
         device_inner.enable_interrupts();
         let dev = Arc::new_cyclic(|self_ref| Self {
+            blkdev_meta: BlockDevMeta::new(devname),
             self_ref: self_ref.clone(),
             dev_id,
             locked_kobj_state: LockedKObjectState::default(),
@@ -110,10 +188,6 @@ impl VirtIOBlkDevice {
             }),
         });
 
-        dev.set_driver(Some(Arc::downgrade(
-            &(virtio_blk_driver() as Arc<dyn Driver>),
-        )));
-
         Some(dev)
     }
 
@@ -123,6 +197,26 @@ impl VirtIOBlkDevice {
 }
 
 impl BlockDevice for VirtIOBlkDevice {
+    fn dev_name(&self) -> &BlockDevName {
+        &self.blkdev_meta.devname
+    }
+
+    fn blkdev_meta(&self) -> &BlockDevMeta {
+        &self.blkdev_meta
+    }
+
+    fn disk_range(&self) -> GeneralBlockRange {
+        let inner = self.inner();
+        let blocks = inner.device_inner.capacity() as usize * SECTOR_SIZE / LBA_SIZE;
+        drop(inner);
+        log::debug!(
+            "VirtIOBlkDevice '{:?}' disk_range: 0..{}",
+            self.dev_name(),
+            blocks
+        );
+        GeneralBlockRange::new(0, blocks).unwrap()
+    }
+
     fn read_at_sync(
         &self,
         lba_id_start: BlockId,
@@ -305,6 +399,14 @@ impl Device for VirtIOBlkDevice {
     fn state_synced(&self) -> bool {
         true
     }
+
+    fn dev_parent(&self) -> Option<Weak<dyn Device>> {
+        self.inner().device_common.get_parent_weak_or_clear()
+    }
+
+    fn set_dev_parent(&self, parent: Option<Weak<dyn Device>>) {
+        self.inner().device_common.parent = parent;
+    }
 }
 
 impl KObject for VirtIOBlkDevice {
@@ -389,13 +491,22 @@ struct VirtIOBlkDriver {
 impl VirtIOBlkDriver {
     pub fn new() -> Arc<Self> {
         let inner = InnerVirtIOBlkDriver {
+            virtio_driver_common: VirtIODriverCommonData::default(),
             driver_common: DriverCommonData::default(),
             kobj_common: KObjectCommonData::default(),
         };
-        Arc::new(VirtIOBlkDriver {
+
+        let id_table = VirtioDeviceId::new(
+            virtio_drivers::transport::DeviceType::Block as u32,
+            VIRTIO_VENDOR_ID.into(),
+        );
+        let result = VirtIOBlkDriver {
             inner: SpinLock::new(inner),
             kobj_state: LockedKObjectState::default(),
-        })
+        };
+        result.add_virtio_id(id_table);
+
+        return Arc::new(result);
     }
 
     fn inner(&self) -> SpinLockGuard<InnerVirtIOBlkDriver> {
@@ -405,13 +516,14 @@ impl VirtIOBlkDriver {
 
 #[derive(Debug)]
 struct InnerVirtIOBlkDriver {
+    virtio_driver_common: VirtIODriverCommonData,
     driver_common: DriverCommonData,
     kobj_common: KObjectCommonData,
 }
 
 impl VirtIODriver for VirtIOBlkDriver {
     fn probe(&self, device: &Arc<dyn VirtIODevice>) -> Result<(), SystemError> {
-        let _dev = device
+        let dev = device
             .clone()
             .arc_any()
             .downcast::<VirtIOBlkDevice>()
@@ -423,8 +535,17 @@ impl VirtIODriver for VirtIOBlkDriver {
                 SystemError::EINVAL
             })?;
 
+        block_dev_manager().register(dev as Arc<dyn BlockDevice>)?;
         return Ok(());
     }
+
+    fn virtio_id_table(&self) -> LinkedList<crate::driver::virtio::VirtioDeviceId> {
+        self.inner().virtio_driver_common.id_table.clone()
+    }
+
+    fn add_virtio_id(&self, id: VirtioDeviceId) {
+        self.inner().virtio_driver_common.id_table.push_back(id);
+    }
 }
 
 impl Driver for VirtIOBlkDriver {

+ 54 - 31
kernel/src/driver/disk/ahci/ahcidisk.rs

@@ -1,7 +1,10 @@
 use super::{_port, hba::HbaCmdTable};
 use crate::arch::MMArch;
-use crate::driver::base::block::block_device::{BlockDevice, BlockId};
+use crate::driver::base::block::block_device::{
+    BlockDevName, BlockDevice, BlockId, GeneralBlockRange,
+};
 use crate::driver::base::block::disk_info::Partition;
+use crate::driver::base::block::manager::BlockDevMeta;
 use crate::driver::base::class::Class;
 use crate::driver::base::device::bus::Bus;
 
@@ -11,6 +14,7 @@ use crate::driver::base::kobject::{KObjType, KObject, KObjectState};
 use crate::driver::base::kset::KSet;
 use crate::driver::disk::ahci::HBA_PxIS_TFES;
 
+use crate::driver::scsi::scsi_manager;
 use crate::filesystem::kernfs::KernFSInode;
 use crate::filesystem::mbr::MbrDiskPartionTable;
 
@@ -19,13 +23,13 @@ use crate::driver::disk::ahci::hba::{
     ATA_DEV_DRQ,
 };
 use crate::libs::rwlock::{RwLockReadGuard, RwLockWriteGuard};
-use crate::libs::spinlock::SpinLock;
+use crate::libs::spinlock::{SpinLock, SpinLockGuard};
 use crate::mm::{verify_area, MemoryManagementArch, PhysAddr, VirtAddr};
 use log::error;
 use system_error::SystemError;
 
 use alloc::sync::Weak;
-use alloc::{string::String, sync::Arc, vec::Vec};
+use alloc::{sync::Arc, vec::Vec};
 
 use core::fmt::Debug;
 use core::sync::atomic::{compiler_fence, Ordering};
@@ -33,8 +37,7 @@ use core::{mem::size_of, ptr::write_bytes};
 
 /// @brief: 只支持MBR分区格式的磁盘结构体
 pub struct AhciDisk {
-    pub name: String,
-    pub flags: u16,                      // 磁盘的状态flags
+    // 磁盘的状态flags
     pub partitions: Vec<Arc<Partition>>, // 磁盘分区数组
     // port: &'static mut HbaPort,      // 控制硬盘的端口
     pub ctrl_num: u8,
@@ -45,16 +48,21 @@ pub struct AhciDisk {
 
 /// @brief: 带锁的AhciDisk
 #[derive(Debug)]
-pub struct LockedAhciDisk(pub SpinLock<AhciDisk>);
+pub struct LockedAhciDisk {
+    blkdev_meta: BlockDevMeta,
+    inner: SpinLock<AhciDisk>,
+}
+
+impl LockedAhciDisk {
+    pub fn inner(&self) -> SpinLockGuard<AhciDisk> {
+        self.inner.lock()
+    }
+}
+
 /// 函数实现
 impl Debug for AhciDisk {
     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
-        write!(
-            f,
-            "{{ name: {}, flags: {}, part_s: {:?} }}",
-            self.name, self.flags, self.partitions
-        )?;
-        return Ok(());
+        write!(f, "AhciDisk")
     }
 }
 
@@ -371,35 +379,30 @@ impl AhciDisk {
 }
 
 impl LockedAhciDisk {
-    pub fn new(
-        name: String,
-        flags: u16,
-        ctrl_num: u8,
-        port_num: u8,
-    ) -> Result<Arc<LockedAhciDisk>, SystemError> {
+    pub fn new(ctrl_num: u8, port_num: u8) -> Result<Arc<LockedAhciDisk>, SystemError> {
+        let devname = scsi_manager().alloc_id().ok_or(SystemError::EBUSY)?;
         // 构建磁盘结构体
-        let result: Arc<LockedAhciDisk> = Arc::new_cyclic(|self_ref| {
-            LockedAhciDisk(SpinLock::new(AhciDisk {
-                name,
-                flags,
-                partitions: Default::default(),
+        let result: Arc<LockedAhciDisk> = Arc::new_cyclic(|self_ref| LockedAhciDisk {
+            blkdev_meta: BlockDevMeta::new(devname),
+            inner: SpinLock::new(AhciDisk {
+                partitions: Vec::new(),
                 ctrl_num,
                 port_num,
                 self_ref: self_ref.clone(),
-            }))
+            }),
         });
         let table: MbrDiskPartionTable = result.read_mbr_table()?;
 
         // 求出有多少可用分区
         let partitions = table.partitions(Arc::downgrade(&result) as Weak<dyn BlockDevice>);
-        result.0.lock().partitions = partitions;
+        result.inner().partitions = partitions;
 
         return Ok(result);
     }
 
     /// @brief: 从磁盘中读取 MBR 分区表结构体
     pub fn read_mbr_table(&self) -> Result<MbrDiskPartionTable, SystemError> {
-        let disk = self.0.lock().self_ref.upgrade().unwrap() as Arc<dyn BlockDevice>;
+        let disk = self.inner().self_ref.upgrade().unwrap() as Arc<dyn BlockDevice>;
         MbrDiskPartionTable::from_disk(disk)
     }
 }
@@ -506,9 +509,29 @@ impl Device for LockedAhciDisk {
     fn set_class(&self, _class: Option<Weak<dyn Class>>) {
         todo!()
     }
+
+    fn dev_parent(&self) -> Option<Weak<dyn Device>> {
+        None
+    }
+
+    fn set_dev_parent(&self, _dev_parent: Option<Weak<dyn Device>>) {
+        todo!()
+    }
 }
 
 impl BlockDevice for LockedAhciDisk {
+    fn dev_name(&self) -> &BlockDevName {
+        &self.blkdev_meta.devname
+    }
+
+    fn blkdev_meta(&self) -> &BlockDevMeta {
+        &self.blkdev_meta
+    }
+
+    fn disk_range(&self) -> GeneralBlockRange {
+        todo!("Get ahci blk disk range")
+    }
+
     #[inline]
     fn as_any_ref(&self) -> &dyn core::any::Any {
         self
@@ -520,12 +543,12 @@ impl BlockDevice for LockedAhciDisk {
     }
 
     fn sync(&self) -> Result<(), SystemError> {
-        return self.0.lock().sync();
+        return self.inner().sync();
     }
 
     #[inline]
     fn device(&self) -> Arc<dyn Device> {
-        return self.0.lock().self_ref.upgrade().unwrap();
+        return self.inner().self_ref.upgrade().unwrap();
     }
 
     fn block_size(&self) -> usize {
@@ -533,7 +556,7 @@ impl BlockDevice for LockedAhciDisk {
     }
 
     fn partitions(&self) -> Vec<Arc<Partition>> {
-        return self.0.lock().partitions.clone();
+        return self.inner().partitions.clone();
     }
 
     #[inline]
@@ -543,7 +566,7 @@ impl BlockDevice for LockedAhciDisk {
         count: usize,          // 读取lba的数量
         buf: &mut [u8],
     ) -> Result<usize, SystemError> {
-        self.0.lock().read_at(lba_id_start, count, buf)
+        self.inner().read_at(lba_id_start, count, buf)
     }
 
     #[inline]
@@ -553,6 +576,6 @@ impl BlockDevice for LockedAhciDisk {
         count: usize,
         buf: &[u8],
     ) -> Result<usize, SystemError> {
-        self.0.lock().write_at(lba_id_start, count, buf)
+        self.inner().write_at(lba_id_start, count, buf)
     }
 }

+ 8 - 52
kernel/src/driver/disk/ahci/mod.rs

@@ -4,31 +4,27 @@ pub mod ahcidisk;
 pub mod hba;
 
 use crate::arch::MMArch;
-use crate::driver::base::block::disk_info::BLK_GF_AHCI;
+use crate::driver::base::block::manager::block_dev_manager;
 use crate::driver::block::cache::cached_block_device::BlockCache;
-// 依赖的rust工具包
+use crate::driver::disk::ahci::ahcidisk::LockedAhciDisk;
 use crate::driver::pci::pci::{
     get_pci_device_structure_mut, PciDeviceStructure, PCI_DEVICE_LINKEDLIST,
 };
-use crate::filesystem::devfs::devfs_register;
 
 use crate::driver::disk::ahci::{
-    ahcidisk::LockedAhciDisk,
     hba::HbaMem,
     hba::{HbaPort, HbaPortType},
 };
 use crate::libs::rwlock::RwLockWriteGuard;
 use crate::libs::spinlock::{SpinLock, SpinLockGuard};
 use crate::mm::{MemoryManagementArch, VirtAddr};
-use ahci_inode::LockedAhciInode;
-use alloc::{boxed::Box, collections::LinkedList, format, string::String, sync::Arc, vec::Vec};
+use alloc::{boxed::Box, collections::LinkedList, vec::Vec};
 use core::sync::atomic::compiler_fence;
-use log::{debug, error};
+use log::debug;
 use system_error::SystemError;
 
 // 仅module内可见 全局数据区  hbr_port, disks
 static LOCKED_HBA_MEM_LIST: SpinLock<Vec<&mut HbaMem>> = SpinLock::new(Vec::new());
-static LOCKED_DISKS_LIST: SpinLock<Vec<Arc<LockedAhciDisk>>> = SpinLock::new(Vec::new());
 
 const AHCI_CLASS: u8 = 0x1;
 const AHCI_SUBCLASS: u8 = 0x6;
@@ -56,8 +52,6 @@ fn ahci_device_search<'a>(
 pub fn ahci_init() -> Result<(), SystemError> {
     let mut list = PCI_DEVICE_LINKEDLIST.write();
     let ahci_device = ahci_device_search(&mut list)?;
-    // 全局数据 - 列表
-    let mut disks_list = LOCKED_DISKS_LIST.lock();
 
     for device in ahci_device {
         let standard_device = device.as_standard_device_mut().unwrap();
@@ -81,7 +75,6 @@ pub fn ahci_init() -> Result<(), SystemError> {
         let hba_mem_index = hba_mem_list.len() - 1;
         drop(hba_mem_list);
         // 初始化所有的port
-        let mut id = 0;
         for j in 0..32 {
             if (pi >> j) & 1 > 0 {
                 let hba_mem_list = LOCKED_HBA_MEM_LIST.lock();
@@ -124,31 +117,12 @@ pub fn ahci_init() -> Result<(), SystemError> {
                         hba_mem_port.init(clb as u64, fb as u64, &ctbas);
                         drop(hba_mem_list);
                         compiler_fence(core::sync::atomic::Ordering::SeqCst);
-                        // 创建 disk
-                        disks_list.push(LockedAhciDisk::new(
-                            format!("ahci_disk_{}", id),
-                            BLK_GF_AHCI,
-                            hba_mem_index as u8,
-                            j as u8,
-                        )?);
-                        id += 1; // ID 从0开始
+                        let ahci_disk = LockedAhciDisk::new(hba_mem_index as u8, j as u8)?;
+                        block_dev_manager()
+                            .register(ahci_disk)
+                            .expect("register ahci disk failed");
 
                         debug!("start register ahci device");
-
-                        // 挂载到devfs上面去
-                        let ret = devfs_register(
-                            format!("ahci_{}", id).as_str(),
-                            LockedAhciInode::new(disks_list.last().unwrap().clone()),
-                        );
-                        if let Err(err) = ret {
-                            error!(
-                                "Ahci_{} ctrl = {}, port = {} failed to register, error code = {:?}",
-                                id,
-                                hba_mem_index as u8,
-                                j,
-                                err
-                            );
-                        }
                     }
                 }
             }
@@ -160,24 +134,6 @@ pub fn ahci_init() -> Result<(), SystemError> {
     return Ok(());
 }
 
-/// @brief: 获取所有的 disk
-#[allow(dead_code)]
-pub fn disks() -> Vec<Arc<LockedAhciDisk>> {
-    let disks_list = LOCKED_DISKS_LIST.lock();
-    return disks_list.clone();
-}
-
-/// @brief: 通过 name 获取 disk
-pub fn get_disks_by_name(name: String) -> Result<Arc<LockedAhciDisk>, SystemError> {
-    let disks_list: SpinLockGuard<Vec<Arc<LockedAhciDisk>>> = LOCKED_DISKS_LIST.lock();
-    let result = disks_list
-        .iter()
-        .find(|x| x.0.lock().name == name)
-        .ok_or(SystemError::ENXIO)?
-        .clone();
-    return Ok(result);
-}
-
 /// @brief: 通过 ctrl_num 和 port_num 获取 port
 fn _port(ctrl_num: u8, port_num: u8) -> &'static mut HbaPort {
     let list: SpinLockGuard<Vec<&mut HbaMem>> = LOCKED_HBA_MEM_LIST.lock();

+ 36 - 34
kernel/src/driver/input/ps2_mouse/ps_mouse_device.rs

@@ -16,9 +16,9 @@ use crate::{
             class::Class,
             device::{
                 bus::Bus, device_manager, device_number::DeviceNumber, driver::Driver, Device,
-                DeviceType, IdTable,
+                DeviceCommonData, DeviceType, IdTable,
             },
-            kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
+            kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
             kset::KSet,
         },
         input::{
@@ -184,13 +184,8 @@ impl Ps2MouseDevice {
     pub fn new() -> Self {
         let r = Self {
             inner: SpinLock::new(InnerPs2MouseDevice {
-                bus: None,
-                class: None,
-                driver: None,
-                kern_inode: None,
-                parent: None,
-                kset: None,
-                kobj_type: None,
+                device_common: DeviceCommonData::default(),
+                kobject_common: KObjectCommonData::default(),
                 current_packet: 0,
                 current_state: MouseState::new(),
                 buf: AllocRingBuffer::new(MOUSE_BUFFER_CAPACITY),
@@ -409,17 +404,16 @@ impl Ps2MouseDevice {
         }
         Err(SystemError::ETIMEDOUT)
     }
+
+    fn inner(&self) -> SpinLockGuard<InnerPs2MouseDevice> {
+        self.inner.lock_irqsave()
+    }
 }
 
 #[derive(Debug)]
 struct InnerPs2MouseDevice {
-    bus: Option<Weak<dyn Bus>>,
-    class: Option<Weak<dyn Class>>,
-    driver: Option<Weak<dyn Driver>>,
-    kern_inode: Option<Arc<KernFSInode>>,
-    parent: Option<Weak<dyn KObject>>,
-    kset: Option<Arc<KSet>>,
-    kobj_type: Option<&'static dyn KObjType>,
+    device_common: DeviceCommonData,
+    kobject_common: KObjectCommonData,
 
     /// 鼠标数据
     current_state: MouseState,
@@ -446,19 +440,19 @@ impl Device for Ps2MouseDevice {
     }
 
     fn set_bus(&self, bus: Option<alloc::sync::Weak<dyn Bus>>) {
-        self.inner.lock_irqsave().bus = bus;
+        self.inner().device_common.bus = bus;
     }
 
     fn set_class(&self, class: Option<alloc::sync::Weak<dyn Class>>) {
-        self.inner.lock_irqsave().class = class;
+        self.inner().device_common.class = class;
     }
 
     fn driver(&self) -> Option<alloc::sync::Arc<dyn Driver>> {
-        self.inner.lock_irqsave().driver.clone()?.upgrade()
+        self.inner().device_common.driver.clone()?.upgrade()
     }
 
     fn set_driver(&self, driver: Option<alloc::sync::Weak<dyn Driver>>) {
-        self.inner.lock_irqsave().driver = driver;
+        self.inner().device_common.driver = driver;
     }
 
     fn can_match(&self) -> bool {
@@ -472,18 +466,26 @@ impl Device for Ps2MouseDevice {
     }
 
     fn bus(&self) -> Option<alloc::sync::Weak<dyn Bus>> {
-        self.inner.lock_irqsave().bus.clone()
+        self.inner().device_common.bus.clone()
     }
 
     fn class(&self) -> Option<Arc<dyn Class>> {
-        let mut guard = self.inner.lock_irqsave();
-        let r = guard.class.clone()?.upgrade();
+        let mut guard = self.inner();
+        let r = guard.device_common.class.clone()?.upgrade();
         if r.is_none() {
-            guard.class = None;
+            guard.device_common.class = None;
         }
 
         return r;
     }
+
+    fn dev_parent(&self) -> Option<alloc::sync::Weak<dyn Device>> {
+        self.inner().device_common.get_parent_weak_or_clear()
+    }
+
+    fn set_dev_parent(&self, dev_parent: Option<alloc::sync::Weak<dyn Device>>) {
+        self.inner().device_common.parent = dev_parent;
+    }
 }
 
 impl SerioDevice for Ps2MouseDevice {
@@ -530,35 +532,35 @@ impl KObject for Ps2MouseDevice {
     }
 
     fn set_inode(&self, inode: Option<alloc::sync::Arc<KernFSInode>>) {
-        self.inner.lock_irqsave().kern_inode = inode;
+        self.inner().kobject_common.kern_inode = inode;
     }
 
     fn inode(&self) -> Option<alloc::sync::Arc<KernFSInode>> {
-        self.inner.lock_irqsave().kern_inode.clone()
+        self.inner().kobject_common.kern_inode.clone()
     }
 
     fn parent(&self) -> Option<alloc::sync::Weak<dyn KObject>> {
-        self.inner.lock_irqsave().parent.clone()
+        self.inner().kobject_common.parent.clone()
     }
 
     fn set_parent(&self, parent: Option<alloc::sync::Weak<dyn KObject>>) {
-        self.inner.lock_irqsave().parent = parent
+        self.inner().kobject_common.parent = parent
     }
 
     fn kset(&self) -> Option<alloc::sync::Arc<KSet>> {
-        self.inner.lock_irqsave().kset.clone()
+        self.inner().kobject_common.kset.clone()
     }
 
     fn set_kset(&self, kset: Option<alloc::sync::Arc<KSet>>) {
-        self.inner.lock_irqsave().kset = kset;
+        self.inner().kobject_common.kset = kset;
     }
 
     fn kobj_type(&self) -> Option<&'static dyn KObjType> {
-        self.inner.lock_irqsave().kobj_type
+        self.inner().kobject_common.kobj_type
     }
 
     fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
-        self.inner.lock_irqsave().kobj_type = ktype;
+        self.inner().kobject_common.kobj_type = ktype;
     }
 
     fn name(&self) -> alloc::string::String {
@@ -665,12 +667,12 @@ impl IndexNode for Ps2MouseDevice {
 
 impl Ps2Device for Ps2MouseDevice {}
 
-pub fn rs_ps2_mouse_device_init(parent: Arc<dyn KObject>) -> Result<(), SystemError> {
+pub fn rs_ps2_mouse_device_init(dev_parent: Arc<dyn Device>) -> Result<(), SystemError> {
     debug!("ps2_mouse_device initializing...");
     let psmouse = Arc::new(Ps2MouseDevice::new());
 
     device_manager().device_default_initialize(&(psmouse.clone() as Arc<dyn Device>));
-    psmouse.set_parent(Some(Arc::downgrade(&parent)));
+    psmouse.set_dev_parent(Some(Arc::downgrade(&dev_parent)));
     serio_device_manager().register_port(psmouse.clone() as Arc<dyn SerioDevice>)?;
 
     devfs_register(&psmouse.name(), psmouse.clone()).map_err(|e| {

+ 37 - 33
kernel/src/driver/input/serio/i8042/i8042_device.rs

@@ -6,15 +6,17 @@ use alloc::{
 use crate::{
     driver::base::{
         class::Class,
-        device::{bus::Bus, driver::Driver, Device, DeviceState, DeviceType, IdTable},
-        kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
+        device::{
+            bus::Bus, driver::Driver, Device, DeviceCommonData, DeviceState, DeviceType, IdTable,
+        },
+        kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
         kset::KSet,
         platform::platform_device::PlatformDevice,
     },
     filesystem::kernfs::KernFSInode,
     libs::{
         rwlock::{RwLockReadGuard, RwLockWriteGuard},
-        spinlock::SpinLock,
+        spinlock::{SpinLock, SpinLockGuard},
     },
 };
 
@@ -31,13 +33,8 @@ impl I8042PlatformDevice {
     pub fn new() -> Self {
         return Self {
             inner: SpinLock::new(InnerI8042PlatformDevice {
-                bus: None,
-                class: None,
-                driver: None,
-                kern_inode: None,
-                parent: None,
-                kset: None,
-                kobj_type: None,
+                kobject_common: KObjectCommonData::default(),
+                device_common: DeviceCommonData::default(),
                 device_state: DeviceState::NotInitialized,
                 pdev_id: 0,
                 pdev_id_auto: false,
@@ -45,17 +42,16 @@ impl I8042PlatformDevice {
             kobj_state: LockedKObjectState::new(None),
         };
     }
+
+    fn inner(&self) -> SpinLockGuard<InnerI8042PlatformDevice> {
+        self.inner.lock()
+    }
 }
 
 #[derive(Debug)]
 pub struct InnerI8042PlatformDevice {
-    bus: Option<Weak<dyn Bus>>,
-    class: Option<Weak<dyn Class>>,
-    driver: Option<Weak<dyn Driver>>,
-    kern_inode: Option<Arc<KernFSInode>>,
-    parent: Option<Weak<dyn KObject>>,
-    kset: Option<Arc<KSet>>,
-    kobj_type: Option<&'static dyn KObjType>,
+    kobject_common: KObjectCommonData,
+    device_common: DeviceCommonData,
     device_state: DeviceState,
     pdev_id: i32,
     pdev_id_auto: bool,
@@ -71,31 +67,31 @@ impl Device for I8042PlatformDevice {
     }
 
     fn bus(&self) -> Option<Weak<dyn Bus>> {
-        self.inner.lock().bus.clone()
+        self.inner().device_common.bus.clone()
     }
 
     fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
-        self.inner.lock().bus = bus;
+        self.inner().device_common.bus = bus;
     }
     fn class(&self) -> Option<Arc<dyn Class>> {
-        let mut guard = self.inner.lock();
-        let r = guard.class.clone()?.upgrade();
+        let mut guard = self.inner();
+        let r = guard.device_common.class.clone()?.upgrade();
         if r.is_none() {
-            guard.class = None;
+            guard.device_common.class = None;
         }
 
         return r;
     }
     fn set_class(&self, class: Option<Weak<dyn Class>>) {
-        self.inner.lock().class = class;
+        self.inner().device_common.class = class;
     }
 
     fn driver(&self) -> Option<Arc<dyn Driver>> {
-        self.inner.lock().driver.clone()?.upgrade()
+        self.inner().device_common.driver.clone()?.upgrade()
     }
 
     fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
-        self.inner.lock().driver = driver;
+        self.inner().device_common.driver = driver;
     }
 
     fn is_dead(&self) -> bool {
@@ -111,6 +107,14 @@ impl Device for I8042PlatformDevice {
     fn state_synced(&self) -> bool {
         true
     }
+
+    fn dev_parent(&self) -> Option<Weak<dyn Device>> {
+        self.inner().device_common.get_parent_weak_or_clear()
+    }
+
+    fn set_dev_parent(&self, dev_parent: Option<Weak<dyn Device>>) {
+        self.inner().device_common.parent = dev_parent;
+    }
 }
 
 impl KObject for I8042PlatformDevice {
@@ -119,35 +123,35 @@ impl KObject for I8042PlatformDevice {
     }
 
     fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
-        self.inner.lock().kern_inode = inode;
+        self.inner().kobject_common.kern_inode = inode;
     }
 
     fn inode(&self) -> Option<Arc<KernFSInode>> {
-        self.inner.lock().kern_inode.clone()
+        self.inner().kobject_common.kern_inode.clone()
     }
 
     fn parent(&self) -> Option<Weak<dyn KObject>> {
-        self.inner.lock().parent.clone()
+        self.inner().kobject_common.parent.clone()
     }
 
     fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
-        self.inner.lock().parent = parent;
+        self.inner().kobject_common.parent = parent;
     }
 
     fn kset(&self) -> Option<Arc<KSet>> {
-        self.inner.lock().kset.clone()
+        self.inner().kobject_common.kset.clone()
     }
 
     fn set_kset(&self, kset: Option<Arc<KSet>>) {
-        self.inner.lock().kset = kset;
+        self.inner().kobject_common.kset = kset;
     }
 
     fn kobj_type(&self) -> Option<&'static dyn KObjType> {
-        self.inner.lock().kobj_type
+        self.inner().kobject_common.kobj_type
     }
 
     fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
-        self.inner.lock().kobj_type = ktype;
+        self.inner().kobject_common.kobj_type = ktype;
     }
 
     fn name(&self) -> String {

+ 35 - 33
kernel/src/driver/input/serio/i8042/i8042_ports.rs

@@ -8,8 +8,8 @@ use crate::{
     driver::{
         base::{
             class::Class,
-            device::{bus::Bus, driver::Driver, Device, DeviceType, IdTable},
-            kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
+            device::{bus::Bus, driver::Driver, Device, DeviceCommonData, DeviceType, IdTable},
+            kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
             kset::KSet,
         },
         input::serio::serio_device::SerioDevice,
@@ -17,7 +17,7 @@ use crate::{
     filesystem::kernfs::KernFSInode,
     libs::{
         rwlock::{RwLockReadGuard, RwLockWriteGuard},
-        spinlock::SpinLock,
+        spinlock::{SpinLock, SpinLockGuard},
     },
 };
 
@@ -32,13 +32,8 @@ pub struct I8042AuxPort {
 
 #[derive(Debug)]
 pub struct InnerI8042AuxPort {
-    bus: Option<Weak<dyn Bus>>,
-    class: Option<Weak<dyn Class>>,
-    driver: Option<Weak<dyn Driver>>,
-    kern_inode: Option<Arc<KernFSInode>>,
-    parent: Option<Weak<dyn KObject>>,
-    kset: Option<Arc<KSet>>,
-    kobj_type: Option<&'static dyn KObjType>,
+    device_common: DeviceCommonData,
+    kobject_common: KObjectCommonData,
 }
 
 impl I8042AuxPort {
@@ -46,17 +41,16 @@ impl I8042AuxPort {
     pub fn new() -> Self {
         return Self {
             inner: SpinLock::new(InnerI8042AuxPort {
-                bus: None,
-                class: None,
-                driver: None,
-                kern_inode: None,
-                parent: None,
-                kset: None,
-                kobj_type: None,
+                device_common: DeviceCommonData::default(),
+                kobject_common: KObjectCommonData::default(),
             }),
             kobj_state: LockedKObjectState::new(None),
         };
     }
+
+    fn inner(&self) -> SpinLockGuard<InnerI8042AuxPort> {
+        self.inner.lock()
+    }
 }
 
 impl Device for I8042AuxPort {
@@ -69,32 +63,32 @@ impl Device for I8042AuxPort {
     }
 
     fn bus(&self) -> Option<Weak<dyn Bus>> {
-        self.inner.lock().bus.clone()
+        self.inner().device_common.bus.clone()
     }
 
     fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
-        self.inner.lock().bus = bus;
+        self.inner().device_common.bus = bus;
     }
 
     fn set_class(&self, class: Option<Weak<dyn Class>>) {
-        self.inner.lock().class = class;
+        self.inner().device_common.class = class;
     }
 
     fn class(&self) -> Option<Arc<dyn Class>> {
-        let mut guard = self.inner.lock();
-        let r = guard.class.clone()?.upgrade();
+        let mut guard = self.inner();
+        let r = guard.device_common.class.clone()?.upgrade();
         if r.is_none() {
-            guard.class = None;
+            guard.device_common.class = None;
         }
         return r;
     }
 
     fn driver(&self) -> Option<Arc<dyn Driver>> {
-        self.inner.lock().driver.clone()?.upgrade()
+        self.inner().device_common.driver.clone()?.upgrade()
     }
 
     fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
-        self.inner.lock().driver = driver;
+        self.inner().device_common.driver = driver;
     }
 
     fn is_dead(&self) -> bool {
@@ -110,6 +104,14 @@ impl Device for I8042AuxPort {
     fn state_synced(&self) -> bool {
         true
     }
+
+    fn dev_parent(&self) -> Option<Weak<dyn Device>> {
+        self.inner().device_common.get_parent_weak_or_clear()
+    }
+
+    fn set_dev_parent(&self, parent: Option<Weak<dyn Device>>) {
+        self.inner().device_common.parent = parent;
+    }
 }
 
 impl KObject for I8042AuxPort {
@@ -118,35 +120,35 @@ impl KObject for I8042AuxPort {
     }
 
     fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
-        self.inner.lock().kern_inode = inode;
+        self.inner().kobject_common.kern_inode = inode;
     }
 
     fn inode(&self) -> Option<Arc<KernFSInode>> {
-        self.inner.lock().kern_inode.clone()
+        self.inner().kobject_common.kern_inode.clone()
     }
 
     fn parent(&self) -> Option<Weak<dyn KObject>> {
-        self.inner.lock().parent.clone()
+        self.inner().kobject_common.parent.clone()
     }
 
     fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
-        self.inner.lock().parent = parent;
+        self.inner().kobject_common.parent = parent;
     }
 
     fn kset(&self) -> Option<Arc<KSet>> {
-        self.inner.lock().kset.clone()
+        self.inner().kobject_common.kset.clone()
     }
 
     fn set_kset(&self, kset: Option<Arc<KSet>>) {
-        self.inner.lock().kset = kset;
+        self.inner().kobject_common.kset = kset;
     }
 
     fn kobj_type(&self) -> Option<&'static dyn KObjType> {
-        self.inner.lock().kobj_type
+        self.inner().kobject_common.kobj_type
     }
 
     fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
-        self.inner.lock().kobj_type = ktype;
+        self.inner().kobject_common.kobj_type = ktype;
     }
 
     fn name(&self) -> String {

+ 3 - 4
kernel/src/driver/input/serio/i8042/mod.rs

@@ -6,7 +6,6 @@ use unified_init::macros::unified_init;
 use crate::{
     driver::base::{
         device::{device_manager, Device},
-        kobject::KObject,
         platform::{
             platform_device::{platform_device_manager, PlatformDevice},
             platform_driver::{platform_driver_manager, PlatformDriver},
@@ -65,14 +64,14 @@ pub fn i8042_stop(_serio: &Arc<dyn SerioDevice>) -> Result<(), SystemError> {
 /// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/input/serio/i8042.c#i8042_setup_aux
 pub fn i8042_setup_aux() -> Result<(), SystemError> {
     let aux_port = Arc::new(I8042AuxPort::new());
-    aux_port.set_parent(Some(Arc::downgrade(
-        &(i8042_platform_device() as Arc<dyn KObject>),
+    aux_port.set_dev_parent(Some(Arc::downgrade(
+        &(i8042_platform_device() as Arc<dyn Device>),
     )));
     serio_device_manager().register_port(aux_port.clone() as Arc<dyn SerioDevice>)?;
 
     #[cfg(target_arch = "x86_64")]
     crate::driver::input::ps2_mouse::ps_mouse_device::rs_ps2_mouse_device_init(
-        aux_port.clone() as Arc<dyn KObject>
+        aux_port.clone() as Arc<dyn Device>
     )?;
     Ok(())
 }

+ 1 - 0
kernel/src/driver/mod.rs

@@ -11,6 +11,7 @@ pub mod net;
 pub mod open_firmware;
 pub mod pci;
 pub mod rtc;
+pub mod scsi;
 pub mod serial;
 pub mod timers;
 pub mod tty;

+ 0 - 10
kernel/src/driver/multiboot2/Makefile

@@ -1,10 +0,0 @@
-SRC = $(wildcard *.c)
-OBJ = $(SRC:.c=.o)
-CFLAGS += -I .
-
-.PHONY: all
-
-all: $(OBJ)
-
-%.o: %.c
-	$(CC) $(CFLAGS) -c $< -o $@

+ 0 - 165
kernel/src/driver/multiboot2/multiboot2.c

@@ -1,165 +0,0 @@
-#include "multiboot2.h"
-
-#include <common/glib.h>
-#include <common/kprint.h>
-// uintptr_t multiboot2_boot_info_addr;
-// unsigned int multiboot2_magic;
-unsigned int multiboot2_boot_info_size;
-
-#define MBI_RAW_MAX_SIZE 409600
-// 由于启动时传递的mb2 info所在的地址,在内存管理初始化之后会被覆盖,所以需要将其拷贝到一个固定的位置
-static uint8_t mbi_raw[MBI_RAW_MAX_SIZE] = {0};
-bool multiboot2_init(uint64_t mb2_info_paddr, uint32_t mb2_magic)
-{
-  uint64_t vaddr = (uint64_t)phys_2_virt(mb2_info_paddr);
-  if (mb2_magic != MULTIBOOT2_BOOTLOADER_MAGIC)
-    return false;
-  // vaddr+0 处保存了大小
-  multiboot2_boot_info_size = *(uint32_t *)vaddr;
-  if (multiboot2_boot_info_size > MBI_RAW_MAX_SIZE)
-    return false;
-
-  memcpy((void *)mbi_raw, (void *)vaddr, multiboot2_boot_info_size);
-  
-  return true;
-}
-
-void multiboot2_iter(bool (*_fun)(const struct iter_data_t *, void *, unsigned int *),
-                     void *data, unsigned int *count)
-{
-  // kdebug("multiboot2_boot_info_addr=%#018lx", multiboot2_boot_info_addr);
-
-  // uintptr_t addr = multiboot2_boot_info_addr;
-
-  // for(int i=0;i<8192;i++)
-  // {
-  //   mbi_raw[i] = ((uint8_t *)multiboot2_boot_info_addr)[i];
-  // }
-  uint8_t * addr = mbi_raw;
-  // 接下来的第8字节开始,为 tag 信息
-  struct iter_data_t *tag = (struct iter_data_t *)((void *)addr + 8);
-  for (; tag->type != MULTIBOOT_TAG_TYPE_END;
-       tag = (struct iter_data_t *)((uint8_t *)tag + ALIGN(tag->size, 8)))
-  {
-
-    if (_fun(tag, data, count) == true)
-    {
-      return;
-    }
-  }
-  return;
-}
-
-// 读取 grub2 传递的物理内存信息,保存到 e820map_t 结构体中
-// 一般而言是这样的
-// 地址(长度) 类型
-// 0x00(0x9F000) 0x1
-// 0x9F000(0x1000) 0x2
-// 0xE8000(0x18000) 0x2
-// 0x100000(0x7EF0000) 0x1
-// 0x7FF0000(0x10000) 0x3
-// 0xFFFC0000(0x40000) 0x2
-/**
- * @brief 获取multiboot2协议提供的内存区域信息
- *
- * @param _iter_data 要被迭代的信息的结构体
- * @param _data 返回信息的结构体指针
- * @param count 返回数组的长度
- * @return true
- * @return false
- */
-bool multiboot2_get_memory(const struct iter_data_t *_iter_data, void *data, unsigned int *count)
-{
-  if (_iter_data->type != MULTIBOOT_TAG_TYPE_MMAP)
-    return false;
-
-  struct multiboot_mmap_entry_t *resource = (struct multiboot_mmap_entry_t *)data;
-  struct multiboot_mmap_entry_t *mmap = ((struct multiboot_tag_mmap_t *)_iter_data)->entries;
-  *count = 0;
-  for (; (uint8_t *)mmap < (uint8_t *)_iter_data + _iter_data->size;
-       mmap = (struct multiboot_mmap_entry_t *)((uint8_t *)mmap + ((struct multiboot_tag_mmap_t *)_iter_data)->entry_size))
-  {
-    *resource = *mmap;
-    // 将指针进行增加
-    resource = (struct multiboot_mmap_entry_t *)((uint8_t *)resource + ((struct multiboot_tag_mmap_t *)_iter_data)->entry_size);
-    ++(*count);
-  }
-  return true;
-}
-
-/**
- * @brief 获取VBE信息
- *
- * @param _iter_data 要被迭代的信息的结构体
- * @param _data 返回信息的结构体指针
- */
-bool multiboot2_get_VBE_info(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved)
-{
-
-  if (_iter_data->type != MULTIBOOT_TAG_TYPE_VBE)
-    return false;
-  *(struct multiboot_tag_vbe_t *)data = *(struct multiboot_tag_vbe_t *)_iter_data;
-  return true;
-}
-
-/// @brief 获取加载基地址
-/// @param _iter_data 
-/// @param data 
-/// @param reserved 
-/// @return 
-bool multiboot2_get_load_base(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved)
-{
-
-  if (_iter_data->type != MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR)
-    return false;
-  *(struct multiboot_tag_load_base_addr_t *)data = *(struct multiboot_tag_load_base_addr_t *)_iter_data;
-  return true;
-}
-
-/**
- * @brief 获取帧缓冲区信息
- *
- * @param _iter_data 要被迭代的信息的结构体
- * @param _data 返回信息的结构体指针
- */
-bool multiboot2_get_Framebuffer_info(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved)
-{
-  if (_iter_data->type != MULTIBOOT_TAG_TYPE_FRAMEBUFFER)
-    return false;
-  *(struct multiboot_tag_framebuffer_info_t *)data = *(struct multiboot_tag_framebuffer_info_t *)_iter_data;
-  return true;
-}
-
-/**
- * @brief 获取acpi旧版RSDP
- *
- * @param _iter_data 要被迭代的信息的结构体
- * @param _data old RSDP的结构体指针
- * @param reserved
- * @return uint8_t*  struct multiboot_tag_old_acpi_t
- */
-bool multiboot2_get_acpi_old_RSDP(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved)
-{
-  if (_iter_data->type != MULTIBOOT_TAG_TYPE_ACPI_OLD)
-    return false;
-
-  *(struct multiboot_tag_old_acpi_t *)data = *(struct multiboot_tag_old_acpi_t *)_iter_data;
-
-  return true;
-}
-
-/**
- * @brief 获取acpi新版RSDP
- *
- * @param _iter_data 要被迭代的信息的结构体
- * @param _data old RSDP的结构体指针
- * @param reserved
- * @return uint8_t*  struct multiboot_tag_old_acpi_t
- */
-bool multiboot2_get_acpi_new_RSDP(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved)
-{
-  if (_iter_data->type != MULTIBOOT_TAG_TYPE_ACPI_NEW)
-    return false;
-  *(struct multiboot_tag_new_acpi_t *)data = *(struct multiboot_tag_new_acpi_t *)_iter_data;
-  return true;
-}

+ 0 - 473
kernel/src/driver/multiboot2/multiboot2.h

@@ -1,473 +0,0 @@
-/**
- * @file multiboot2.h
- * @brief multiboot2 解析
- */
-
-#pragma once
-
-#include <DragonOS/stdint.h>
-#include "stdbool.h"
-#include <common/boot_info.h>
-#include <driver/acpi/acpi.h>
-
-/// @see Multiboot2 Specification version 2.0.pdf
-// 启动后,在 32 位内核进入点,机器状态如下:
-//   1. CS 指向基地址为 0x00000000,限长为4G – 1的代码段描述符。
-//   2. DS,SS,ES,FS 和 GS 指向基地址为0x00000000,限长为4G –
-//   1的数据段描述符。
-//   3. A20 地址线已经打开。
-//   4. 页机制被禁止。
-//   5. 中断被禁止。
-//   6. EAX = 0x2BADB002
-//   7. 系统信息和启动信息块的线性地址保存在 EBX中(相当于一个指针)。
-//      以下即为这个信息块的结构
-
-/**
- * @brief MULTIBOOT2 接口抽象
- */
-
-/*  How many bytes from the start of the file we search for the header. */
-static const unsigned int MULTIBOOT_SEARCH = 32768;
-static const unsigned int MULTIBOOT_HEADER_ALIGN = 8;
-
-/*  The magic field should contain this. */
-static const unsigned int MULTIBOOT2_HEADER_MAGIC = 0xe85250d6;
-
-/*  This should be in %eax. */
-static const unsigned int MULTIBOOT2_BOOTLOADER_MAGIC = 0x36d76289;
-
-/*  Alignment of multiboot modules. */
-static const unsigned int MULTIBOOT_MOD_ALIGN = 0x00001000;
-
-/*  Alignment of the multiboot info structure. */
-static const unsigned int MULTIBOOT_INFO_ALIGN = 0x00000008;
-
-/*  Flags set in the 'flags' member of the multiboot header. */
-
-static const unsigned int MULTIBOOT_TAG_ALIGN = 8;
-static const unsigned int MULTIBOOT_TAG_TYPE_END = 0;
-static const unsigned int MULTIBOOT_TAG_TYPE_CMDLINE = 1;
-static const unsigned int MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME = 2;
-static const unsigned int MULTIBOOT_TAG_TYPE_MODULE = 3;
-static const unsigned int MULTIBOOT_TAG_TYPE_BASIC_MEMINFO = 4;
-static const unsigned int MULTIBOOT_TAG_TYPE_BOOTDEV = 5;
-static const unsigned int MULTIBOOT_TAG_TYPE_MMAP = 6;
-static const unsigned int MULTIBOOT_TAG_TYPE_VBE = 7;
-static const unsigned int MULTIBOOT_TAG_TYPE_FRAMEBUFFER = 8;
-static const unsigned int MULTIBOOT_TAG_TYPE_ELF_SECTIONS = 9;
-static const unsigned int MULTIBOOT_TAG_TYPE_APM = 10;
-static const unsigned int MULTIBOOT_TAG_TYPE_EFI32 = 11;
-static const unsigned int MULTIBOOT_TAG_TYPE_EFI64 = 12;
-static const unsigned int MULTIBOOT_TAG_TYPE_SMBIOS = 13;
-static const unsigned int MULTIBOOT_TAG_TYPE_ACPI_OLD = 14;
-static const unsigned int MULTIBOOT_TAG_TYPE_ACPI_NEW = 15;
-static const unsigned int MULTIBOOT_TAG_TYPE_NETWORK = 16;
-static const unsigned int MULTIBOOT_TAG_TYPE_EFI_MMAP = 17;
-static const unsigned int MULTIBOOT_TAG_TYPE_EFI_BS = 18;
-static const unsigned int MULTIBOOT_TAG_TYPE_EFI32_IH = 19;
-static const unsigned int MULTIBOOT_TAG_TYPE_EFI64_IH = 20;
-static const unsigned int MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR = 21;
-
-static const unsigned int MULTIBOOT_HEADER_TAG_END = 0;
-static const unsigned int MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST =
-    1;
-static const unsigned int MULTIBOOT_HEADER_TAG_ADDRESS = 2;
-static const unsigned int MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS = 3;
-static const unsigned int MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS = 4;
-static const unsigned int MULTIBOOT_HEADER_TAG_FRAMEBUFFER = 5;
-static const unsigned int MULTIBOOT_HEADER_TAG_MODULE_ALIGN = 6;
-static const unsigned int MULTIBOOT_HEADER_TAG_EFI_BS = 7;
-static const unsigned int MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI32 =
-    8;
-static const unsigned int MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 =
-    9;
-static const unsigned int MULTIBOOT_HEADER_TAG_RELOCATABLE = 10;
-
-static const unsigned int MULTIBOOT_ARCHITECTURE_I386 = 0;
-static const unsigned int MULTIBOOT_ARCHITECTURE_MIPS32 = 4;
-static const unsigned int MULTIBOOT_HEADER_TAG_OPTIONAL = 1;
-
-static const unsigned int MULTIBOOT_LOAD_PREFERENCE_NONE = 0;
-static const unsigned int MULTIBOOT_LOAD_PREFERENCE_LOW = 1;
-static const unsigned int MULTIBOOT_LOAD_PREFERENCE_HIGH = 2;
-
-static const unsigned int MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED =
-    1;
-static const unsigned int MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED =
-    2;
-
-static const unsigned int MULTIBOOT_MEMORY_AVAILABLE = 1;
-static const unsigned int MULTIBOOT_MEMORY_RESERVED = 2;
-static const unsigned int MULTIBOOT_MEMORY_ACPI_RECLAIMABLE = 3;
-static const unsigned int MULTIBOOT_MEMORY_NVS = 4;
-static const unsigned int MULTIBOOT_MEMORY_BADRAM = 5;
-
-struct multiboot_header_t
-{
-    // Must be MULTIBOOT_MAGIC - see above.
-    unsigned int magic;
-    // ISA
-    unsigned int architecture;
-    // Total header length.
-    unsigned int header_length;
-    // The above fields plus this one must equal 0 mod 2^32.
-    unsigned int checksum;
-};
-
-struct multiboot_header_tag_t
-{
-    uint16_t type;
-    uint16_t flags;
-    unsigned int size;
-};
-struct multiboot_header_tag_information_request_t
-{
-    uint16_t type;
-    uint16_t flags;
-    unsigned int size;
-
-    unsigned int requests[0];
-};
-struct multiboot_header_tag_address_t
-{
-    uint16_t type;
-    uint16_t flags;
-    unsigned int size;
-
-    unsigned int header_addr;
-    unsigned int load_addr;
-    unsigned int load_end_addr;
-    unsigned int bss_end_addr;
-};
-
-struct multiboot_header_tag_entry_address_t
-{
-    uint16_t type;
-    uint16_t flags;
-    unsigned int size;
-
-    unsigned int entry_addr;
-};
-
-struct multiboot_header_tag_console_flags_t
-{
-    uint16_t type;
-    uint16_t flags;
-    unsigned int size;
-
-    unsigned int console_flags;
-};
-
-struct multiboot_header_tag_framebuffer_t
-{
-    uint16_t type;
-    uint16_t flags;
-    unsigned int size;
-
-    unsigned int width;
-    unsigned int height;
-    unsigned int depth;
-};
-
-struct multiboot_header_tag_module_align_t
-{
-    uint16_t type;
-    uint16_t flags;
-    unsigned int size;
-};
-
-struct multiboot_header_tag_relocatable_t
-{
-    uint16_t type;
-    uint16_t flags;
-    unsigned int size;
-
-    unsigned int min_addr;
-    unsigned int max_addr;
-    unsigned int align;
-    unsigned int preference;
-};
-
-struct multiboot_color_t
-{
-    uint8_t red;
-    uint8_t green;
-    uint8_t blue;
-};
-
-// multiboot2协议的内存区域信息
-struct multiboot_mmap_entry_t
-{
-    uint64_t addr;
-    uint64_t len;
-    unsigned int type;
-    unsigned int reserved;
-};
-
-struct multiboot_tag_t
-{
-    unsigned int type;
-    unsigned int size;
-};
-
-struct multiboot_tag_string_t
-{
-    struct multiboot_tag_t tag_t;
-    char string[0];
-};
-
-struct multiboot_tag_module_t
-{
-    struct multiboot_tag_t tag_t;
-    unsigned int mod_start;
-    unsigned int mod_end;
-    char cmdline[0];
-};
-
-struct multiboot_tag_basic_meminfo_t
-{
-    struct multiboot_tag_t tag_t;
-    unsigned int mem_lower;
-    unsigned int mem_upper;
-};
-
-struct multiboot_tag_bootdev_t
-{
-    struct multiboot_tag_t tag_t;
-    unsigned int biosdev;
-    unsigned int slice;
-    unsigned int part;
-};
-
-struct multiboot_tag_mmap_t
-{
-    struct multiboot_tag_t tag_t;
-    unsigned int entry_size;
-    unsigned int entry_version;
-    struct multiboot_mmap_entry_t entries[0];
-};
-
-struct multiboot_vbe_info_block_t
-{
-    uint8_t external_specification[512];
-};
-
-struct multiboot_vbe_mode_info_block_t
-{
-    uint8_t external_specification[256];
-};
-
-// bootloader传递的VBE信息的结构体
-struct multiboot_tag_vbe_t
-{
-    struct multiboot_tag_t tag_t;
-    uint16_t vbe_mode;
-    uint16_t vbe_interface_seg;
-    uint16_t vbe_interface_off;
-    uint16_t vbe_interface_len;
-
-    // The fields ‘vbe_control_info’ and ‘vbe_mode_info’ contain VBE control information returned by the VBE Function 00h and VBE mode information
-    // returned by the VBE Function 01h, respectively.
-    struct multiboot_vbe_info_block_t vbe_control_info;
-    struct multiboot_vbe_mode_info_block_t vbe_mode_info;
-};
-
-struct multiboot_tag_framebuffer_info_t
-{
-    struct multiboot_tag_t tag_t;
-    uint64_t framebuffer_addr;
-    uint32_t framebuffer_pitch; // 帧缓存上界
-    // width and height expressed in pixels except type=2
-    // when type=2, they are expressed in characters
-    uint32_t framebuffer_width;
-    uint32_t framebuffer_height;
-    // number of bits per pixel.
-    uint8_t framebuffer_bpp;
-    // 帧缓存的类型
-    uint8_t framebuffer_type;
-    uint8_t reserved;
-};
-
-// indexed color
-struct multiboot_tag_framebuffer_info_type0_t
-{
-    struct multiboot_tag_framebuffer_info_t header;
-    uint32_t framebuffer_palette_num_colors;
-    struct multiboot_color_t color_desc;
-};
-
-// direct RGB color
-struct multiboot_tag_framebuffer_info_type1_t
-{
-    struct multiboot_tag_framebuffer_info_t header;
-
-    uint8_t framebuffer_red_field_position;
-    uint8_t framebuffer_red_mask_size;
-    uint8_t framebuffer_green_field_position;
-    uint8_t framebuffer_green_mask_size;
-    uint8_t framebuffer_blue_field_position;
-    uint8_t framebuffer_blue_mask_size;
-};
-
-struct multiboot_tag_elf_sections_t
-{
-    struct multiboot_tag_t tag_t;
-    unsigned int num;
-    unsigned int entsize;
-    // 段字符串表索引
-    unsigned int shndx;
-    char sections[0];
-};
-
-struct multiboot_tag_apm_t
-{
-    struct multiboot_tag_t tag_t;
-    uint16_t version;
-    uint16_t cseg;
-    unsigned int offset;
-    uint16_t cseg_16;
-    uint16_t dseg;
-    uint16_t flags;
-    uint16_t cseg_len;
-    uint16_t cseg_16_len;
-    uint16_t dseg_len;
-};
-
-struct multiboot_tag_efi32_t
-{
-    struct multiboot_tag_t tag_t;
-    unsigned int pointer;
-};
-
-struct multiboot_tag_efi64_t
-{
-    struct multiboot_tag_t tag_t;
-    uint64_t pointer;
-};
-
-struct multiboot_tag_smbios_t
-{
-    struct multiboot_tag_t tag_t;
-    uint8_t major;
-    uint8_t minor;
-    uint8_t reserved[6];
-    uint8_t tables[0];
-};
-
-struct multiboot_tag_old_acpi_t
-{
-    struct multiboot_tag_t tag_t;
-    //uint8_t rsdp[0];
-    struct acpi_RSDP_t rsdp;
-};
-
-struct multiboot_tag_new_acpi_t
-{
-    struct multiboot_tag_t tag_t;
-    //uint8_t rsdp[0];
-    struct acpi_RSDP_2_t rsdp;
-};
-
-struct multiboot_tag_network_t
-{
-    struct multiboot_tag_t tag_t;
-    uint8_t dhcpack[0];
-};
-
-struct multiboot_tag_efi_mmap_t
-{
-    struct multiboot_tag_t tag_t;
-    unsigned int descr_size;
-    unsigned int descr_vers;
-    uint8_t efi_mmap[0];
-};
-
-struct multiboot_tag_efi32_ih_t
-{
-    struct multiboot_tag_t tag_t;
-    unsigned int pointer;
-};
-
-struct multiboot_tag_efi64_ih_t
-{
-    struct multiboot_tag_t tag_t;
-    uint64_t pointer;
-};
-
-struct multiboot_tag_load_base_addr_t
-{
-    struct multiboot_tag_t tag_t;
-    unsigned int load_base_addr;
-};
-
-// 迭代变量
-// 与 multiboot_tag_t 相同
-struct iter_data_t
-{
-    unsigned int type;
-    unsigned int size;
-};
-
-/**
- * @brief 初始化
- * @return true            成功
- * @return false           失败
- */
-bool multiboot2_init(uint64_t mb2_info_paddr, uint32_t mb2_magic);
-
-/**
- * @brief 迭代器
- * @param  _fun            迭代操作
- * @param  _data           数据
- */
-void multiboot2_iter(bool (*_fun)(const struct iter_data_t *, void *, unsigned int *),
-                     void *_data, unsigned int *count);
-
-/**
- * @brief 获取multiboot2协议提供的内存区域信息
- *
- * @param _iter_data 要被迭代的信息的结构体
- * @param _data 返回信息的结构体指针
- * @param count 返回数组的长度
- * @return true
- * @return false
- */
-bool multiboot2_get_memory(const struct iter_data_t *_iter_data, void *_data, unsigned int *count);
-
-bool multiboot2_get_load_base(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved);
-
-/**
- * @brief 获取VBE信息
- *
- * @param _iter_data 要被迭代的信息的结构体
- * @param _data 返回信息的结构体指针
- */
-bool multiboot2_get_VBE_info(const struct iter_data_t *_iter_data, void *_data, unsigned int *reserved);
-
-/**
- * @brief 获取帧缓冲区信息
- *
- * @param _iter_data 要被迭代的信息的结构体
- * @param _data 返回信息的结构体指针
- */
-bool multiboot2_get_Framebuffer_info(const struct iter_data_t *_iter_data, void *_data, unsigned int *reserved);
-
-/**
- * @brief 获取acpi旧版RSDP
- *
- * @param _iter_data 要被迭代的信息的结构体
- * @param _data old RSDP的结构体指针
- * @param reserved
- * @return uint8_t*
- */
-bool multiboot2_get_acpi_old_RSDP(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved);
-
-/**
- * @brief 获取acpi新版RSDP
- *
- * @param _iter_data 要被迭代的信息的结构体
- * @param _data old RSDP的结构体指针
- * @param reserved
- * @return uint8_t*  struct multiboot_tag_old_acpi_t
- */
-bool multiboot2_get_acpi_new_RSDP(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved);

+ 83 - 0
kernel/src/driver/net/class.rs

@@ -0,0 +1,83 @@
+use crate::{
+    driver::base::{
+        class::{class_manager, Class},
+        device::sys_dev_char_kset,
+        kobject::KObject,
+        subsys::SubSysPrivate,
+    },
+    filesystem::sysfs::AttributeGroup,
+    init::initcall::INITCALL_SUBSYS,
+};
+use alloc::{
+    string::ToString,
+    sync::{Arc, Weak},
+};
+use system_error::SystemError;
+use unified_init::macros::unified_init;
+
+use super::sysfs::NetAttrGroup;
+
+/// `/sys/class/net` 的 class 实例
+static mut CLASS_NET_INSTANCE: Option<Arc<NetClass>> = None;
+
+/// 获取 `/sys/class/net` 的 class 实例
+#[inline(always)]
+#[allow(dead_code)]
+pub fn sys_class_net_instance() -> Option<&'static Arc<NetClass>> {
+    unsafe { CLASS_NET_INSTANCE.as_ref() }
+}
+
+/// 初始化net子系统
+#[unified_init(INITCALL_SUBSYS)]
+pub fn net_init() -> Result<(), SystemError> {
+    let net_class: Arc<NetClass> = NetClass::new();
+    class_manager().class_register(&(net_class.clone() as Arc<dyn Class>))?;
+
+    unsafe {
+        CLASS_NET_INSTANCE = Some(net_class);
+    }
+
+    return Ok(());
+}
+
+/// '/sys/class/net' 类
+#[derive(Debug)]
+pub struct NetClass {
+    subsystem: SubSysPrivate,
+}
+
+impl NetClass {
+    const NAME: &'static str = "net";
+    pub fn new() -> Arc<Self> {
+        let net_class = Arc::new(Self {
+            subsystem: SubSysPrivate::new(Self::NAME.to_string(), None, None, &[]),
+        });
+        net_class
+            .subsystem()
+            .set_class(Some(Arc::downgrade(&net_class) as Weak<dyn Class>));
+
+        return net_class;
+    }
+}
+
+impl Class for NetClass {
+    fn name(&self) -> &'static str {
+        return Self::NAME;
+    }
+
+    fn dev_kobj(&self) -> Option<Arc<dyn KObject>> {
+        Some(sys_dev_char_kset() as Arc<dyn KObject>)
+    }
+
+    fn set_dev_kobj(&self, _kobj: Arc<dyn KObject>) {
+        unimplemented!("NetClass::set_dev_kobj");
+    }
+
+    fn subsystem(&self) -> &SubSysPrivate {
+        return &self.subsystem;
+    }
+
+    fn dev_groups(&self) -> &'static [&'static dyn AttributeGroup] {
+        return &[&NetAttrGroup];
+    }
+}

+ 123 - 43
kernel/src/driver/net/e1000e/e1000e_driver.rs

@@ -5,17 +5,20 @@ use crate::{
     driver::{
         base::{
             class::Class,
-            device::{bus::Bus, driver::Driver, Device, DeviceType, IdTable},
-            kobject::{KObjType, KObject, KObjectState},
+            device::{bus::Bus, driver::Driver, Device, DeviceCommonData, DeviceType, IdTable},
+            kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
         },
-        net::NetDevice,
+        net::{register_netdevice, NetDeivceState, NetDevice, NetDeviceCommonData, Operstate},
+    },
+    libs::{
+        rwlock::{RwLockReadGuard, RwLockWriteGuard},
+        spinlock::{SpinLock, SpinLockGuard},
     },
-    libs::spinlock::SpinLock,
     net::{generate_iface_id, NET_DEVICES},
     time::Instant,
 };
 use alloc::{
-    string::String,
+    string::{String, ToString},
     sync::{Arc, Weak},
 };
 use core::{
@@ -32,6 +35,8 @@ use system_error::SystemError;
 
 use super::e1000e::{E1000EBuffer, E1000EDevice};
 
+const DEVICE_NAME: &str = "e1000e";
+
 pub struct E1000ERxToken(E1000EBuffer);
 pub struct E1000ETxToken {
     driver: E1000EDriver,
@@ -73,12 +78,24 @@ impl Debug for E1000EDriverWrapper {
     }
 }
 
+#[cast_to([sync] NetDevice)]
+#[cast_to([sync] Device)]
 pub struct E1000EInterface {
     driver: E1000EDriverWrapper,
     iface_id: usize,
     iface: SpinLock<smoltcp::iface::Interface>,
     name: String,
+    inner: SpinLock<InnerE1000EInterface>,
+    locked_kobj_state: LockedKObjectState,
 }
+
+#[derive(Debug)]
+pub struct InnerE1000EInterface {
+    netdevice_common: NetDeviceCommonData,
+    device_common: DeviceCommonData,
+    kobj_common: KObjectCommonData,
+}
+
 impl phy::RxToken for E1000ERxToken {
     fn consume<R, F>(mut self, f: F) -> R
     where
@@ -190,10 +207,20 @@ impl E1000EInterface {
             iface_id,
             iface: SpinLock::new(iface),
             name: format!("eth{}", iface_id),
+            inner: SpinLock::new(InnerE1000EInterface {
+                netdevice_common: NetDeviceCommonData::default(),
+                device_common: DeviceCommonData::default(),
+                kobj_common: KObjectCommonData::default(),
+            }),
+            locked_kobj_state: LockedKObjectState::default(),
         });
 
         return result;
     }
+
+    pub fn inner(&self) -> SpinLockGuard<InnerE1000EInterface> {
+        return self.inner.lock();
+    }
 }
 
 impl Debug for E1000EInterface {
@@ -208,43 +235,70 @@ impl Debug for E1000EInterface {
 
 impl Device for E1000EInterface {
     fn dev_type(&self) -> DeviceType {
-        todo!()
+        DeviceType::Net
     }
 
     fn id_table(&self) -> IdTable {
-        todo!()
+        IdTable::new(DEVICE_NAME.to_string(), None)
+    }
+
+    fn bus(&self) -> Option<Weak<dyn Bus>> {
+        self.inner().device_common.bus.clone()
+    }
+
+    fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
+        self.inner().device_common.bus = bus;
     }
 
-    fn set_bus(&self, _bus: Option<Weak<dyn Bus>>) {
-        todo!()
+    fn class(&self) -> Option<Arc<dyn Class>> {
+        let mut guard = self.inner();
+        let r = guard.device_common.class.clone()?.upgrade();
+        if r.is_none() {
+            guard.device_common.class = None;
+        }
+
+        return r;
     }
 
-    fn set_class(&self, _class: Option<Weak<dyn Class>>) {
-        todo!()
+    fn set_class(&self, class: Option<Weak<dyn Class>>) {
+        self.inner().device_common.class = class;
     }
 
     fn driver(&self) -> Option<Arc<dyn Driver>> {
-        todo!()
+        let r = self.inner().device_common.driver.clone()?.upgrade();
+        if r.is_none() {
+            self.inner().device_common.driver = None;
+        }
+
+        return r;
     }
 
-    fn set_driver(&self, _driver: Option<Weak<dyn Driver>>) {
-        todo!()
+    fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
+        self.inner().device_common.driver = driver;
     }
 
     fn is_dead(&self) -> bool {
-        todo!()
+        false
     }
 
     fn can_match(&self) -> bool {
-        todo!()
+        self.inner().device_common.can_match
     }
 
-    fn set_can_match(&self, _can_match: bool) {
-        todo!()
+    fn set_can_match(&self, can_match: bool) {
+        self.inner().device_common.can_match = can_match;
     }
 
     fn state_synced(&self) -> bool {
-        todo!()
+        true
+    }
+
+    fn dev_parent(&self) -> Option<Weak<dyn Device>> {
+        self.inner().device_common.get_parent_weak_or_clear()
+    }
+
+    fn set_dev_parent(&self, parent: Option<Weak<dyn Device>>) {
+        self.inner().device_common.parent = parent;
     }
 }
 
@@ -260,7 +314,7 @@ impl NetDevice for E1000EInterface {
     }
 
     #[inline]
-    fn name(&self) -> String {
+    fn iface_name(&self) -> String {
         return self.name.clone();
     }
 
@@ -295,6 +349,31 @@ impl NetDevice for E1000EInterface {
     fn inner_iface(&self) -> &SpinLock<smoltcp::iface::Interface> {
         return &self.iface;
     }
+
+    fn addr_assign_type(&self) -> u8 {
+        return self.inner().netdevice_common.addr_assign_type;
+    }
+
+    fn net_device_type(&self) -> u16 {
+        self.inner().netdevice_common.net_device_type = 1; // 以太网设备
+        return self.inner().netdevice_common.net_device_type;
+    }
+
+    fn net_state(&self) -> NetDeivceState {
+        return self.inner().netdevice_common.state;
+    }
+
+    fn set_net_state(&self, state: NetDeivceState) {
+        self.inner().netdevice_common.state |= state;
+    }
+
+    fn operstate(&self) -> Operstate {
+        return self.inner().netdevice_common.operstate;
+    }
+
+    fn set_operstate(&self, state: Operstate) {
+        self.inner().netdevice_common.operstate = state;
+    }
 }
 
 impl KObject for E1000EInterface {
@@ -302,32 +381,32 @@ impl KObject for E1000EInterface {
         self
     }
 
-    fn set_inode(&self, _inode: Option<Arc<crate::filesystem::kernfs::KernFSInode>>) {
-        todo!()
+    fn set_inode(&self, inode: Option<Arc<crate::filesystem::kernfs::KernFSInode>>) {
+        self.inner().kobj_common.kern_inode = inode;
     }
 
     fn inode(&self) -> Option<Arc<crate::filesystem::kernfs::KernFSInode>> {
-        todo!()
+        self.inner().kobj_common.kern_inode.clone()
     }
 
     fn parent(&self) -> Option<alloc::sync::Weak<dyn KObject>> {
-        todo!()
+        self.inner().kobj_common.parent.clone()
     }
 
-    fn set_parent(&self, _parent: Option<alloc::sync::Weak<dyn KObject>>) {
-        todo!()
+    fn set_parent(&self, parent: Option<alloc::sync::Weak<dyn KObject>>) {
+        self.inner().kobj_common.parent = parent;
     }
 
     fn kset(&self) -> Option<Arc<crate::driver::base::kset::KSet>> {
-        todo!()
+        self.inner().kobj_common.kset.clone()
     }
 
-    fn set_kset(&self, _kset: Option<Arc<crate::driver::base::kset::KSet>>) {
-        todo!()
+    fn set_kset(&self, kset: Option<Arc<crate::driver::base::kset::KSet>>) {
+        self.inner().kobj_common.kset = kset;
     }
 
     fn kobj_type(&self) -> Option<&'static dyn crate::driver::base::kobject::KObjType> {
-        todo!()
+        self.inner().kobj_common.kobj_type
     }
 
     fn name(&self) -> String {
@@ -335,27 +414,23 @@ impl KObject for E1000EInterface {
     }
 
     fn set_name(&self, _name: String) {
-        todo!()
+        // do nothing
     }
 
-    fn kobj_state(
-        &self,
-    ) -> crate::libs::rwlock::RwLockReadGuard<crate::driver::base::kobject::KObjectState> {
-        todo!()
+    fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
+        self.locked_kobj_state.read()
     }
 
-    fn kobj_state_mut(
-        &self,
-    ) -> crate::libs::rwlock::RwLockWriteGuard<crate::driver::base::kobject::KObjectState> {
-        todo!()
+    fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
+        self.locked_kobj_state.write()
     }
 
-    fn set_kobj_state(&self, _state: KObjectState) {
-        todo!()
+    fn set_kobj_state(&self, state: KObjectState) {
+        *self.locked_kobj_state.write() = state;
     }
 
-    fn set_kobj_type(&self, _ktype: Option<&'static dyn KObjType>) {
-        todo!()
+    fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
+        self.inner().kobj_common.kobj_type = ktype;
     }
 }
 
@@ -363,9 +438,14 @@ pub fn e1000e_driver_init(device: E1000EDevice) {
     let mac = smoltcp::wire::EthernetAddress::from_bytes(&device.mac_address());
     let driver = E1000EDriver::new(device);
     let iface = E1000EInterface::new(driver);
+    // 标识网络设备已经启动
+    iface.set_net_state(NetDeivceState::__LINK_STATE_START);
+
     // 将网卡的接口信息注册到全局的网卡接口信息表中
     NET_DEVICES
         .write_irqsave()
         .insert(iface.nic_id(), iface.clone());
     info!("e1000e driver init successfully!\tMAC: [{}]", mac);
+
+    register_netdevice(iface.clone()).expect("register lo device failed");
 }

+ 124 - 46
kernel/src/driver/net/loopback.rs

@@ -2,10 +2,15 @@ use crate::arch::rand::rand;
 use crate::driver::base::class::Class;
 use crate::driver::base::device::bus::Bus;
 use crate::driver::base::device::driver::Driver;
-use crate::driver::base::device::{Device, DeviceType, IdTable};
-use crate::driver::base::kobject::{KObjType, KObject, KObjectState};
+use crate::driver::base::device::{Device, DeviceCommonData, DeviceType, IdTable};
+use crate::driver::base::kobject::{
+    KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState,
+};
+use crate::driver::base::kset::KSet;
+use crate::filesystem::kernfs::KernFSInode;
 use crate::init::initcall::INITCALL_DEVICE;
-use crate::libs::spinlock::SpinLock;
+use crate::libs::rwlock::{RwLockReadGuard, RwLockWriteGuard};
+use crate::libs::spinlock::{SpinLock, SpinLockGuard};
 use crate::net::{generate_iface_id, NET_DEVICES};
 use crate::time::Instant;
 use alloc::collections::VecDeque;
@@ -23,7 +28,7 @@ use smoltcp::{
 use system_error::SystemError;
 use unified_init::macros::unified_init;
 
-use super::NetDevice;
+use super::{register_netdevice, NetDeivceState, NetDevice, NetDeviceCommonData, Operstate};
 
 const DEVICE_NAME: &str = "loopback";
 
@@ -235,11 +240,22 @@ impl phy::Device for LoopbackDriver {
 
 /// ## LoopbackInterface结构
 /// 封装驱动包裹器和iface,设置接口名称
+#[cast_to([sync] NetDevice)]
+#[cast_to([sync] Device)]
 pub struct LoopbackInterface {
     driver: LoopbackDriverWapper,
     iface_id: usize,
     iface: SpinLock<smoltcp::iface::Interface>,
     name: String,
+    inner: SpinLock<InnerLoopbackInterface>,
+    locked_kobj_state: LockedKObjectState,
+}
+
+#[derive(Debug)]
+pub struct InnerLoopbackInterface {
+    netdevice_common: NetDeviceCommonData,
+    device_common: DeviceCommonData,
+    kobj_common: KObjectCommonData,
 }
 
 impl LoopbackInterface {
@@ -274,8 +290,18 @@ impl LoopbackInterface {
             iface_id,
             iface: SpinLock::new(iface),
             name: "lo".to_string(),
+            inner: SpinLock::new(InnerLoopbackInterface {
+                netdevice_common: NetDeviceCommonData::default(),
+                device_common: DeviceCommonData::default(),
+                kobj_common: KObjectCommonData::default(),
+            }),
+            locked_kobj_state: LockedKObjectState::default(),
         })
     }
+
+    fn inner(&self) -> SpinLockGuard<InnerLoopbackInterface> {
+        return self.inner.lock();
+    }
 }
 
 impl Debug for LoopbackInterface {
@@ -287,38 +313,38 @@ impl Debug for LoopbackInterface {
             .finish()
     }
 }
-//TODO: 向sysfs注册lo设备
+
 impl KObject for LoopbackInterface {
     fn as_any_ref(&self) -> &dyn core::any::Any {
         self
     }
 
-    fn set_inode(&self, _inode: Option<Arc<crate::filesystem::kernfs::KernFSInode>>) {
-        todo!()
+    fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
+        self.inner().kobj_common.kern_inode = inode;
     }
 
-    fn inode(&self) -> Option<Arc<crate::filesystem::kernfs::KernFSInode>> {
-        todo!()
+    fn inode(&self) -> Option<Arc<KernFSInode>> {
+        self.inner().kobj_common.kern_inode.clone()
     }
 
-    fn parent(&self) -> Option<alloc::sync::Weak<dyn KObject>> {
-        todo!()
+    fn parent(&self) -> Option<Weak<dyn KObject>> {
+        self.inner().kobj_common.parent.clone()
     }
 
-    fn set_parent(&self, _parent: Option<alloc::sync::Weak<dyn KObject>>) {
-        todo!()
+    fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
+        self.inner().kobj_common.parent = parent;
     }
 
-    fn kset(&self) -> Option<Arc<crate::driver::base::kset::KSet>> {
-        todo!()
+    fn kset(&self) -> Option<Arc<KSet>> {
+        self.inner().kobj_common.kset.clone()
     }
 
-    fn set_kset(&self, _kset: Option<Arc<crate::driver::base::kset::KSet>>) {
-        todo!()
+    fn set_kset(&self, kset: Option<Arc<KSet>>) {
+        self.inner().kobj_common.kset = kset;
     }
 
-    fn kobj_type(&self) -> Option<&'static dyn crate::driver::base::kobject::KObjType> {
-        todo!()
+    fn kobj_type(&self) -> Option<&'static dyn KObjType> {
+        self.inner().kobj_common.kobj_type
     }
 
     fn name(&self) -> String {
@@ -326,27 +352,23 @@ impl KObject for LoopbackInterface {
     }
 
     fn set_name(&self, _name: String) {
-        todo!()
+        // do nothing
     }
 
-    fn kobj_state(
-        &self,
-    ) -> crate::libs::rwlock::RwLockReadGuard<crate::driver::base::kobject::KObjectState> {
-        todo!()
+    fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
+        self.locked_kobj_state.read()
     }
 
-    fn kobj_state_mut(
-        &self,
-    ) -> crate::libs::rwlock::RwLockWriteGuard<crate::driver::base::kobject::KObjectState> {
-        todo!()
+    fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
+        self.locked_kobj_state.write()
     }
 
-    fn set_kobj_state(&self, _state: KObjectState) {
-        todo!()
+    fn set_kobj_state(&self, state: KObjectState) {
+        *self.locked_kobj_state.write() = state;
     }
 
-    fn set_kobj_type(&self, _ktype: Option<&'static dyn KObjType>) {
-        todo!()
+    fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
+        self.inner().kobj_common.kobj_type = ktype;
     }
 }
 
@@ -359,43 +381,70 @@ impl Device for LoopbackInterface {
         IdTable::new(DEVICE_NAME.to_string(), None)
     }
 
-    fn set_bus(&self, _bus: Option<Weak<dyn Bus>>) {
-        todo!()
+    fn bus(&self) -> Option<Weak<dyn Bus>> {
+        self.inner().device_common.bus.clone()
     }
 
-    fn set_class(&self, _class: Option<Weak<dyn Class>>) {
-        todo!()
+    fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
+        self.inner().device_common.bus = bus;
+    }
+
+    fn class(&self) -> Option<Arc<dyn Class>> {
+        let mut guard = self.inner();
+        let r = guard.device_common.class.clone()?.upgrade();
+        if r.is_none() {
+            guard.device_common.class = None;
+        }
+
+        return r;
+    }
+
+    fn set_class(&self, class: Option<Weak<dyn Class>>) {
+        self.inner().device_common.class = class;
     }
 
     fn driver(&self) -> Option<Arc<dyn Driver>> {
-        todo!()
+        let r = self.inner().device_common.driver.clone()?.upgrade();
+        if r.is_none() {
+            self.inner().device_common.driver = None;
+        }
+
+        return r;
     }
 
-    fn set_driver(&self, _driver: Option<Weak<dyn Driver>>) {
-        todo!()
+    fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
+        self.inner().device_common.driver = driver;
     }
 
     fn is_dead(&self) -> bool {
-        todo!()
+        false
     }
 
     fn can_match(&self) -> bool {
-        todo!()
+        self.inner().device_common.can_match
     }
 
-    fn set_can_match(&self, _can_match: bool) {
-        todo!()
+    fn set_can_match(&self, can_match: bool) {
+        self.inner().device_common.can_match = can_match;
     }
 
     fn state_synced(&self) -> bool {
         true
     }
+
+    fn dev_parent(&self) -> Option<Weak<dyn Device>> {
+        self.inner().device_common.get_parent_weak_or_clear()
+    }
+
+    fn set_dev_parent(&self, parent: Option<Weak<dyn Device>>) {
+        self.inner().device_common.parent = parent;
+    }
 }
 
 impl NetDevice for LoopbackInterface {
-    /// 由于lo网卡设备不是实际的物理设备,其mac地址需要手动设置为一个默认值,这里默认为0200000001
+    /// 由于lo网卡设备不是实际的物理设备,其mac地址需要手动设置为一个默认值,这里默认为00:00:00:00:00
     fn mac(&self) -> smoltcp::wire::EthernetAddress {
-        let mac = [0x02, 0x00, 0x00, 0x00, 0x00, 0x01];
+        let mac = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
         smoltcp::wire::EthernetAddress(mac)
     }
 
@@ -405,7 +454,7 @@ impl NetDevice for LoopbackInterface {
     }
 
     #[inline]
-    fn name(&self) -> String {
+    fn iface_name(&self) -> String {
         self.name.clone()
     }
     /// ## `update_ip_addrs` 用于更新接口的 IP 地址。
@@ -459,6 +508,31 @@ impl NetDevice for LoopbackInterface {
     fn inner_iface(&self) -> &SpinLock<smoltcp::iface::Interface> {
         return &self.iface;
     }
+
+    fn addr_assign_type(&self) -> u8 {
+        return self.inner().netdevice_common.addr_assign_type;
+    }
+
+    fn net_device_type(&self) -> u16 {
+        self.inner().netdevice_common.net_device_type = 24; // 环回设备
+        return self.inner().netdevice_common.net_device_type;
+    }
+
+    fn net_state(&self) -> NetDeivceState {
+        return self.inner().netdevice_common.state;
+    }
+
+    fn set_net_state(&self, state: NetDeivceState) {
+        self.inner().netdevice_common.state |= state;
+    }
+
+    fn operstate(&self) -> Operstate {
+        return self.inner().netdevice_common.operstate;
+    }
+
+    fn set_operstate(&self, state: Operstate) {
+        self.inner().netdevice_common.operstate = state;
+    }
 }
 
 pub fn loopback_probe() {
@@ -469,10 +543,14 @@ pub fn loopback_probe() {
 pub fn loopback_driver_init() {
     let driver = LoopbackDriver::new();
     let iface = LoopbackInterface::new(driver);
+    // 标识网络设备已经启动
+    iface.set_net_state(NetDeivceState::__LINK_STATE_START);
 
     NET_DEVICES
         .write_irqsave()
         .insert(iface.iface_id, iface.clone());
+
+    register_netdevice(iface.clone()).expect("register lo device failed");
 }
 
 /// ## lo网卡设备的注册函数

+ 88 - 2
kernel/src/driver/net/mod.rs

@@ -1,24 +1,62 @@
-use alloc::string::String;
+use alloc::{string::String, sync::Arc};
 use smoltcp::{
     iface,
     wire::{self, EthernetAddress},
 };
+use sysfs::netdev_register_kobject;
 
 use super::base::device::Device;
 use crate::libs::spinlock::SpinLock;
 use system_error::SystemError;
 
+pub mod class;
 mod dma;
 pub mod e1000e;
 pub mod irq_handle;
 pub mod loopback;
+pub mod sysfs;
 pub mod virtio_net;
+
+bitflags! {
+    pub struct NetDeivceState: u16 {
+        /// 表示网络设备已经启动
+        const __LINK_STATE_START = 1 << 0;
+        /// 表示网络设备在系统中存在,即注册到sysfs中
+        const __LINK_STATE_PRESENT = 1 << 1;
+        /// 表示网络设备没有检测到载波信号
+        const __LINK_STATE_NOCARRIER = 1 << 2;
+        /// 表示设备的链路监视操作处于挂起状态
+        const __LINK_STATE_LINKWATCH_PENDING = 1 << 3;
+        /// 表示设备处于休眠状态
+        const __LINK_STATE_DORMANT = 1 << 4;
+    }
+}
+
+#[derive(Debug, Copy, Clone)]
+#[allow(dead_code, non_camel_case_types)]
+pub enum Operstate {
+    /// 网络接口的状态未知
+    IF_OPER_UNKNOWN = 0,
+    /// 网络接口不存在
+    IF_OPER_NOTPRESENT = 1,
+    /// 网络接口已禁用或未连接
+    IF_OPER_DOWN = 2,
+    /// 网络接口的下层接口已关闭
+    IF_OPER_LOWERLAYERDOWN = 3,
+    /// 网络接口正在测试
+    IF_OPER_TESTING = 4,
+    /// 网络接口处于休眠状态
+    IF_OPER_DORMANT = 5,
+    /// 网络接口已启用
+    IF_OPER_UP = 6,
+}
+
 #[allow(dead_code)]
 pub trait NetDevice: Device {
     /// @brief 获取网卡的MAC地址
     fn mac(&self) -> EthernetAddress;
 
-    fn name(&self) -> String;
+    fn iface_name(&self) -> String;
 
     /// @brief 获取网卡的id
     fn nic_id(&self) -> usize;
@@ -30,4 +68,52 @@ pub trait NetDevice: Device {
     /// @brief 获取smoltcp的网卡接口类型
     fn inner_iface(&self) -> &SpinLock<smoltcp::iface::Interface>;
     // fn as_any_ref(&'static self) -> &'static dyn core::any::Any;
+
+    fn addr_assign_type(&self) -> u8;
+
+    fn net_device_type(&self) -> u16;
+
+    fn net_state(&self) -> NetDeivceState;
+
+    fn set_net_state(&self, state: NetDeivceState);
+
+    fn operstate(&self) -> Operstate;
+
+    fn set_operstate(&self, state: Operstate);
+}
+
+/// 网络设备的公共数据
+#[derive(Debug)]
+pub struct NetDeviceCommonData {
+    /// 表示网络接口的地址分配类型
+    pub addr_assign_type: u8,
+    /// 表示网络接口的类型
+    pub net_device_type: u16,
+    /// 表示网络接口的状态
+    pub state: NetDeivceState,
+    /// 表示网络接口的操作状态
+    pub operstate: Operstate,
+}
+
+impl Default for NetDeviceCommonData {
+    fn default() -> Self {
+        Self {
+            addr_assign_type: 0,
+            net_device_type: 1,
+            state: NetDeivceState::empty(),
+            operstate: Operstate::IF_OPER_UNKNOWN,
+        }
+    }
+}
+
+/// 将网络设备注册到sysfs中
+/// 参考:https://code.dragonos.org.cn/xref/linux-2.6.39/net/core/dev.c?fi=register_netdev#5373
+fn register_netdevice(dev: Arc<dyn NetDevice>) -> Result<(), SystemError> {
+    // 在sysfs中注册设备
+    netdev_register_kobject(dev.clone())?;
+
+    // 标识网络设备在系统中存在
+    dev.set_net_state(NetDeivceState::__LINK_STATE_PRESENT);
+
+    return Ok(());
 }

+ 635 - 0
kernel/src/driver/net/sysfs.rs

@@ -0,0 +1,635 @@
+use crate::{
+    driver::base::{
+        class::Class,
+        device::{device_manager, Device},
+        kobject::KObject,
+    },
+    filesystem::{
+        sysfs::{
+            file::sysfs_emit_str, Attribute, AttributeGroup, SysFSOpsSupport, SYSFS_ATTR_MODE_RO,
+            SYSFS_ATTR_MODE_RW,
+        },
+        vfs::syscall::ModeType,
+    },
+};
+use alloc::sync::Arc;
+use intertrait::cast::CastArc;
+use log::error;
+use system_error::SystemError;
+
+use super::{class::sys_class_net_instance, NetDeivceState, NetDevice, Operstate};
+
+/// 将设备注册到`/sys/class/net`目录下
+/// 参考:https://code.dragonos.org.cn/xref/linux-2.6.39/net/core/net-sysfs.c?fi=netdev_register_kobject#1311
+pub fn netdev_register_kobject(dev: Arc<dyn NetDevice>) -> Result<(), SystemError> {
+    // 初始化设备
+    device_manager().device_default_initialize(&(dev.clone() as Arc<dyn Device>));
+
+    // 设置dev的class为net
+    dev.set_class(Some(Arc::downgrade(
+        &(sys_class_net_instance().cloned().unwrap() as Arc<dyn Class>),
+    )));
+
+    // 设置设备的kobject名
+    dev.set_name(dev.iface_name().clone());
+
+    device_manager().add_device(dev.clone() as Arc<dyn Device>)?;
+
+    return Ok(());
+}
+
+// 参考:https://code.dragonos.org.cn/xref/linux-6.6.21/net/core/net-sysfs.c
+#[derive(Debug)]
+pub struct NetAttrGroup;
+
+impl AttributeGroup for NetAttrGroup {
+    fn name(&self) -> Option<&str> {
+        None
+    }
+
+    fn attrs(&self) -> &[&'static dyn Attribute] {
+        &[
+            &AttrAddrAssignType,
+            &AttrAddrLen,
+            &AttrDevId,
+            &AttrIfalias,
+            &AttrIflink,
+            &AttrIfindex,
+            &AttrFeatrues,
+            &AttrType,
+            &AttrLinkMode,
+            &AttrAddress,
+            &AttrBroadcast,
+            &AttrCarrier,
+            &AttrSpeed,
+            &AttrDuplex,
+            &AttrDormant,
+            &AttrOperstate,
+            &AttrMtu,
+            &AttrFlags,
+            &AttrTxQueueLen,
+            &AttrNetdevGroup,
+        ]
+    }
+
+    fn is_visible(
+        &self,
+        _kobj: Arc<dyn KObject>,
+        attr: &'static dyn Attribute,
+    ) -> Option<ModeType> {
+        return Some(attr.mode());
+    }
+}
+
+/// # 表示网络接口的MAC地址是如何分配的
+/// - 0(NET_ADDR_PERM): 永久的MAC地址(默认值)
+/// - 1(NET_ADDR_RANDOM): 随机生成的MAC地址
+/// - 2(NET_ADDR_STOLEN): 从其他设备中获取的MAC地址
+/// - 3(NET_ADDR_SET): 由用户设置的MAC地址
+#[derive(Debug)]
+struct AttrAddrAssignType;
+
+impl Attribute for AttrAddrAssignType {
+    fn name(&self) -> &str {
+        "addr_assign_type"
+    }
+
+    fn mode(&self) -> ModeType {
+        SYSFS_ATTR_MODE_RO
+    }
+
+    fn support(&self) -> SysFSOpsSupport {
+        SysFSOpsSupport::ATTR_SHOW
+    }
+
+    fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
+        let net_device = kobj.cast::<dyn NetDevice>().map_err(|_| {
+            error!("AttrAddrAssignType::show() failed: kobj is not a NetDevice");
+            SystemError::EINVAL
+        })?;
+        let addr_assign_type = net_device.addr_assign_type();
+        sysfs_emit_str(buf, &format!("{}\n", addr_assign_type))
+    }
+}
+
+/// # 表示网络接口的MAC地址的长度,以字节为单位
+#[derive(Debug)]
+struct AttrAddrLen;
+
+impl Attribute for AttrAddrLen {
+    fn name(&self) -> &str {
+        "addr_len"
+    }
+
+    fn mode(&self) -> ModeType {
+        SYSFS_ATTR_MODE_RO
+    }
+
+    fn support(&self) -> SysFSOpsSupport {
+        SysFSOpsSupport::ATTR_SHOW
+    }
+
+    fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
+        todo!("AttrAddrLen::show")
+    }
+}
+
+/// # 表示网络接口的设备ID,是一个十六进制数
+#[derive(Debug)]
+struct AttrDevId;
+
+impl Attribute for AttrDevId {
+    fn name(&self) -> &str {
+        "dev_id"
+    }
+
+    fn mode(&self) -> ModeType {
+        SYSFS_ATTR_MODE_RO
+    }
+
+    fn support(&self) -> SysFSOpsSupport {
+        SysFSOpsSupport::ATTR_SHOW
+    }
+
+    fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
+        todo!("AttrDevId::show")
+    }
+}
+
+/// # 表示网络接口的别名,可以设置
+#[derive(Debug)]
+struct AttrIfalias;
+
+impl Attribute for AttrIfalias {
+    fn name(&self) -> &str {
+        "ifalias"
+    }
+
+    fn mode(&self) -> ModeType {
+        SYSFS_ATTR_MODE_RW
+    }
+
+    fn support(&self) -> SysFSOpsSupport {
+        SysFSOpsSupport::ATTR_SHOW | SysFSOpsSupport::ATTR_STORE
+    }
+
+    fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
+        todo!("AttrIfalias::show")
+    }
+
+    fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
+        todo!("AttrIfalias::store")
+    }
+}
+
+/// # 表示网络接口的链路索引,用于表示网络接口在系统中的位置
+#[derive(Debug)]
+struct AttrIflink;
+
+impl Attribute for AttrIflink {
+    fn name(&self) -> &str {
+        "iflink"
+    }
+
+    fn mode(&self) -> ModeType {
+        SYSFS_ATTR_MODE_RO
+    }
+
+    fn support(&self) -> SysFSOpsSupport {
+        SysFSOpsSupport::ATTR_SHOW
+    }
+
+    fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
+        todo!("AttrIflink::show")
+    }
+}
+
+/// # 标识网络接口的索引
+#[derive(Debug)]
+struct AttrIfindex;
+
+impl Attribute for AttrIfindex {
+    fn name(&self) -> &str {
+        "ifindex"
+    }
+
+    fn mode(&self) -> ModeType {
+        SYSFS_ATTR_MODE_RO
+    }
+
+    fn support(&self) -> SysFSOpsSupport {
+        SysFSOpsSupport::ATTR_SHOW
+    }
+
+    fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
+        todo!("AttrIfindex::show")
+    }
+}
+
+/// # 用于显示网络接口支持的特性,这些特性通常由网络驱动程序和硬件能力决定
+#[derive(Debug)]
+struct AttrFeatrues;
+
+impl Attribute for AttrFeatrues {
+    fn name(&self) -> &str {
+        "features"
+    }
+
+    fn mode(&self) -> ModeType {
+        SYSFS_ATTR_MODE_RO
+    }
+
+    fn support(&self) -> SysFSOpsSupport {
+        SysFSOpsSupport::ATTR_SHOW
+    }
+
+    fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
+        todo!("AttrFeatrues::show")
+    }
+}
+
+/// # 用于表示网络接口的类型
+/// - 1:ARPHRD_ETHER 以太网接口
+/// - 24:ARPHRD_LOOPBACK 回环接口
+/// - 512:ARPHRD_IEEE80211_RADIOTAP IEEE 802.11 无线接口
+/// - 768:ARPHRD_IEEE802154 IEEE 802.15.4 无线接口
+/// - 769:ARPHRD_6LOWPAN 6LoWPAN接口
+#[derive(Debug)]
+struct AttrType;
+
+impl Attribute for AttrType {
+    fn name(&self) -> &str {
+        "type"
+    }
+
+    fn mode(&self) -> ModeType {
+        SYSFS_ATTR_MODE_RO
+    }
+
+    fn support(&self) -> SysFSOpsSupport {
+        SysFSOpsSupport::ATTR_SHOW
+    }
+
+    fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
+        let net_deive = kobj.cast::<dyn NetDevice>().map_err(|_| {
+            error!("AttrType::show() failed: kobj is not a NetDevice");
+            SystemError::EINVAL
+        })?;
+        let net_type = net_deive.net_device_type();
+        sysfs_emit_str(buf, &format!("{}\n", net_type))
+    }
+}
+
+/// # 表示网络接口的链路模式,用于指示网络接口是否处于自动协商模式
+/// - 0:表示网络接口处于自动协商模式
+/// - 1:表示网络接口处于强制模式,即链路参数(如速度和双工模式)是手动配置的,而不是通过自动协商确定的
+#[derive(Debug)]
+struct AttrLinkMode;
+
+impl Attribute for AttrLinkMode {
+    fn name(&self) -> &str {
+        "link_mode"
+    }
+
+    fn mode(&self) -> ModeType {
+        SYSFS_ATTR_MODE_RO
+    }
+
+    fn support(&self) -> SysFSOpsSupport {
+        SysFSOpsSupport::ATTR_SHOW
+    }
+
+    fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
+        todo!("AttrLinkMode::show")
+    }
+}
+
+/// # 表示网络接口的MAC地址
+#[derive(Debug)]
+struct AttrAddress;
+
+impl Attribute for AttrAddress {
+    fn name(&self) -> &str {
+        "address"
+    }
+
+    fn mode(&self) -> ModeType {
+        SYSFS_ATTR_MODE_RO
+    }
+
+    fn support(&self) -> SysFSOpsSupport {
+        SysFSOpsSupport::ATTR_SHOW
+    }
+
+    fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
+        let net_device = kobj.cast::<dyn NetDevice>().map_err(|_| {
+            error!("AttrAddress::show() failed: kobj is not a NetDevice");
+            SystemError::EINVAL
+        })?;
+        let mac_addr = net_device.mac();
+        sysfs_emit_str(buf, &format!("{}\n", mac_addr))
+    }
+}
+
+/// # 表示网络接口的广播地址
+#[derive(Debug)]
+struct AttrBroadcast;
+
+impl Attribute for AttrBroadcast {
+    fn name(&self) -> &str {
+        "broadcast"
+    }
+
+    fn mode(&self) -> ModeType {
+        SYSFS_ATTR_MODE_RO
+    }
+
+    fn support(&self) -> SysFSOpsSupport {
+        SysFSOpsSupport::ATTR_SHOW
+    }
+
+    fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
+        todo!("AttrBroadcast::show")
+    }
+}
+
+/// # 表示网络接口的物理链路状态
+/// - 0:表示网络接口处于关闭状态
+/// - 1:表示网络接口处于打开状态
+#[derive(Debug)]
+struct AttrCarrier;
+
+impl Attribute for AttrCarrier {
+    fn name(&self) -> &str {
+        "carrier"
+    }
+
+    fn mode(&self) -> ModeType {
+        SYSFS_ATTR_MODE_RO
+    }
+
+    fn support(&self) -> SysFSOpsSupport {
+        SysFSOpsSupport::ATTR_SHOW
+    }
+
+    fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
+        let net_device = kobj.cast::<dyn NetDevice>().map_err(|_| {
+            error!("AttrCarrier::show() failed: kobj is not a NetDevice");
+            SystemError::EINVAL
+        })?;
+        if net_device
+            .net_state()
+            .contains(NetDeivceState::__LINK_STATE_START)
+            && !net_device
+                .net_state()
+                .contains(NetDeivceState::__LINK_STATE_NOCARRIER)
+        {
+            sysfs_emit_str(buf, "1\n")
+        } else {
+            sysfs_emit_str(buf, "0\n")
+        }
+    }
+}
+
+/// # 表示网络接口的当前连接速度,单位为Mbps
+/// - 特殊值:-1,表示无法确定,通常是因为接口不支持查询速度或接口未连接
+#[derive(Debug)]
+struct AttrSpeed;
+
+impl Attribute for AttrSpeed {
+    fn name(&self) -> &str {
+        "speed"
+    }
+
+    fn mode(&self) -> ModeType {
+        SYSFS_ATTR_MODE_RO
+    }
+
+    fn support(&self) -> SysFSOpsSupport {
+        SysFSOpsSupport::ATTR_SHOW
+    }
+
+    fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
+        todo!("AttrSpeed::show")
+    }
+}
+
+/// # 表示网络接口的双工模式
+/// - half:半双工,网络接口不能同时发送和接收数据
+/// - full:全双工,网络接口可以同时发送和接收数据
+/// - unknown:未知,通常表示接口未连接或无法确定双工模式
+#[derive(Debug)]
+struct AttrDuplex;
+
+impl Attribute for AttrDuplex {
+    fn name(&self) -> &str {
+        "duplex"
+    }
+
+    fn mode(&self) -> ModeType {
+        SYSFS_ATTR_MODE_RO
+    }
+
+    fn support(&self) -> SysFSOpsSupport {
+        SysFSOpsSupport::ATTR_SHOW
+    }
+
+    fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
+        todo!("AttrDuplex::show")
+    }
+}
+
+/// 表示网络接口是否处于休眠状态
+/// - 0:表示网络接口未处于休眠状态
+/// - 1:表示网络接口处于休眠状态
+#[derive(Debug)]
+struct AttrDormant;
+
+impl Attribute for AttrDormant {
+    fn name(&self) -> &str {
+        "dormant"
+    }
+
+    fn mode(&self) -> ModeType {
+        SYSFS_ATTR_MODE_RO
+    }
+
+    fn support(&self) -> SysFSOpsSupport {
+        SysFSOpsSupport::ATTR_SHOW
+    }
+
+    fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
+        todo!("AttrDormant::show")
+    }
+}
+
+/// # 表示网络接口的操作状态
+/// - up:网络接口已启用并且正在运行
+/// - down:网络接口已禁用或未连接
+/// - dormant:网络接口处于休眠状态,等待某些条件满足后激活
+/// - testing:网络接口正在测试中
+/// - unknown:网络接口的状态未知
+/// - notpresent:网络接口硬件不存在
+/// - lowerlayerdown:网络接口的底层设备未启用
+/// - inactive:网络接口未激活
+#[derive(Debug)]
+struct AttrOperstate;
+
+impl Attribute for AttrOperstate {
+    fn name(&self) -> &str {
+        "operstate"
+    }
+
+    fn mode(&self) -> ModeType {
+        SYSFS_ATTR_MODE_RO
+    }
+
+    fn support(&self) -> SysFSOpsSupport {
+        SysFSOpsSupport::ATTR_SHOW
+    }
+
+    fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
+        let net_device = _kobj.cast::<dyn NetDevice>().map_err(|_| {
+            error!("AttrOperstate::show() failed: kobj is not a NetDevice");
+            SystemError::EINVAL
+        })?;
+        if !net_device
+            .net_state()
+            .contains(NetDeivceState::__LINK_STATE_START)
+        {
+            net_device.set_operstate(Operstate::IF_OPER_DOWN);
+        }
+
+        let operstate_str = match net_device.operstate() {
+            Operstate::IF_OPER_UP => "up",
+            Operstate::IF_OPER_DOWN => "down",
+            Operstate::IF_OPER_DORMANT => "dormant",
+            Operstate::IF_OPER_TESTING => "testing",
+            Operstate::IF_OPER_UNKNOWN => "unknown",
+            Operstate::IF_OPER_NOTPRESENT => "notpresent",
+            Operstate::IF_OPER_LOWERLAYERDOWN => "lowerlayerdown",
+        };
+
+        sysfs_emit_str(_buf, &format!("{}\n", operstate_str))
+    }
+}
+
+/// # 表示网络接口的最大传输单元
+#[derive(Debug)]
+struct AttrMtu;
+
+impl Attribute for AttrMtu {
+    fn name(&self) -> &str {
+        "mtu"
+    }
+
+    fn mode(&self) -> ModeType {
+        SYSFS_ATTR_MODE_RO
+    }
+
+    fn support(&self) -> SysFSOpsSupport {
+        SysFSOpsSupport::ATTR_SHOW
+    }
+
+    fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
+        todo!("AttrMtu::show")
+    }
+
+    fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
+        todo!("AttrMtu::store")
+    }
+}
+
+/// # 表示网络接口的标志,这些标志提供了关于网络接口状态和配置的详细信息
+/// - IFF_UP(0x1):接口已启用
+/// - IFF_BROADCAST(0x2):支持广播
+/// - IFF_DEBUG(0x4):调试模式
+/// - IFF_LOOPBACK(0x8):环回接口
+/// - IFF_POINTOPOINT(0x10):点对点链路
+/// - IFF_NOTRAILERS(0x20):禁用拖尾
+/// - IFF_RUNNING(0x40):资源已分配
+/// - IFF_NOARP(0x80):无ARP协议
+/// - IFF_PROMISC(0x100):混杂模式
+/// - IFF_ALLMULTI(0x200):接收所有多播放数据包
+/// - IFF_ MASTER(0x400):主设备
+/// - IFF_SLAVE(0x800):从设备
+/// - IFF_MULTICAST(0x1000):支持多播
+/// - IFF_PORTSEL(0x2000):可以选择媒体类型
+/// - IFF_AUTOMEDIA(0x4000):自动选择媒体类型
+/// - IFF_DYNAMIC(0x8000):动态接口
+#[derive(Debug)]
+struct AttrFlags;
+
+impl Attribute for AttrFlags {
+    fn name(&self) -> &str {
+        "flags"
+    }
+
+    fn mode(&self) -> ModeType {
+        SYSFS_ATTR_MODE_RO
+    }
+
+    fn support(&self) -> SysFSOpsSupport {
+        SysFSOpsSupport::ATTR_SHOW
+    }
+
+    fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
+        todo!("AttrFlags::show")
+    }
+
+    fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
+        todo!("AttrFlags::store")
+    }
+}
+
+/// # 表示网络接口的传输队列长度
+#[derive(Debug)]
+struct AttrTxQueueLen;
+
+impl Attribute for AttrTxQueueLen {
+    fn name(&self) -> &str {
+        "tx_queue_len"
+    }
+
+    fn mode(&self) -> ModeType {
+        SYSFS_ATTR_MODE_RO
+    }
+
+    fn support(&self) -> SysFSOpsSupport {
+        SysFSOpsSupport::ATTR_SHOW
+    }
+
+    fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
+        todo!("AttrTxQueueLen::show")
+    }
+
+    fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
+        todo!("AttrTxQueueLen::store")
+    }
+}
+
+/// # 表示网络设备所属的设备组
+#[derive(Debug)]
+struct AttrNetdevGroup;
+
+impl Attribute for AttrNetdevGroup {
+    fn name(&self) -> &str {
+        "netdev_group"
+    }
+
+    fn mode(&self) -> ModeType {
+        SYSFS_ATTR_MODE_RO
+    }
+
+    fn support(&self) -> SysFSOpsSupport {
+        SysFSOpsSupport::ATTR_SHOW
+    }
+
+    fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
+        todo!("AttrNetdevGroup::show")
+    }
+
+    fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
+        todo!("AttrNetdevGroup::store")
+    }
+}

+ 339 - 93
kernel/src/driver/net/virtio_net.rs

@@ -6,6 +6,7 @@ use core::{
 };
 
 use alloc::{
+    collections::LinkedList,
     string::{String, ToString},
     sync::{Arc, Weak},
     vec::Vec,
@@ -15,7 +16,7 @@ use smoltcp::{iface, phy, wire};
 use unified_init::macros::unified_init;
 use virtio_drivers::device::net::VirtIONet;
 
-use super::NetDevice;
+use super::{NetDeivceState, NetDevice, NetDeviceCommonData, Operstate};
 use crate::{
     arch::rand::rand,
     driver::{
@@ -29,12 +30,14 @@ use crate::{
             kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
             kset::KSet,
         },
+        net::register_netdevice,
         virtio::{
             irq::virtio_irq_manager,
             sysfs::{virtio_bus, virtio_device_manager, virtio_driver_manager},
             transport::VirtIOTransport,
             virtio_impl::HalImpl,
-            VirtIODevice, VirtIODeviceIndex, VirtIODriver, VIRTIO_VENDOR_ID,
+            VirtIODevice, VirtIODeviceIndex, VirtIODriver, VirtIODriverCommonData, VirtioDeviceId,
+            VIRTIO_VENDOR_ID,
         },
     },
     exception::{irqdesc::IrqReturn, IrqNumber},
@@ -51,13 +54,245 @@ use system_error::SystemError;
 
 static mut VIRTIO_NET_DRIVER: Option<Arc<VirtIONetDriver>> = None;
 
-const DEVICE_NAME: &str = "virtio_net";
+const VIRTIO_NET_BASENAME: &str = "virtio_net";
 
 #[inline(always)]
+#[allow(dead_code)]
 fn virtio_net_driver() -> Arc<VirtIONetDriver> {
     unsafe { VIRTIO_NET_DRIVER.as_ref().unwrap().clone() }
 }
 
+/// virtio net device
+#[derive(Debug)]
+#[cast_to([sync] VirtIODevice)]
+#[cast_to([sync] Device)]
+pub struct VirtIONetDevice {
+    dev_id: Arc<DeviceId>,
+    inner: SpinLock<InnerVirtIONetDevice>,
+    locked_kobj_state: LockedKObjectState,
+}
+
+unsafe impl Send for VirtIONetDevice {}
+unsafe impl Sync for VirtIONetDevice {}
+
+struct InnerVirtIONetDevice {
+    device_inner: VirtIONicDeviceInner,
+    name: Option<String>,
+    virtio_index: Option<VirtIODeviceIndex>,
+    kobj_common: KObjectCommonData,
+    device_common: DeviceCommonData,
+}
+
+impl Debug for InnerVirtIONetDevice {
+    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+        f.debug_struct("InnerVirtIOBlkDevice").finish()
+    }
+}
+
+impl VirtIONetDevice {
+    pub fn new(transport: VirtIOTransport, dev_id: Arc<DeviceId>) -> Option<Arc<Self>> {
+        let driver_net: VirtIONet<HalImpl, VirtIOTransport, 2> =
+            match VirtIONet::<HalImpl, VirtIOTransport, 2>::new(transport, 4096) {
+                Ok(net) => net,
+                Err(_) => {
+                    error!("VirtIONet init failed");
+                    return None;
+                }
+            };
+        let mac = wire::EthernetAddress::from_bytes(&driver_net.mac_address());
+        debug!("VirtIONetDevice mac: {:?}", mac);
+        let device_inner = VirtIONicDeviceInner::new(driver_net);
+
+        let dev = Arc::new(Self {
+            dev_id,
+            inner: SpinLock::new(InnerVirtIONetDevice {
+                device_inner,
+                name: None,
+                virtio_index: None,
+                kobj_common: KObjectCommonData::default(),
+                device_common: DeviceCommonData::default(),
+            }),
+            locked_kobj_state: LockedKObjectState::default(),
+        });
+
+        // dev.set_driver(Some(Arc::downgrade(&virtio_net_driver()) as Weak<dyn Driver>));
+
+        return Some(dev);
+    }
+
+    fn inner(&self) -> SpinLockGuard<InnerVirtIONetDevice> {
+        return self.inner.lock();
+    }
+}
+
+impl KObject for VirtIONetDevice {
+    fn as_any_ref(&self) -> &dyn Any {
+        self
+    }
+
+    fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
+        self.inner().kobj_common.kern_inode = inode;
+    }
+
+    fn inode(&self) -> Option<Arc<KernFSInode>> {
+        self.inner().kobj_common.kern_inode.clone()
+    }
+
+    fn parent(&self) -> Option<Weak<dyn KObject>> {
+        self.inner().kobj_common.parent.clone()
+    }
+
+    fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
+        self.inner().kobj_common.parent = parent;
+    }
+
+    fn kset(&self) -> Option<Arc<KSet>> {
+        self.inner().kobj_common.kset.clone()
+    }
+
+    fn set_kset(&self, kset: Option<Arc<KSet>>) {
+        self.inner().kobj_common.kset = kset;
+    }
+
+    fn kobj_type(&self) -> Option<&'static dyn KObjType> {
+        self.inner().kobj_common.kobj_type
+    }
+
+    fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
+        self.inner().kobj_common.kobj_type = ktype;
+    }
+
+    fn name(&self) -> String {
+        self.device_name()
+    }
+
+    fn set_name(&self, _name: String) {
+        // do nothing
+    }
+
+    fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
+        self.locked_kobj_state.read()
+    }
+
+    fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
+        self.locked_kobj_state.write()
+    }
+
+    fn set_kobj_state(&self, state: KObjectState) {
+        *self.locked_kobj_state.write() = state;
+    }
+}
+
+impl Device for VirtIONetDevice {
+    fn dev_type(&self) -> DeviceType {
+        DeviceType::Net
+    }
+
+    fn id_table(&self) -> IdTable {
+        IdTable::new(VIRTIO_NET_BASENAME.to_string(), None)
+    }
+
+    fn bus(&self) -> Option<Weak<dyn Bus>> {
+        self.inner().device_common.bus.clone()
+    }
+
+    fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
+        self.inner().device_common.bus = bus;
+    }
+
+    fn class(&self) -> Option<Arc<dyn Class>> {
+        let mut guard = self.inner();
+        let r = guard.device_common.class.clone()?.upgrade();
+        if r.is_none() {
+            guard.device_common.class = None;
+        }
+
+        return r;
+    }
+
+    fn set_class(&self, class: Option<Weak<dyn Class>>) {
+        self.inner().device_common.class = class;
+    }
+
+    fn driver(&self) -> Option<Arc<dyn Driver>> {
+        let r = self.inner().device_common.driver.clone()?.upgrade();
+        if r.is_none() {
+            self.inner().device_common.driver = None;
+        }
+
+        return r;
+    }
+
+    fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
+        self.inner().device_common.driver = driver;
+    }
+
+    fn is_dead(&self) -> bool {
+        false
+    }
+
+    fn can_match(&self) -> bool {
+        self.inner().device_common.can_match
+    }
+
+    fn set_can_match(&self, can_match: bool) {
+        self.inner().device_common.can_match = can_match;
+    }
+    fn state_synced(&self) -> bool {
+        true
+    }
+
+    fn dev_parent(&self) -> Option<Weak<dyn Device>> {
+        self.inner().device_common.get_parent_weak_or_clear()
+    }
+
+    fn set_dev_parent(&self, parent: Option<Weak<dyn Device>>) {
+        self.inner().device_common.parent = parent;
+    }
+}
+
+impl VirtIODevice for VirtIONetDevice {
+    fn handle_irq(&self, _irq: IrqNumber) -> Result<IrqReturn, SystemError> {
+        poll_ifaces_try_lock_onetime().ok();
+        return Ok(IrqReturn::Handled);
+    }
+
+    fn dev_id(&self) -> &Arc<DeviceId> {
+        return &self.dev_id;
+    }
+
+    fn set_device_name(&self, name: String) {
+        self.inner().name = Some(name);
+    }
+
+    fn device_name(&self) -> String {
+        self.inner()
+            .name
+            .clone()
+            .unwrap_or_else(|| "virtio_net".to_string())
+    }
+
+    fn set_virtio_device_index(&self, index: VirtIODeviceIndex) {
+        self.inner().virtio_index = Some(index);
+    }
+
+    fn virtio_device_index(&self) -> Option<VirtIODeviceIndex> {
+        return self.inner().virtio_index;
+    }
+
+    fn device_type_id(&self) -> u32 {
+        virtio_drivers::transport::DeviceType::Network as u32
+    }
+
+    fn vendor(&self) -> u32 {
+        VIRTIO_VENDOR_ID.into()
+    }
+
+    fn irq(&self) -> Option<IrqNumber> {
+        None
+    }
+}
+
 pub struct VirtIoNetImpl {
     inner: VirtIONet<HalImpl, VirtIOTransport, 2>,
 }
@@ -127,13 +362,12 @@ impl Debug for VirtIONicDeviceInner {
     }
 }
 
-#[cast_to([sync] VirtIODevice)]
+#[cast_to([sync] NetDevice)]
 #[cast_to([sync] Device)]
 pub struct VirtioInterface {
     device_inner: VirtIONicDeviceInnerWrapper,
     iface_id: usize,
     iface_name: String,
-    dev_id: Arc<DeviceId>,
     iface: SpinLock<iface::Interface>,
     inner: SpinLock<InnerVirtIOInterface>,
     locked_kobj_state: LockedKObjectState,
@@ -141,10 +375,9 @@ pub struct VirtioInterface {
 
 #[derive(Debug)]
 struct InnerVirtIOInterface {
-    name: Option<String>,
-    virtio_index: Option<VirtIODeviceIndex>,
-    device_common: DeviceCommonData,
     kobj_common: KObjectCommonData,
+    device_common: DeviceCommonData,
+    netdevice_common: NetDeviceCommonData,
 }
 
 impl core::fmt::Debug for VirtioInterface {
@@ -152,7 +385,6 @@ impl core::fmt::Debug for VirtioInterface {
         f.debug_struct("VirtioInterface")
             .field("iface_id", &self.iface_id)
             .field("iface_name", &self.iface_name)
-            .field("dev_id", &self.dev_id)
             .field("inner", &self.inner)
             .field("locked_kobj_state", &self.locked_kobj_state)
             .finish()
@@ -160,7 +392,7 @@ impl core::fmt::Debug for VirtioInterface {
 }
 
 impl VirtioInterface {
-    pub fn new(mut device_inner: VirtIONicDeviceInner, dev_id: Arc<DeviceId>) -> Arc<Self> {
+    pub fn new(mut device_inner: VirtIONicDeviceInner) -> Arc<Self> {
         let iface_id = generate_iface_id();
         let mut iface_config = iface::Config::new(wire::HardwareAddress::Ethernet(
             wire::EthernetAddress(device_inner.inner.lock().mac_address()),
@@ -175,18 +407,13 @@ impl VirtioInterface {
             locked_kobj_state: LockedKObjectState::default(),
             iface: SpinLock::new(iface),
             iface_name: format!("eth{}", iface_id),
-            dev_id,
             inner: SpinLock::new(InnerVirtIOInterface {
-                name: None,
-                virtio_index: None,
-                device_common: DeviceCommonData::default(),
                 kobj_common: KObjectCommonData::default(),
+                device_common: DeviceCommonData::default(),
+                netdevice_common: NetDeviceCommonData::default(),
             }),
         });
 
-        result.inner().device_common.driver =
-            Some(Arc::downgrade(&virtio_net_driver()) as Weak<dyn Driver>);
-
         return result;
     }
 
@@ -201,47 +428,6 @@ impl VirtioInterface {
     }
 }
 
-impl VirtIODevice for VirtioInterface {
-    fn handle_irq(&self, _irq: IrqNumber) -> Result<IrqReturn, SystemError> {
-        poll_ifaces_try_lock_onetime().ok();
-        return Ok(IrqReturn::Handled);
-    }
-
-    fn irq(&self) -> Option<IrqNumber> {
-        None
-    }
-
-    fn dev_id(&self) -> &Arc<DeviceId> {
-        return &self.dev_id;
-    }
-    fn set_virtio_device_index(&self, index: VirtIODeviceIndex) {
-        self.inner().virtio_index = Some(index);
-    }
-
-    fn virtio_device_index(&self) -> Option<VirtIODeviceIndex> {
-        return self.inner().virtio_index;
-    }
-
-    fn set_device_name(&self, name: String) {
-        self.inner().name = Some(name);
-    }
-
-    fn device_name(&self) -> String {
-        self.inner()
-            .name
-            .clone()
-            .unwrap_or_else(|| "virtio_net".to_string())
-    }
-
-    fn device_type_id(&self) -> u32 {
-        virtio_drivers::transport::DeviceType::Network as u32
-    }
-
-    fn vendor(&self) -> u32 {
-        VIRTIO_VENDOR_ID.into()
-    }
-}
-
 impl Drop for VirtioInterface {
     fn drop(&mut self) {
         // 从全局的网卡接口信息表中删除这个网卡的接口信息
@@ -255,7 +441,7 @@ impl Device for VirtioInterface {
     }
 
     fn id_table(&self) -> IdTable {
-        IdTable::new(DEVICE_NAME.to_string(), None)
+        IdTable::new(VIRTIO_NET_BASENAME.to_string(), None)
     }
 
     fn bus(&self) -> Option<Weak<dyn Bus>> {
@@ -308,6 +494,14 @@ impl Device for VirtioInterface {
     fn state_synced(&self) -> bool {
         true
     }
+
+    fn dev_parent(&self) -> Option<Weak<dyn Device>> {
+        self.inner().device_common.get_parent_weak_or_clear()
+    }
+
+    fn set_dev_parent(&self, parent: Option<Weak<dyn Device>>) {
+        self.inner().device_common.parent = parent;
+    }
 }
 
 impl VirtIONicDeviceInner {
@@ -413,22 +607,21 @@ impl phy::RxToken for VirtioNetToken {
 }
 
 /// @brief virtio-net 驱动的初始化与测试
-pub fn virtio_net(transport: VirtIOTransport, dev_id: Arc<DeviceId>) {
-    let driver_net: VirtIONet<HalImpl, VirtIOTransport, 2> =
-        match VirtIONet::<HalImpl, VirtIOTransport, 2>::new(transport, 4096) {
-            Ok(net) => net,
-            Err(_) => {
-                error!("VirtIONet init failed");
-                return;
-            }
-        };
-    let mac = wire::EthernetAddress::from_bytes(&driver_net.mac_address());
-    let dev_inner = VirtIONicDeviceInner::new(driver_net);
-    let iface = VirtioInterface::new(dev_inner, dev_id);
-    debug!("To add virtio net: {}, mac: {}", iface.device_name(), mac);
-    virtio_device_manager()
-        .device_add(iface.clone() as Arc<dyn VirtIODevice>)
-        .expect("Add virtio net failed");
+pub fn virtio_net(
+    transport: VirtIOTransport,
+    dev_id: Arc<DeviceId>,
+    dev_parent: Option<Arc<dyn Device>>,
+) {
+    let virtio_net_deivce = VirtIONetDevice::new(transport, dev_id);
+    if let Some(virtio_net_deivce) = virtio_net_deivce {
+        debug!("VirtIONetDevice '{:?}' created", virtio_net_deivce.dev_id);
+        if let Some(dev_parent) = dev_parent {
+            virtio_net_deivce.set_dev_parent(Some(Arc::downgrade(&dev_parent)));
+        }
+        virtio_device_manager()
+            .device_add(virtio_net_deivce.clone() as Arc<dyn VirtIODevice>)
+            .expect("Add virtio net failed");
+    }
 }
 
 impl NetDevice for VirtioInterface {
@@ -443,7 +636,7 @@ impl NetDevice for VirtioInterface {
     }
 
     #[inline]
-    fn name(&self) -> String {
+    fn iface_name(&self) -> String {
         return self.iface_name.clone();
     }
 
@@ -485,6 +678,31 @@ impl NetDevice for VirtioInterface {
     // fn as_any_ref(&'static self) -> &'static dyn core::any::Any {
     //     return self;
     // }
+
+    fn addr_assign_type(&self) -> u8 {
+        return self.inner().netdevice_common.addr_assign_type;
+    }
+
+    fn net_device_type(&self) -> u16 {
+        self.inner().netdevice_common.net_device_type = 1; // 以太网设备
+        return self.inner().netdevice_common.net_device_type;
+    }
+
+    fn net_state(&self) -> NetDeivceState {
+        return self.inner().netdevice_common.state;
+    }
+
+    fn set_net_state(&self, state: NetDeivceState) {
+        self.inner().netdevice_common.state |= state;
+    }
+
+    fn operstate(&self) -> Operstate {
+        return self.inner().netdevice_common.operstate;
+    }
+
+    fn set_operstate(&self, state: Operstate) {
+        self.inner().netdevice_common.operstate = state;
+    }
 }
 
 impl KObject for VirtioInterface {
@@ -521,7 +739,7 @@ impl KObject for VirtioInterface {
     }
 
     fn name(&self) -> String {
-        self.device_name()
+        self.iface_name.clone()
     }
 
     fn set_name(&self, _name: String) {
@@ -569,13 +787,22 @@ struct VirtIONetDriver {
 impl VirtIONetDriver {
     pub fn new() -> Arc<Self> {
         let inner = InnerVirtIODriver {
+            virtio_driver_common: VirtIODriverCommonData::default(),
             driver_common: DriverCommonData::default(),
             kobj_common: KObjectCommonData::default(),
         };
-        Arc::new(VirtIONetDriver {
+
+        let id_table = VirtioDeviceId::new(
+            virtio_drivers::transport::DeviceType::Network as u32,
+            VIRTIO_VENDOR_ID.into(),
+        );
+        let result = VirtIONetDriver {
             inner: SpinLock::new(inner),
             kobj_state: LockedKObjectState::default(),
-        })
+        };
+        result.add_virtio_id(id_table);
+
+        return Arc::new(result);
     }
 
     fn inner(&self) -> SpinLockGuard<InnerVirtIODriver> {
@@ -585,59 +812,78 @@ impl VirtIONetDriver {
 
 #[derive(Debug)]
 struct InnerVirtIODriver {
+    virtio_driver_common: VirtIODriverCommonData,
     driver_common: DriverCommonData,
     kobj_common: KObjectCommonData,
 }
 
 impl VirtIODriver for VirtIONetDriver {
     fn probe(&self, device: &Arc<dyn VirtIODevice>) -> Result<(), SystemError> {
-        let iface = device
+        log::debug!("VirtIONetDriver::probe()");
+        let virtio_net_device = device
             .clone()
             .arc_any()
-            .downcast::<VirtioInterface>()
+            .downcast::<VirtIONetDevice>()
             .map_err(|_| {
                 error!(
-                "VirtIONetDriver::probe() failed: device is not a VirtioInterface. Device: '{:?}'",
-                device.name()
-            );
+                    "VirtIONetDriver::probe() failed: device is not a VirtIODevice. Device: '{:?}'",
+                    device.name()
+                );
                 SystemError::EINVAL
             })?;
 
+        let iface: Arc<VirtioInterface> =
+            VirtioInterface::new(virtio_net_device.inner().device_inner.clone());
+        // 标识网络设备已经启动
+        iface.set_net_state(NetDeivceState::__LINK_STATE_START);
+        // 设置iface的父设备为virtio_net_device
+        iface.set_dev_parent(Some(Arc::downgrade(&virtio_net_device) as Weak<dyn Device>));
+        // 在sysfs中注册iface
+        register_netdevice(iface.clone() as Arc<dyn NetDevice>)?;
+
         // 将网卡的接口信息注册到全局的网卡接口信息表中
         NET_DEVICES
             .write_irqsave()
             .insert(iface.nic_id(), iface.clone());
 
         virtio_irq_manager()
-            .register_device(iface.clone())
-            .expect("Register virtio net failed");
+            .register_device(device.clone())
+            .expect("Register virtio net irq failed");
 
         return Ok(());
     }
+
+    fn virtio_id_table(&self) -> LinkedList<VirtioDeviceId> {
+        self.inner().virtio_driver_common.id_table.clone()
+    }
+
+    fn add_virtio_id(&self, id: VirtioDeviceId) {
+        self.inner().virtio_driver_common.id_table.push_back(id);
+    }
 }
 
 impl Driver for VirtIONetDriver {
     fn id_table(&self) -> Option<IdTable> {
-        Some(IdTable::new(DEVICE_NAME.to_string(), None))
+        Some(IdTable::new(VIRTIO_NET_BASENAME.to_string(), None))
     }
 
     fn add_device(&self, device: Arc<dyn Device>) {
-        let iface = device
+        let virtio_net_device = device
             .arc_any()
-            .downcast::<VirtioInterface>()
+            .downcast::<VirtIONetDevice>()
             .expect("VirtIONetDriver::add_device() failed: device is not a VirtioInterface");
 
         self.inner()
             .driver_common
             .devices
-            .push(iface as Arc<dyn Device>);
+            .push(virtio_net_device as Arc<dyn Device>);
     }
 
     fn delete_device(&self, device: &Arc<dyn Device>) {
-        let _iface = device
+        let _virtio_net_device = device
             .clone()
             .arc_any()
-            .downcast::<VirtioInterface>()
+            .downcast::<VirtIONetDevice>()
             .expect("VirtIONetDriver::delete_device() failed: device is not a VirtioInterface");
 
         let mut guard = self.inner();
@@ -702,7 +948,7 @@ impl KObject for VirtIONetDriver {
     }
 
     fn name(&self) -> String {
-        DEVICE_NAME.to_string()
+        VIRTIO_NET_BASENAME.to_string()
     }
 
     fn set_name(&self, _name: String) {

+ 41 - 24
kernel/src/driver/pci/device.rs

@@ -13,7 +13,10 @@ use crate::{
         kset::KSet,
     },
     filesystem::kernfs::KernFSInode,
-    libs::{rwlock::RwLockWriteGuard, spinlock::SpinLock},
+    libs::{
+        rwlock::RwLockWriteGuard,
+        spinlock::{SpinLock, SpinLockGuard},
+    },
 };
 
 use super::{
@@ -41,10 +44,8 @@ impl PciDeviceManager {
     /// - Err(e) :失败原因
     pub fn device_add(&self, pci_dev: Arc<dyn PciDevice>) -> Result<(), SystemError> {
         // pci设备一般放置在/sys/device/pci:xxxx下
-        if pci_dev.parent().is_none() {
-            pci_dev.set_parent(Some(Arc::downgrade(
-                &(pci_bus_device() as Arc<dyn KObject>),
-            )));
+        if pci_dev.dev_parent().is_none() {
+            pci_dev.set_dev_parent(Some(Arc::downgrade(&(pci_bus_device() as Arc<dyn Device>))));
         }
         // 设置设备的总线
         pci_dev.set_bus(Some(Arc::downgrade(&(pci_bus() as Arc<dyn Bus>))));
@@ -90,26 +91,34 @@ pub trait PciDevice: Device {
 #[derive(Debug)]
 #[cast_to([sync] Device)]
 pub struct PciBusDevice {
-    // inner: SpinLock<InnerPciBusDevice>,
-    device_data: SpinLock<DeviceCommonData>,
-    kobj_data: SpinLock<KObjectCommonData>,
+    inner: SpinLock<InnerPciBusDevice>,
     kobj_state: LockedKObjectState,
     name: String,
 }
 
 impl PciBusDevice {
     pub fn new(parent: Option<Weak<dyn KObject>>) -> Arc<Self> {
-        let common_device = DeviceCommonData::default();
-        let common_kobj = KObjectCommonData::default();
         let bus_device = Self {
-            device_data: SpinLock::new(common_device),
-            kobj_data: SpinLock::new(common_kobj),
+            inner: SpinLock::new(InnerPciBusDevice {
+                kobject_common: KObjectCommonData::default(),
+                device_common: DeviceCommonData::default(),
+            }),
             kobj_state: LockedKObjectState::new(None),
             name: "pci".to_string(),
         };
         bus_device.set_parent(parent);
         return Arc::new(bus_device);
     }
+
+    fn inner(&self) -> SpinLockGuard<InnerPciBusDevice> {
+        self.inner.lock()
+    }
+}
+
+#[derive(Debug)]
+struct InnerPciBusDevice {
+    kobject_common: KObjectCommonData,
+    device_common: DeviceCommonData,
 }
 
 impl KObject for PciBusDevice {
@@ -118,27 +127,27 @@ impl KObject for PciBusDevice {
     }
 
     fn parent(&self) -> Option<alloc::sync::Weak<dyn KObject>> {
-        self.kobj_data.lock().parent.clone()
+        self.inner().kobject_common.parent.clone()
     }
 
     fn inode(&self) -> Option<Arc<KernFSInode>> {
-        self.kobj_data.lock().kern_inode.clone()
+        self.inner().kobject_common.kern_inode.clone()
     }
 
     fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
-        self.kobj_data.lock().kern_inode = inode;
+        self.inner().kobject_common.kern_inode = inode;
     }
 
     fn kobj_type(&self) -> Option<&'static dyn KObjType> {
-        self.kobj_data.lock().kobj_type
+        self.inner().kobject_common.kobj_type
     }
 
     fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
-        self.kobj_data.lock().kobj_type = ktype
+        self.inner().kobject_common.kobj_type = ktype
     }
 
     fn kset(&self) -> Option<Arc<KSet>> {
-        self.kobj_data.lock().kset.clone()
+        self.inner().kobject_common.kset.clone()
     }
 
     fn kobj_state(
@@ -164,11 +173,11 @@ impl KObject for PciBusDevice {
     }
 
     fn set_kset(&self, kset: Option<Arc<KSet>>) {
-        self.kobj_data.lock().kset = kset;
+        self.inner().kobject_common.kset = kset;
     }
 
     fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
-        self.kobj_data.lock().parent = parent;
+        self.inner().kobject_common.parent = parent;
     }
 }
 
@@ -182,15 +191,15 @@ impl Device for PciBusDevice {
     }
 
     fn bus(&self) -> Option<Weak<dyn Bus>> {
-        self.device_data.lock().bus.clone()
+        self.inner().device_common.bus.clone()
     }
 
     fn set_bus(&self, bus: Option<alloc::sync::Weak<dyn Bus>>) {
-        self.device_data.lock().bus = bus
+        self.inner().device_common.bus = bus
     }
 
     fn driver(&self) -> Option<Arc<dyn Driver>> {
-        self.device_data.lock().driver.clone()?.upgrade()
+        self.inner().device_common.driver.clone()?.upgrade()
     }
 
     fn is_dead(&self) -> bool {
@@ -198,7 +207,7 @@ impl Device for PciBusDevice {
     }
 
     fn set_driver(&self, driver: Option<alloc::sync::Weak<dyn Driver>>) {
-        self.device_data.lock().driver = driver;
+        self.inner().device_common.driver = driver;
     }
 
     fn can_match(&self) -> bool {
@@ -216,4 +225,12 @@ impl Device for PciBusDevice {
     fn state_synced(&self) -> bool {
         todo!()
     }
+
+    fn dev_parent(&self) -> Option<alloc::sync::Weak<dyn Device>> {
+        self.inner().device_common.get_parent_weak_or_clear()
+    }
+
+    fn set_dev_parent(&self, dev_parent: Option<alloc::sync::Weak<dyn Device>>) {
+        self.inner().device_common.parent = dev_parent;
+    }
 }

+ 2 - 2
kernel/src/driver/pci/pci_irq.rs

@@ -369,7 +369,7 @@ pub trait PciInterrupt: PciDeviceStructure {
                         irq_num,
                         common_msg.irq_name.clone(),
                         common_msg.irq_hander,
-                        IrqHandleFlags::empty(),
+                        IrqHandleFlags::IRQF_SHARED,
                         Some(common_msg.dev_id.clone()),
                     );
 
@@ -532,7 +532,7 @@ pub trait PciInterrupt: PciDeviceStructure {
                         irq_num,
                         common_msg.irq_name.clone(),
                         common_msg.irq_hander,
-                        IrqHandleFlags::empty(),
+                        IrqHandleFlags::IRQF_SHARED,
                         Some(common_msg.dev_id.clone()),
                     );
 

+ 39 - 26
kernel/src/driver/pci/raw_device.rs

@@ -24,31 +24,36 @@ use super::{
 #[cast_to([sync] Device)]
 #[cast_to([sync] PciDevice)]
 pub struct PciGeneralDevice {
-    device_data: RwLock<DeviceCommonData>,
-    kobj_data: RwLock<KObjectCommonData>,
-    name: RwLock<Option<String>>,
+    inner: RwLock<InnerPciGeneralDevice>,
     kobj_state: LockedKObjectState,
     dev_id: PciDeviceID,
     header: Arc<PciDeviceStructureGeneralDevice>,
 }
 
+#[derive(Debug)]
+struct InnerPciGeneralDevice {
+    name: Option<String>,
+    kobject_common: KObjectCommonData,
+    device_common: DeviceCommonData,
+}
+
 impl From<&PciDeviceStructureGeneralDevice> for PciGeneralDevice {
     fn from(value: &PciDeviceStructureGeneralDevice) -> Self {
         let value = Arc::new(value.clone());
         let name: String = value.common_header.bus_device_function.into();
         let kobj_state = LockedKObjectState::new(None);
-        let common_dev = RwLock::new(DeviceCommonData::default());
-        let common_kobj = RwLock::new(KObjectCommonData::default());
         let dev_id = PciDeviceID::dummpy();
 
         // dev_id.set_special(PciSpecifiedData::Virtio());
         let res = Self {
-            device_data: common_dev,
-            kobj_data: common_kobj,
+            inner: RwLock::new(InnerPciGeneralDevice {
+                name: None,
+                kobject_common: KObjectCommonData::default(),
+                device_common: DeviceCommonData::default(),
+            }),
             kobj_state,
             dev_id,
             header: value,
-            name: RwLock::new(None),
         };
         res.set_name(name);
         res
@@ -83,21 +88,21 @@ impl Device for PciGeneralDevice {
     }
 
     fn bus(&self) -> Option<Weak<dyn Bus>> {
-        self.device_data.read().bus.clone()
+        self.inner.read().device_common.bus.clone()
     }
 
     fn class(&self) -> Option<Arc<dyn Class>> {
-        let mut guard = self.device_data.write();
-        let r = guard.class.clone()?.upgrade();
+        let mut guard = self.inner.write();
+        let r = guard.device_common.class.clone()?.upgrade();
         if r.is_none() {
-            guard.class = None;
+            guard.device_common.class = None;
         }
 
         return r;
     }
 
     fn driver(&self) -> Option<Arc<dyn Driver>> {
-        self.device_data.read().driver.clone()?.upgrade()
+        self.inner.read().device_common.driver.clone()?.upgrade()
     }
 
     fn dev_type(&self) -> DeviceType {
@@ -117,22 +122,30 @@ impl Device for PciGeneralDevice {
     }
 
     fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
-        self.device_data.write().bus = bus;
+        self.inner.write().device_common.bus = bus;
     }
 
     fn set_can_match(&self, _can_match: bool) {}
 
     fn set_class(&self, class: Option<Weak<dyn Class>>) {
-        self.device_data.write().class = class;
+        self.inner.write().device_common.class = class;
     }
 
     fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
-        self.device_data.write().driver = driver
+        self.inner.write().device_common.driver = driver
     }
 
     fn state_synced(&self) -> bool {
         true
     }
+
+    fn dev_parent(&self) -> Option<Weak<dyn Device>> {
+        self.inner.write().device_common.parent.clone()
+    }
+
+    fn set_dev_parent(&self, dev_parent: Option<Weak<dyn Device>>) {
+        self.inner.write().device_common.parent = dev_parent;
+    }
 }
 
 impl KObject for PciGeneralDevice {
@@ -141,43 +154,43 @@ impl KObject for PciGeneralDevice {
     }
 
     fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
-        self.kobj_data.write().kern_inode = inode;
+        self.inner.write().kobject_common.kern_inode = inode;
     }
 
     fn inode(&self) -> Option<Arc<KernFSInode>> {
-        self.kobj_data.read().kern_inode.clone()
+        self.inner.read().kobject_common.kern_inode.clone()
     }
 
     fn parent(&self) -> Option<Weak<dyn KObject>> {
-        self.kobj_data.read().parent.clone()
+        self.inner.read().kobject_common.parent.clone()
     }
 
     fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
-        self.kobj_data.write().parent = parent;
+        self.inner.write().kobject_common.parent = parent;
     }
 
     fn kset(&self) -> Option<Arc<KSet>> {
-        self.kobj_data.read().kset.clone()
+        self.inner.read().kobject_common.kset.clone()
     }
 
     fn set_kset(&self, kset: Option<Arc<KSet>>) {
-        self.kobj_data.write().kset = kset;
+        self.inner.write().kobject_common.kset = kset;
     }
 
     fn kobj_type(&self) -> Option<&'static dyn KObjType> {
-        self.kobj_data.read().kobj_type
+        self.inner.read().kobject_common.kobj_type
     }
 
     fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
-        self.kobj_data.write().kobj_type = ktype;
+        self.inner.write().kobject_common.kobj_type = ktype;
     }
 
     fn name(&self) -> String {
-        self.name.read().clone().unwrap()
+        self.inner.read().name.clone().unwrap()
     }
 
     fn set_name(&self, name: String) {
-        *self.name.write() = Some(name);
+        self.inner.write().name = Some(name);
     }
 
     fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {

+ 5 - 0
kernel/src/driver/pci/subsys.rs

@@ -151,6 +151,11 @@ impl Bus for PciBus {
         };
         return Ok(pci_dev.name().eq(&pci_driver.name()));
     }
+
+    fn root_device(&self) -> Option<Weak<dyn Device>> {
+        let root_device = pci_bus_device() as Arc<dyn Device>;
+        return Some(Arc::downgrade(&root_device));
+    }
 }
 
 #[derive(Debug)]

+ 8 - 0
kernel/src/driver/pci/test/pt_device.rs

@@ -130,6 +130,14 @@ impl Device for TestDevice {
     fn state_synced(&self) -> bool {
         true
     }
+
+    fn dev_parent(&self) -> Option<Weak<dyn Device>> {
+        self.device_data.read().parent.clone()
+    }
+
+    fn set_dev_parent(&self, dev_parent: Option<Weak<dyn Device>>) {
+        self.device_data.write().parent = dev_parent
+    }
 }
 
 impl KObject for TestDevice {

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