Skip to content

feat(misc/reboot): 进一步完善reboot系统调用 #1157

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

1037827920
Copy link
Contributor

Pr修改内容

restart模式 - kernel_restart()

重启前的准备1 - kernel_restart_prepare():

  1. 调用reboot_notifier_list通知链执行回调函数,但是并没有相应的回调函数注册到这个通知链,目前是仅提供了接口调用注册

  2. 执行设备的shutdown方法 - device_shutdown(),原本对有class的设备,有bus的设备,以及有Driver的设备执行shutdown,但是我们有class的设备目前并不需要shutdown,然后我们的Driver trait也没有shutdown方法,所以就只实现了有Bus设备的shutdown,主要是如下Bus设备:

    • PlatformBus:主要是实现了PlatformBus的shutdown(),以及实现PlatformDriver trait的设备的shutdown(),有I8042Driver、CmosPlatformDriver(这两个是因为没有初始化并使用对应的资源,所以shutdown直接返回ok)、Serial8250ISADriver(这个驱动的shutdown本来就是do nothing)
    • SerioBus:主要是实现了SerioBus的shutdown(),以及实现SerioDriver trait的设备的cleanup(),有Ps2MouseDriver(没有初始化并使用对应的资源,所以do nothing)
    • PciBus:主要是实现了PciBus的shutdown(),以及实现PciDriver trait的设备的shutdown(),有TestDriver(依旧是do nothing)
    • VirtIOBus:VirtIOBus的shutdown()就是do nothing的
    • EventSourceBus:EventSourceBus的shutdown()就是do nothing的

    除此之外,此pr还对设备这块有较多修改,后面单独说明

执行核心重启操作 - machine_restart():

  • 执行系统关闭操作 - machine_shutdown()
    1. 禁用io apic
    2. 禁用本地中断
    3. 禁用local apic
    4. 禁用hpet
  • 执行紧急重启操作 - emergency_restart()
    • acpi重启方式 - acpi_reboot()
    • kdb重启方式
    • cf9重启方式
    • triple重启方式

halt模式 - kernel_halt()

停止前的准备 - kernel_shutdown_prepare():

  • 调用reboot_notifier_list通知链执行回调函数
  • 修改系统状态
  • 执行设备的shutdown方法 - device_shutdown()

执行系统停止操作 - machine_halt():

  • 执行系统关闭操作 - machine_shutdown()
  • 停止当前CPU的运行,系统进入最终的停机状态 - stop_this_cpu()

drver模块

概述: 主要是修改了两点,一个是add_kobj(),另一个是引入了CommonKobj结构体

add_kobj()

修改前的逻辑: 通过手动指定kset,然后通过join()将kobject加入到kset中,而join()会在执行核心逻辑前进行assert,只有kobj.kset()为空再执行核心逻辑。

修改前存在的问题: 这样做的话,那你在使用join()前,就不能调用set_kset()去设置一个kobj的kset。否则就不能成功设置kset,而且还要在join的时候还要去手动传kset,有点麻烦。

修改后的逻辑: 参考linux的做法,通过kob.kset(),即自身的kset,将自身加入到自身的kset中。所以在join()前都有一个set_kset()的操作

修改的主要内容: 修改了add_kobj()join()的逻辑,以及在每个设备初始化的时候都进行了kset的设置(如果有的话),而不是通过传参给add_kobj()设置

CommonKobj结构体

目的: 把一些在linux本来是kobject,但是在Dragon却是Kset的换成kobject。使用KSet.resgister()注册一个kset的时候,后面可能会引入uevent,但是作为一个普通的kobj可能是没有这个的东西的,类似于Kset和Kobject的区别可能还有很多,所以我觉得还是把他们区分出来比较好

下面说明一下我将一些sysfs节点类型从kset改成kobj的部分,并给出了对应的参考地址:

fireware: [firmware.c - drivers/base/firmware.c - Linux source code v6.6 - Bootlin Elixir Cross Referencer](https://elixir.bootlin.com/linux/v6.6/source/drivers/base/firmware.c#L17)

ToDo

restart模式

  • 重启前的准备1 - kernel_restart_prepare()

    • 主要是禁用ebpf的helper函数
  • 将当前进程迁移到所需的cpu上 - migrate_to_reboot_cpu()

  • 执行系统关闭的钩子函数 - syscore_shutdown(),这个syscore机制主要涉及到系统核心阶段的一些钩子函数的执行,通过syscore_ops结构体可以知道有系统挂起、系统恢复和系统关闭的钩子函数

  • 执行核心重启操作 - machine_restart()

    • 执行系统关闭操作 - mahine_shutdown()

      • 主要是停止所有非当前CPU的执行,这样可以确保所有CPU在关机过程中不再执行任何任务
      • iommu的关闭(这个我不太清楚,我好像没看到DragonOS相关的代码)
    • 执行紧急重启操作 - emergency_restart()

      • 如果发生了紧急重启,禁用所有vmx操作
      • 使用tboot关闭机器并重启
      • efi方式重启:由于x86架构并没有进行efi_init()的操作,没有初始化efi的runtime服务,所以没法使用efi重启
      • bios方式重启:由于x86架构并没有实现实模式跳板(即短暂将CPU模式切换回实模式)这个功能,故无法实现bios重启

halt模式

  • 停止前的准备 - kernel_shutdown_prepare()

    • 主要是禁用ebpf的helper函数
  • 将当前进程迁移到所需的cpu上 - migrate_to_reboot_cpu()

  • 执行系统关闭的钩子函数 - syscore_shutdown()

  • 执行系统停止操作 - machine_halt()

    • 使用tboot关闭机器并重启

CAD模式

  • ctrl_alt_del()

power_off模式

  • 执行通知链power_off_prep_handler_list回调函数 - do_kernel_power_off_prepare()
  • 将当前进程迁移到所需的cpu上 - migrate_to_reboot_cpu()
  • 执行系统关闭的钩子函数 - syscore_shutdown()
  • 执行核心的power_off函数 - native_machine_power_off()

software_suspend模式

todo

kexec模式

todo

@github-actions github-actions bot added the enhancement New feature or request label May 9, 2025
@fslongjin fslongjin requested review from fslongjin and sparkzky May 9, 2025 15:37
Comment on lines 590 to 593
// 这段不知道啥意思,看后面要不要保留 (这段代码不能执行,否则会报错),说明Dragon的APIC不是集成APIC
if max_lvt > 3 {
apic_write(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ESR as u32, 0);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

用x86库可以判断cpu feature.然后根据判断结果去执行。
有的硬件就是集成的apic的。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

哦哦,这里我忘记删注释了,linux通过APIC_INTEGRATED宏来判断是否是集成apic,然后如果是64位架构都是集成apic
https://elixir.bootlin.com/linux/v6.6/source/arch/x86/include/asm/apicdef.h#L33

@fslongjin fslongjin requested a review from Copilot June 11, 2025 17:45
@fslongjin
Copy link
Member

这个分支需要合并一下主线,并且把系统调用部分改为新的syscall_table的方式~

https://docs.dragonos.org.cn/kernel/syscall/syscall_table.html

@github-actions github-actions bot added the documentation Improvements or additions to documentation label Jun 11, 2025
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR extends the reboot/shutdown subsystem and refactors sysfs driver registration to use CommonKobj and the new KObjectManager::init_and_add_kobj API, with corresponding updates across ACPI, bus, class, debugfs, and arch drivers.

  • Switch many /sys/... registrations from KSet to CommonKobj with init_and_add_kobj
  • Implement and stub out platform reboot/halt paths for x86_64, RISC-V, and LoongArch
  • Refactor RTC, HPET, APIC drivers to support orderly shutdown and restart

Reviewed Changes

Copilot reviewed 54 out of 54 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
kernel/src/driver/base/device/bus.rs Updated bus driver kobject registration pattern
kernel/src/driver/base/class.rs Switched class dev kobj and registration calls
kernel/src/driver/acpi/sysfs.rs Replaced ACPI sysfs ksets with CommonKobj usage
kernel/src/driver/acpi/reboot.rs Added full ACPI reboot implementation
kernel/src/driver/acpi/mod.rs Initialized ACPI kobject instead of kset
kernel/src/debug/sysfs/mod.rs Changed debugfs registration to CommonKobj
kernel/src/debug/tracing/mod.rs Updated tracing to use debugfs_kobj
kernel/src/arch/x86_64/smp/mod.rs Adjusted set_online_cpu signature
kernel/src/arch/x86_64/reboot.rs New x86_64 reboot/halt flows
kernel/src/arch/x86_64/process/mod.rs Implemented stop_this_cpu halt helper
kernel/src/arch/x86_64/driver/rtc.rs Extracted CMOS read/write and locking
kernel/src/arch/x86_64/driver/hpet.rs Added HPET shutdown/restart and enable checks
kernel/src/arch/x86_64/driver/apic/mod.rs Introduced local APIC shutdown
kernel/src/arch/x86_64/driver/apic/ioapic.rs Made IOAPIC function public
kernel/src/arch/riscv64/reboot.rs Stubbed RISC-V reboot/halt
kernel/src/arch/loongarch64/reboot.rs Stubbed LoongArch reboot/halt
Comments suppressed due to low confidence (2)

kernel/src/driver/base/class.rs:129

  • Typo in identifier 'ClassKObjbectType'—it should be 'ClassKObjectType' for consistency.
subsys.set_kobj_type(Some(&ClassKObjbectType));

kernel/src/driver/acpi/sysfs.rs:243

  • Logic error: bit_width calculation uses register.bit_offset twice. It should use register.bit_offset + register.bit_width.
let bit_width = round_up(register.bit_offset + register.bit_offset, access_width);

use alloc::string::ToString;
use alloc::sync::Arc;
use system_error::SystemError;
use unified_init::macros::unified_init;

/// `/sys/kernel/debug`的kset
static mut SYS_KERNEL_DEBUG_KSET_INSTANCE: Option<Arc<KSet>> = None;
/// `/sys/kernel/debug`的koject
Copy link
Preview

Copilot AI Jun 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in comment: 'koject' should be 'kobject'.

Suggested change
/// `/sys/kernel/debug`的koject
/// `/sys/kernel/debug`的kobject

Copilot uses AI. Check for mistakes.

@fslongjin
Copy link
Member

修改后的逻辑: 参考linux的做法,通过kob.kset(),即自身的kset,将自身加入到自身的kset中。所以在join()前都有一个set_kset()的操作

这个地方怎么感觉可能会循环引用导致内存泄露?这个有分析过这个问题吗

@1037827920
Copy link
Contributor Author

修改后的逻辑: 参考linux的做法,通过kob.kset(),即自身的kset,将自身加入到自身的kset中。所以在join()前都有一个set_kset()的操作

这个地方怎么感觉可能会循环引用导致内存泄露?这个有分析过这个问题吗

不会的,这个kobject.kset()是Arc,但是kset包含的kobjects是Weak,这个逻辑跟修改前的代码是一样的。这个代码的修改主要是把kobject.set_kset()的逻辑从join()分离出去了,在join()之前进行set_kset()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants