From 15d6f4e831428dcbbe0a324c706d27d74f691c3c Mon Sep 17 00:00:00 2001 From: Mike Miller Date: Fri, 24 Nov 2023 11:44:58 -0800 Subject: [PATCH] o Some code cleanup, but mostly implementing a working /dev/rtc, for RTC_RD_TIME anyway. --- app/AppDelegate.m | 15 ++-- app/RTCDevice.h | 14 ++++ app/RTCDevice.m | 123 ++++++++++++++++++++++++++++++ fs/dev.c | 3 +- fs/dev.h | 6 -- fs/devices.h | 3 +- fs/dyndev.c | 66 ++++------------ fs/dyndev.h | 3 - fs/tty.c | 4 +- iSH-AOK.xcodeproj/project.pbxproj | 14 ++++ util/sync.c | 2 +- 11 files changed, 180 insertions(+), 73 deletions(-) create mode 100644 app/RTCDevice.h create mode 100644 app/RTCDevice.m diff --git a/app/AppDelegate.m b/app/AppDelegate.m index 82e8023880..37f432fd87 100644 --- a/app/AppDelegate.m +++ b/app/AppDelegate.m @@ -17,6 +17,7 @@ #import "SceneDelegate.h" #import "PasteboardDevice.h" #import "LocationDevice.h" +#import "RTCDevice.h" #import "NSObject+SaneKVO.h" #import "Roots.h" #import "TerminalViewController.h" @@ -57,9 +58,7 @@ static void ios_handle_exit(struct task *task, int code) { pid_t pid = task->pid; // if(pids_lock.pid == pid) // unlock(&pids_lock); -// while((critical_region_count(task)) || (locks_held_count(task))) { // Wait for now, task is in one or more critical sections, and/or has locks -// nanosleep(&lock_pause, NULL); -// } + unlock(&pids_lock); dispatch_async(dispatch_get_main_queue(), ^{ [[NSNotificationCenter defaultCenter] postNotificationName:ProcessExitedNotification @@ -103,7 +102,6 @@ @implementation AppDelegate - (intptr_t)boot { #if !ISH_LINUX - NSURL *root = [Roots.instance rootUrl:Roots.instance.defaultRoot]; intptr_t err = mount_root(&fakefs, [root URLByAppendingPathComponent:@"data"].fileSystemRepresentation); @@ -165,16 +163,19 @@ - (intptr_t)boot { // Register clipboard device driver and create device node for it err = dyn_dev_register(&clipboard_dev, DEV_CHAR, DYN_DEV_MAJOR, DEV_CLIPBOARD_MINOR); - if (err != 0) { + if (err != 0) return err; - } generic_mknodat(AT_PWD, "/dev/clipboard", S_IFCHR|0666, dev_make(DYN_DEV_MAJOR, DEV_CLIPBOARD_MINOR)); err = dyn_dev_register(&location_dev, DEV_CHAR, DYN_DEV_MAJOR, DEV_LOCATION_MINOR); if (err != 0) return err; generic_mknodat(AT_PWD, "/dev/location", S_IFCHR|0666, dev_make(DYN_DEV_MAJOR, DEV_LOCATION_MINOR)); - // The following does nothing for now. Placeholder + + // Create an emulated Real Time Clock + err = dyn_dev_register(&rtc_dev, DEV_CHAR, DEV_RTC_MAJOR, DEV_RTC_MINOR); + if (err != 0) + return err; generic_mknodat(AT_PWD, "/dev/rtc0", S_IFCHR|0666, dev_make(DEV_RTC_MAJOR, DEV_RTC_MINOR)); generic_symlinkat("/dev/rtc0", AT_PWD, "/dev/rtc"); diff --git a/app/RTCDevice.h b/app/RTCDevice.h new file mode 100644 index 0000000000..1f9a353dc0 --- /dev/null +++ b/app/RTCDevice.h @@ -0,0 +1,14 @@ +// +// RTCDevice.h +// iSH-AOK +// +// Created by Michael Miller on 11/22/23. +// +#include"fs/tty.h" + +extern struct dev_ops rtc_dev; +extern int rtc_close(struct fd *fd); +extern ssize_t rtc_read(struct fd *fd, void *buf, size_t bufsize); +extern int rtc_ioctl(struct fd *fd, int cmd, void *arg); +extern int rtc_poll(struct fd *fd); +extern int rtc_open(int major, int minor, struct fd *fd); diff --git a/app/RTCDevice.m b/app/RTCDevice.m new file mode 100644 index 0000000000..43b22cb590 --- /dev/null +++ b/app/RTCDevice.m @@ -0,0 +1,123 @@ +#include +#include "fs/poll.h" +#include "fs/dyndev.h" +#include "kernel/errno.h" +#include "debug.h" +#include "fs/devices.h" + +// Real Time Clock file descriptor structure +typedef struct fd rtc_fd; + +// Function to get the current time +typedef struct rtc_time { + int tm_sec; // seconds + int tm_min; // minutes + int tm_hour; // hours + int tm_mday; // day of the month + int tm_mon; // month + int tm_year; // year +} rtc_time; + +static rtc_time *get_current_time(rtc_fd *fd, size_t *len) { + // Obtain the current date + NSDate *currentDate = [NSDate date]; + NSCalendar *calendar = [NSCalendar currentCalendar]; + + // Define the desired date components + NSDateComponents *components = [calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond) + fromDate:currentDate]; + + // Allocate and populate the rtc_time structure + rtc_time *timeStruct = malloc(sizeof(rtc_time)); + if (!timeStruct) { + // Handle memory allocation failure + *len = 0; + return NULL; + } + + // Populate the structure + // Note: tm_mon is 0-based (0 for January) and tm_year is years since 1900 + timeStruct->tm_sec = (int)[components second]; + timeStruct->tm_min = (int)[components minute]; + timeStruct->tm_hour = (int)[components hour]; + timeStruct->tm_mday = (int)[components day]; + timeStruct->tm_mon = (int)[components month] - 1; // Adjust for tm_mon + timeStruct->tm_year = (int)[components year] - 1900; // Adjust for tm_year + + // Update the size + *len = sizeof(rtc_time); + + return timeStruct; +} + + +// Read current time into buffer +static ssize_t rtc_read(rtc_fd *fd, void *buf, size_t bufsize) { + @autoreleasepool { + size_t length = 0; + rtc_time *data = get_current_time(fd, &length); + + if (bufsize < length) { + return _EINVAL; // Buffer size is too small + } + + memcpy(buf, data, length); + return length; // Return the number of bytes copied + } +} + +// Polling is not needed for RTC, return 0 +static int rtc_poll(rtc_fd *fd) { + return 0; +} + +// Function to open the RTC device +static int rtc_open(int major, int minor, rtc_fd *fd) { + return 0; +} + +// Function to close the RTC device +static int rtc_close(rtc_fd *fd) { + return 0; +} + +#define RTC_RD_TIME 0x80247009 // Example definition, adjust as necessary + +static ssize_t rtc_ioctl_size(int cmd) { + switch (cmd) { + case RTC_RD_TIME: + return sizeof(rtc_time); + } + return -1; +} + +// Function to handle ioctl operations +static int rtc_ioctl(struct fd *fd, int cmd, void *arg) { + @autoreleasepool { + switch (cmd) { + case RTC_RD_TIME: { // On a real Linux, there are a number of other possible ioctl()'s. We don't really need them + size_t length = 0; + rtc_time *data = get_current_time(fd, &length); + + if (arg == NULL) { + return _EFAULT; // Null pointer argument + } + + *(rtc_time *) arg = *data; // This is the magic that gets the value back to the "kernel" + + return 0; // Success + } + default: + return _EFAULT; // Oops + } + } +} + +struct dev_ops rtc_dev = { + .open = rtc_open, + .fd.read = rtc_read, + .fd.poll = rtc_poll, + .fd.close = rtc_close, + .fd.ioctl = rtc_ioctl, + .fd.ioctl_size = rtc_ioctl_size, +}; diff --git a/fs/dev.c b/fs/dev.c index 9a72ddd54f..f23beba4c1 100644 --- a/fs/dev.c +++ b/fs/dev.c @@ -5,6 +5,7 @@ #include "fs/tty.h" #include "fs/dyndev.h" #include "fs/devices.h" +#include "app/RTCDevice.h" struct dev_ops *block_devs[256] = { // no block devices yet @@ -15,7 +16,7 @@ struct dev_ops *char_devs[256] = { [TTY_ALTERNATE_MAJOR] = &tty_dev, [TTY_PSEUDO_MASTER_MAJOR] = &tty_dev, [TTY_PSEUDO_SLAVE_MAJOR] = &tty_dev, - // [DEV_RTC_MAJOR] = &rtc_dev_char, + [DEV_RTC_MAJOR] = &rtc_dev, [DYN_DEV_MAJOR] = &dyn_dev_char, }; diff --git a/fs/dev.h b/fs/dev.h index 48662e67e1..79246f43ea 100644 --- a/fs/dev.h +++ b/fs/dev.h @@ -33,12 +33,6 @@ static inline dev_t_ dev_fake_from_real(dev_t dev) { #define DEV_BLOCK 0 #define DEV_CHAR 1 -struct dev_rtc { - int (*open)(int major, int minor, struct fd *fd); - int (*close)(int major, int minor, struct fd *fd); - ssize_t (*read)(void *buf, size_t count); -}; - struct dev_ops { int (*open)(int major, int minor, struct fd *fd); struct fd_ops fd; diff --git a/fs/devices.h b/fs/devices.h index a1a6e58c6d..bed22c744b 100644 --- a/fs/devices.h +++ b/fs/devices.h @@ -35,9 +35,10 @@ // --- dynamic devices --- #define DYN_DEV_MAJOR 240 + // /dev/rtc #define DEV_RTC_MAJOR 252 -#define DEV_RTC_MINOR 0 +#define DEV_RTC_MINOR 2 // /dev/clipboard diff --git a/fs/dyndev.c b/fs/dyndev.c index 76da79e2b2..16230659de 100644 --- a/fs/dyndev.c +++ b/fs/dyndev.c @@ -26,7 +26,7 @@ int dyn_dev_register(struct dev_ops *ops, int type, int major, int minor) { if (minor < 0 || minor > MAX_MINOR) { return _EINVAL; } - if (major != DYN_DEV_MAJOR) { + if ((major != DYN_DEV_MAJOR) && (major != DEV_RTC_MAJOR)) { return _EINVAL; } if (ops == NULL) { @@ -52,68 +52,30 @@ int dyn_dev_register(struct dev_ops *ops, int type, int major, int minor) { static int dyn_open(int type, int major, int minor, struct fd *fd) { assert((type == DEV_CHAR) || (type == DEV_BLOCK)); - assert(major == DYN_DEV_MAJOR || major == DEV_RTC_MAJOR); // mkemkemke + assert(major == DYN_DEV_MAJOR); // it's safe to access devs without locking (read-only) - if(major == DEV_RTC_MAJOR) { - //return rtc_dev_char(major, minor, fd); - } else { - struct dev_ops *ops = dyn_info_char.devs[minor]; - if (ops == NULL) { - return _ENXIO; - } - fd->ops = &ops->fd; - - // Succeed if there's no open provided by ops - if (!ops->open) - return 0; - return ops->open(major, minor, fd); + struct dev_ops *ops; + + ops = dyn_info_char.devs[minor]; + if (ops == NULL) { + return _ENXIO; } - return 0; + fd->ops = &ops->fd; + + // Succeed if there's no open provided by ops + if (!ops->open) + return 0; + + return ops->open(major, minor, fd); } static int dyn_open_char(int major, int minor, struct fd *fd) { return dyn_open(DEV_CHAR, major, minor, fd); } -struct rtc_time { - int tm_sec; /* seconds */ - int tm_min; /* minutes */ - int tm_hour; /* hours */ - int tm_mday; /* day of the month */ - int tm_mon; /* month */ - int tm_year; /* year */ -}; - -int rtc_dev(void *buf, size_t count) { - if (count < sizeof(struct rtc_time)) { - errno = EFAULT; - return -1; - } - - time_t now; - struct tm *tm_now; - struct rtc_time emulatedRTC; - - time(&now); - tm_now = localtime(&now); - - emulatedRTC.tm_sec = tm_now->tm_sec; - emulatedRTC.tm_min = tm_now->tm_min; - emulatedRTC.tm_hour = tm_now->tm_hour; - emulatedRTC.tm_mday = tm_now->tm_mday; - emulatedRTC.tm_mon = tm_now->tm_mon; - emulatedRTC.tm_year = tm_now->tm_year + 1900; - - memcpy(buf, &emulatedRTC, sizeof(emulatedRTC)); - return sizeof(emulatedRTC); -} struct dev_ops dyn_dev_char = { .open = dyn_open_char, }; - -struct dev_ops rtc_dev_char = { - .open = dyn_open_char, -}; diff --git a/fs/dyndev.h b/fs/dyndev.h index f2418f8037..f377144f4c 100644 --- a/fs/dyndev.h +++ b/fs/dyndev.h @@ -9,9 +9,6 @@ // dev_ops handing char device with DYN_DEV_MAJOR major number extern struct dev_ops dyn_dev_char; -// Implement fake rtc -mke -extern struct dev_ops rtc_dev_char; - // Registeres new block/character device with provided major and // minor numbers, handled by provided ops // diff --git a/fs/tty.c b/fs/tty.c index 211f759f77..8be108115a 100644 --- a/fs/tty.c +++ b/fs/tty.c @@ -161,7 +161,7 @@ int tty_open(struct tty *tty, struct fd *fd) { return 0; } -static intptr_t tty_device_open(int major, int minor, struct fd *fd) { +static int tty_device_open(int major, int minor, struct fd *fd) { struct tty *tty; if (major == TTY_ALTERNATE_MAJOR) { if (minor == DEV_TTY_MINOR) { @@ -189,7 +189,7 @@ static intptr_t tty_device_open(int major, int minor, struct fd *fd) { assert(driver != NULL); tty = tty_get(driver, major, minor); if (IS_ERR(tty)) - return PTR_ERR(tty); + return (int)PTR_ERR(tty); } if (tty->driver->ops->open) { diff --git a/iSH-AOK.xcodeproj/project.pbxproj b/iSH-AOK.xcodeproj/project.pbxproj index 87516fb821..23e4f8f06d 100644 --- a/iSH-AOK.xcodeproj/project.pbxproj +++ b/iSH-AOK.xcodeproj/project.pbxproj @@ -104,6 +104,9 @@ 497F6D3D254E5EA600C82F46 /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = BB7D93822087C2890008DA78 /* main.c */; }; 497F6D5C254E609700C82F46 /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = BB7D93822087C2890008DA78 /* main.c */; }; 497F6D87254E62E100C82F46 /* libish.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BB13F7DC200AD81D003D1C4D /* libish.a */; }; + 5D1EDCDD2B0ED04F00DE2547 /* RTCDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D1EDCDC2B0ED04F00DE2547 /* RTCDevice.m */; }; + 5D1EDCDE2B0ED04F00DE2547 /* RTCDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D1EDCDC2B0ED04F00DE2547 /* RTCDevice.m */; }; + 5D1EDCDF2B0ED04F00DE2547 /* RTCDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D1EDCDC2B0ED04F00DE2547 /* RTCDevice.m */; }; 5D8ACEFA284BF122003C50D3 /* net.c in Sources */ = {isa = PBXBuildFile; fileRef = 5D8ACEF9284BF122003C50D3 /* net.c */; }; 5D8ACEFD284CE096003C50D3 /* sys.c in Sources */ = {isa = PBXBuildFile; fileRef = 5D8ACEFC284CE096003C50D3 /* sys.c */; }; 5D8ACEFE284CE096003C50D3 /* sys.c in Sources */ = {isa = PBXBuildFile; fileRef = 5D8ACEFC284CE096003C50D3 /* sys.c */; }; @@ -583,6 +586,8 @@ 497F6CD3254E5CC800C82F46 /* bits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bits.h; sourceTree = ""; }; 497F6CE4254E5E4C00C82F46 /* MakeXcodeAutoCompleteWork */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = MakeXcodeAutoCompleteWork; sourceTree = BUILT_PRODUCTS_DIR; }; 497F6D47254E605F00C82F46 /* ish-AOK */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = "ish-AOK"; path = ish; sourceTree = BUILT_PRODUCTS_DIR; }; + 5D1EDCDA2B0E6B9700DE2547 /* RTCDevice.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RTCDevice.h; sourceTree = ""; }; + 5D1EDCDC2B0ED04F00DE2547 /* RTCDevice.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RTCDevice.m; sourceTree = ""; }; 5D272493277C20DF0005F2A8 /* iSHFileProviderRelease.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = iSHFileProviderRelease.entitlements; sourceTree = ""; }; 5D8ACEF9284BF122003C50D3 /* net.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = net.c; sourceTree = ""; }; 5D8ACEFB284CE096003C50D3 /* sys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sys.h; sourceTree = ""; }; @@ -1057,6 +1062,7 @@ isa = PBXGroup; children = ( 5D9897CE28B6B953003D3670 /* AppStore.xcconfig */, + 5D1EDCDA2B0E6B9700DE2547 /* RTCDevice.h */, 5D9897CF28B6B953003D3670 /* ViewController.h */, BB792B531F96D90D00FFB7A4 /* AppDelegate.h */, BB792B541F96D90D00FFB7A4 /* AppDelegate.m */, @@ -1090,6 +1096,7 @@ BB88F4A4215476BA00A341FD /* iSH.entitlements */, BB88F4912154760800A341FD /* FileProvider */, BB41591D255EF9E300E0950C /* UITests */, + 5D1EDCDC2B0ED04F00DE2547 /* RTCDevice.m */, ); path = app; sourceTree = ""; @@ -2122,6 +2129,7 @@ buildActionMask = 2147483647; files = ( 5DA0A8342AAE21D000397280 /* BatteryStatus.m in Sources */, + 5D1EDCDD2B0ED04F00DE2547 /* RTCDevice.m in Sources */, 5DD383EB2AAE33330013A847 /* UIDevice.m in Sources */, BB28C7BB268975AE00BDC834 /* LocationDevice.m in Sources */, 5D8ACEFD284CE096003C50D3 /* sys.c in Sources */, @@ -2147,6 +2155,7 @@ BB88F49A2154760800A341FD /* FileProviderEnumerator.m in Sources */, BBBFE94921C5CFF100509DD5 /* NSError+ISHErrno.m in Sources */, BB9C7B87240A2B1E00F5D4F0 /* AppGroup.m in Sources */, + 5D1EDCDF2B0ED04F00DE2547 /* RTCDevice.m in Sources */, BB88F4942154760800A341FD /* FileProviderExtension.m in Sources */, BB88F4972154760800A341FD /* FileProviderItem.m in Sources */, ); @@ -2172,6 +2181,7 @@ BB28C79226896B1F00BDC834 /* AboutAppearanceViewController.m in Sources */, BB28C79326896B1F00BDC834 /* AltIconViewController.m in Sources */, 491B31E62883BF22008EEFB0 /* ThemeViewController.m in Sources */, + 5D1EDCDE2B0ED04F00DE2547 /* RTCDevice.m in Sources */, BB28C7B226896C4600BDC834 /* main.m in Sources */, 496C7AB227CC697E005D7613 /* Theme.m in Sources */, BB28C79426896B1F00BDC834 /* AboutNavigationController.m in Sources */, @@ -2523,6 +2533,7 @@ CURRENT_PROJECT_VERSION = 484; DEAD_CODE_STRIPPING = YES; IPHONEOS_DEPLOYMENT_TARGET = 12.0; + "OTHER_CFLAGS[arch=*]" = "-v"; }; name = "Debug-ApplePleaseFixFB19282108"; }; @@ -2533,6 +2544,7 @@ CURRENT_PROJECT_VERSION = 484; DEAD_CODE_STRIPPING = YES; IPHONEOS_DEPLOYMENT_TARGET = 12.0; + "OTHER_CFLAGS[arch=*]" = "-v"; SWIFT_COMPILATION_MODE = wholemodule; }; name = Release; @@ -3085,6 +3097,7 @@ baseConfigurationReference = BBFB2CDA259028DC00545EAB /* StaticLib.xcconfig */; buildSettings = { DEAD_CODE_STRIPPING = YES; + "OTHER_CFLAGS[arch=*]" = "-v"; }; name = "Debug-ApplePleaseFixFB19282108"; }; @@ -3093,6 +3106,7 @@ baseConfigurationReference = BBFB2CDA259028DC00545EAB /* StaticLib.xcconfig */; buildSettings = { DEAD_CODE_STRIPPING = YES; + "OTHER_CFLAGS[arch=*]" = "-v"; }; name = Release; }; diff --git a/util/sync.c b/util/sync.c index 5180d8ea5d..83f3424788 100644 --- a/util/sync.c +++ b/util/sync.c @@ -37,7 +37,7 @@ void modify_critical_region_counter(struct task *task, int value, __attribute__( if(!doEnableExtraLocking) // If they want to fly by the seat of their pants... -mke return; - +// mkemkemke Should I lock the process table here? if(task == NULL) { if(current != NULL) { task = current;